Skip to content

Commit

Permalink
Support formatter in useDefaults
Browse files Browse the repository at this point in the history
Clients can pass a formatter function in the useDefaults hash which can mutate the messages Array passed to the console methods.
  • Loading branch information
jonnyreeves committed Sep 10, 2015
1 parent 7fede74 commit 85ae318
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 14 deletions.
24 changes: 18 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ js-Logger has zero dependencies and comes with AMD and CommonJS module boilerpla
<script src="https://raw.github.com/jonnyreeves/js-logger/master/src/logger.min.js"></script>

## Usage
Nothing beats the sheer ecstasy of logging! js-Logger does its best to not be awkward and get in the way. If you're the sort of person who just wants to get down and dirty then all you need is one line of code:
Nothing beats the sheer ecstasy of logging! js-Logger does its best to not be awkward and get in the way. If you're the sort of person who just wants to get down and dirty then all you need is one line of code:

// Log messages will be written to the window's console.
Logger.useDefaults();
Expand All @@ -28,7 +28,7 @@ Log messages can get a bit annoying; you don't need to tell me, it's all cool.
Logger.setLevel(Logger.WARN);
Logger.debug("Donut machine is out of pink ones"); // Not a peep.
Logger.warn("Asteroid detected!"); // Logs "Asteroid detected!", best do something about that!

// Ah, you know what, I'm sick of all these messages.
Logger.setLevel(Logger.OFF);
Logger.error("Hull breach on decks 5 through to 41!"); // ...
Expand All @@ -40,18 +40,30 @@ All log messages are routed through a handler function which redirects filtered
// Send messages to a custom logging endpoint for analysis.
// TODO: Add some security? (nah, you worry too much! :P)
jQuery.post('/logs', { message: messages[0], level: context.level });
});
});

### Default Log Handler Function
When you invoke `Logger.useDefaults()`, you can specify a default LogLevel and a custom
logFormatter function which can alter the messages printed to the console:

Logger.useDefaults({
logLevel: Logger.WARN,
formatter: function (messages, context) {
messages.unshift('[MyApp]');
if (context.name) messages.unshift('[' + context.name + ']');
}
})

## Named Loggers
Okay, let's get serious, logging is not for kids, it's for adults with serious software to write and mission critical log messages to trawl through. To help you in your goal, js-Logger provides 'named' loggers which can be configured individual with their own contexts.

// Retrieve a named logger and store it for use.
var myLogger = Logger.get('ModuleA');
myLogger.info("FizzWozz starting up");

// This logger instance can be configured independent of all others (including the global one).
myLogger.setLevel(Logger.WARN);

// As it's the same instance being returned each time, you don't have to store a reference:
Logger.get('ModuleA').warn('FizzWozz combombulated!");

Expand All @@ -76,4 +88,4 @@ Sometimes its good to know what's taking so damn long; you can use `Logger.time(
// Stop timing something.
Logger.timeEnd('self destruct sequence'); // logs: 'self destruct sequence: 1022ms'.

Note that `time` and `timeEnd` methods are also provided to named Logger instances.
Note that `time` and `timeEnd` methods are also provided to named Logger instances.
19 changes: 13 additions & 6 deletions src/logger.js
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,18 @@
(contextualLoggersByNameMap[name] = new ContextualLogger(merge({ name: name }, globalLogger.context)));
};

// Configure and example a Default implementation which writes to the `window.console` (if present).
// Configure and example a Default implementation which writes to the `window.console` (if present). The
// `options` hash can be used to configure the default logLevel and provide a custom message formatter.
Logger.useDefaults = function(options) {
options = options || {};

options.formatter = options.formatter || function defaultMessageFormatter(messages, context) {
// Prepend the logger's name to the log message for easy identification.
if (context.name) {
messages.unshift("[" + context.name + "]");
}
};

// Check for the presence of a logger.
if (typeof console === "undefined") {
return;
Expand All @@ -179,6 +187,9 @@

Logger.setLevel(options.defaultLevel || Logger.DEBUG);
Logger.setHandler(function(messages, context) {
// Convert arguments object to Array.
messages = Array.prototype.slice.call(messages);

var hdlr = console.log;
var timerLabel;

Expand Down Expand Up @@ -213,11 +224,7 @@
hdlr = console.info;
}

// Prepend the logger's name to the log message for easy identification.
if (context.name) {
Array.prototype.unshift.call(messages, "[" + context.name + "] ");
}

options.formatter(messages, context);
invokeConsoleMethod(hdlr, messages);
}
});
Expand Down
2 changes: 1 addition & 1 deletion src/logger.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 18 additions & 1 deletion test-src/loggertests.js
Original file line number Diff line number Diff line change
Expand Up @@ -198,4 +198,21 @@

sandbox.restore();
});
}());

QUnit.test('Logger.useDefaults can be supplied a custom message formatter', function (assert) {
var namedLogger = this.logger.get('Dave');
var formatterSpy = sinon.spy();

this.logger.useDefaults({
formatter: formatterSpy
});

namedLogger.warn('Hello', 'World');

assert.equal(formatterSpy.callCount, 1, 'formatter invoked once per log');
assert.deepEqual(formatterSpy.firstCall.args[0], [ 'Hello', 'World' ],
'Log messages supplied to handler');
assert.ok(formatterSpy.firstCall.args[1].name === 'Dave',
'Context passed to formatter');
});
}());

0 comments on commit 85ae318

Please sign in to comment.