Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow logging function overrides & add more loggers #4

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion addon/index.js
Original file line number Diff line number Diff line change
@@ -1 +1,17 @@
export { default } from 'ember-debug-logger/utils/debug-logger';
import {
overrideLoggers,
debugLogger,
infoLogger,
warnLogger,
errorLogger
} from 'ember-debug-logger/utils/debug-logger';

export {
overrideLoggers,
debugLogger,
infoLogger,
warnLogger,
errorLogger
};

export default debugLogger;
4 changes: 3 additions & 1 deletion addon/instance-initializers/debug-logger.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import debugLogger from 'ember-debug-logger/utils/debug-logger';
import {debugLogger, errorLogger} from 'ember-debug-logger/utils/debug-logger';

export function initialize(instance) {
// In 1.13, the app instance exposes the registry; in 2.x, it proxies it instead
let registry = instance.register ? instance : instance.registry;
let inject = registry.inject || registry.injection;

registry.register('debug-logger:main', debugLogger(), { instantiate: false });
registry.register('error-logger:main', errorLogger(), { instantiate: false });

['route', 'component', 'controller', 'service'].forEach(function(type) {
inject.call(registry, type, 'debug', 'debug-logger:main');
inject.call(registry, type, 'error', 'error-logger:main');
});
}

Expand Down
91 changes: 78 additions & 13 deletions addon/utils/debug-logger.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,90 @@
* Logging preferences are persisted in local storage, and you'll need to reload
* the page for changes to take effect.
*/
export default function debugLogger(key) {
return key ? window.debug(key) : instanceLogger;

/**
* The default logging functions
* @type {{debug: *, info: *, warn: *, error: *}}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure these type annotations are providing much use.

*/
let LOGGERS = {
'debug': console.log.bind(console),
'info' : console.info.bind(console),
'warn' : console.warn.bind(console),
'error': console.error.bind(console)
};

/**
* These functions wrap the loggers, so we can perform runtime lookups
* of the loggers, and change them on the fly.
* @type {{debug: (function(): *), info: (function(): *), warn: (function(): *), error: (function(): *)}}
*/
const WRAPPERS = {
'debug': (...args) => LOGGERS['debug'](...args),
'info' : (...args) => LOGGERS['info'](...args),
'warn' : (...args) => LOGGERS['warn'](...args),
'error': (...args) => LOGGERS['error'](...args)
};

/**
* Replaces the logging function for the various log types.
* Expects an object with keys of: debug, info, warn, or error
* The values should be a function.
*
* @function overrideLoggers
* @param {Object} loggers a hash as described above
*/
export function overrideLoggers(loggers) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I follow the logic here — it looks like you're setting the global LOGGERS to the passed hash, and then re-setting each key in that hash to the value it already had.

LOGGERS = loggers;
for (const type of Object.keys(loggers)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When Babel compiles a for/of loop, it assumes the existence of Symbol.iterator — this will cause issues for anyone supporting older browsers without an ES6 shim.

LOGGERS[type] = loggers[type];
}
}

const LOGGER = '_debugLoggerInstance';
/**
* Creates an instance logger of type, type
* @param type
* @returns {Function}
*/
function createInstanceLogger(type) {
return function () {
let logger = this && this[`${type}InstanceLogger`];

if (!logger) {
const loggerKey = this && this._debugContainerKey;
if (!loggerKey) {
throw new Error('On non-container-managed objects, debug-logger requires an explicit key.');
}

export function instanceLogger() {
let logger = this && this[LOGGER];
logger = window.debug(loggerKey);
logger.log = WRAPPERS[type];

if (!logger) {
const loggerKey = this && this._debugContainerKey;
if (!loggerKey) {
throw new Error('On non-container-managed objects, debug-logger requires an explicit key.');
Object.defineProperty(this, type, { value: logger });
}

logger = window.debug(loggerKey);
return logger.apply(this, arguments);
};
}

const instanceDebugLogger = createInstanceLogger('debug');
const instanceInfoLogger = createInstanceLogger('info');
const instanceWarnLogger = createInstanceLogger('warn');
const instanceErrorLogger = createInstanceLogger('error');

Object.defineProperty(this, LOGGER, { value: logger });
}
export function debugLogger(key) {
return key ? window.debug(key) : instanceDebugLogger;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is debug the only type that allows providing an explicit key?

}

return logger.apply(this, arguments);

export function infoLogger() {
return instanceInfoLogger;
}

export function warnLogger() {
return instanceWarnLogger;
}

export function errorLogger() {
return instanceErrorLogger;
}

export default debugLogger;
15 changes: 11 additions & 4 deletions tests/acceptance/container-keys-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,28 @@
import Ember from 'ember';
import { test } from 'qunit';
import moduleForAcceptance from 'dummy/tests/helpers/module-for-acceptance';
import {overrideLoggers} from 'ember-debug-logger';

const { Service, Route } = Ember;

let logger = null;

moduleForAcceptance('Acceptance | logging from container-managed objects', {
beforeEach: function() {
this.application.register('route:application', Route);
this.application.register('service:my/test/module', Service);
this.container = this.container || this.application.__container__;

debug.enable('route:*, service:*');
sinon.stub(console, 'log');

logger = sinon.stub();

overrideLoggers({
debug: logger
});
},

afterEach: function() {
console.log.restore();
debug.disable();
}
});
Expand All @@ -29,13 +36,13 @@ test('it automatically finds keys when attached to container-managed objects', f
const appRoute = this.container.lookup('route:application');
appRoute.debug('test message from the application route');

let [routeMessage] = console.log.lastCall.args;
let [routeMessage] = logger.lastCall.args;
assert.ok(/route:application/.test(routeMessage), 'Route message should include its container key');

const testService = this.container.lookup('service:my/test/module');
testService.debug('test message from the mysterious service');

let [serviceMessage] = console.log.lastCall.args;
let [serviceMessage] = logger.lastCall.args;
assert.ok(/service:my\/test\/module/.test(serviceMessage), 'Service message should include its container key');
});
});
2 changes: 1 addition & 1 deletion tests/unit/utils/debug-logger-test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* global sinon, debug */

import Ember from 'ember';
import debugLogger from 'ember-debug-logger';
import { debugLogger } from 'ember-debug-logger';
import { module, test } from 'qunit';

const { A } = Ember;
Expand Down