js-logger
Advanced tools
Comparing version 1.2.0 to 1.3.0
{ | ||
"name": "js-logger", | ||
"version": "1.2.0", | ||
"version": "1.3.0", | ||
"main": "src/logger.js", | ||
@@ -5,0 +5,0 @@ "ignore": [ |
@@ -0,1 +1,10 @@ | ||
## 1.3.0 (5th July, 2016) | ||
- Add `Logger.createDefaultHandler()`, fixes #26 | ||
- Correct typo in README, fixes #28 | ||
- Adds Typescript definitions (`logger.d.ts`), (#27, @pjsb) | ||
## 1.2.0 (10 September, 2015) | ||
- Support for custom message formatter in Logger.useDefaults() | ||
- Logger.useDefaults() now expects a hash instead of a logLevel. | ||
## 1.1.1 (14th July, 2015) | ||
@@ -2,0 +11,0 @@ - Fixed botched npm release of 1.1.0 :) |
{ | ||
"name": "js-logger", | ||
"version": "1.2.0", | ||
"version": "1.3.0", | ||
"description": "Lightweight, unobtrusive, configurable JavaScript logger", | ||
"author": "Jonny Reeves (http://jonnyreeves.co.uk)", | ||
"homepage": "http://github.com/jonnyreeves/js-logger", | ||
"typings": "./src/logger.d.ts", | ||
"repository": { | ||
@@ -22,3 +23,4 @@ "type": "git", | ||
"scripts": { | ||
"test": "gulp test lint" | ||
"test": "gulp test lint", | ||
"build": "gulp default" | ||
}, | ||
@@ -25,0 +27,0 @@ "devDependencies": { |
140
README.md
@@ -10,3 +10,5 @@ # js-Logger [![Build Status](https://travis-ci.org/jonnyreeves/js-logger.svg?branch=master)](https://travis-ci.org/jonnyreeves/js-logger) [![npm version](https://badge.fury.io/js/js-logger.svg)](http://badge.fury.io/js/js-logger) ![npm dependencies](https://david-dm.org/jonnyreeves/js-logger.png) | ||
<script src="https://raw.github.com/jonnyreeves/js-logger/master/src/logger.min.js"></script> | ||
```html | ||
<script src="https://raw.github.com/jonnyreeves/js-logger/master/src/logger.min.js"></script> | ||
``` | ||
@@ -16,22 +18,28 @@ ## Usage | ||
// Log messages will be written to the window's console. | ||
Logger.useDefaults(); | ||
```js | ||
// Log messages will be written to the window's console. | ||
Logger.useDefaults(); | ||
``` | ||
Now, when you want to emit a red-hot log message, just drop one of the following (the syntax is identical to the `console` object) | ||
Logger.debug("I'm a debug message!"); | ||
Logger.info("OMG! Check this window out!", window); | ||
Logger.warn("Purple Alert! Purple Alert!"); | ||
Logger.error("HOLY SHI... no carrier."); | ||
```js | ||
Logger.debug("I'm a debug message!"); | ||
Logger.info("OMG! Check this window out!", window); | ||
Logger.warn("Purple Alert! Purple Alert!"); | ||
Logger.error("HOLY SHI... no carrier."); | ||
``` | ||
Log messages can get a bit annoying; you don't need to tell me, it's all cool. If things are getting too noisy for your liking then it's time you read up on the `Logger.setLevel` method: | ||
// Only log WARN and ERROR messages. | ||
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! | ||
```js | ||
// Only log WARN and ERROR messages. | ||
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!"); // ... | ||
// 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!"); // ... | ||
``` | ||
@@ -41,42 +49,80 @@ ## Log Handler Functions | ||
Logger.setHandler(function (messages, context) { | ||
// 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 }); | ||
}); | ||
```js | ||
Logger.setHandler(function (messages, context) { | ||
// 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: | ||
js-Logger provides a default handler function which writes to your browser's `console` object using the appropriate logging functions based on the message's log level (ie: `Logger.info()` will result in a call to `console.info()`). The default handler automatically shims for sub-optiomal environments right down to IE7's complete lack of `console` object (it only appears when you open the DevTools - seriosuly, this is one of the anti-user troll things I've seen!) | ||
Logger.useDefaults({ | ||
logLevel: Logger.WARN, | ||
formatter: function (messages, context) { | ||
messages.unshift('[MyApp]'); | ||
if (context.name) messages.unshift('[' + context.name + ']'); | ||
} | ||
}) | ||
Use `Logger.createDefaultHandler()` to return a new log handler function which can then be supplied to `Logger.setHandler()`. | ||
You can customise the formatting of each log message by supplying a formatter function to `createDefaultLogHandler`: | ||
```js | ||
Logger.createDefaultHandler({ | ||
formatter: function(messages, context) { | ||
// prefix each log message with a timestamp. | ||
messages.unshift(new Date().toUTCString()) | ||
} | ||
} | ||
}) | ||
``` | ||
You can use functional composition to extend the default handler with your own custom handler logic: | ||
```js | ||
var consoleHandler = Logger.createDefaultHandler(); | ||
var myHandler = function (messages, context) { | ||
jQuery.post('/logs', { message: messages[0], level: context.level }); | ||
}; | ||
Logger.setHandler(function (messages, context) { | ||
consoleHandler(messages, context); | ||
myHandler(messages, context); | ||
}); | ||
``` | ||
### useDefaults | ||
`Logger.useDefaults()` is a convenience function which allows you to configure both the default logLevel and handler in one go: | ||
```js | ||
Logger.useDefaults({ | ||
defaultLevel: Logger.WARN, | ||
formatter: function (messages, context) { | ||
messages.unshift(new Date().toUTCString()) | ||
} | ||
}) | ||
``` | ||
## 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"); | ||
```js | ||
// 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); | ||
// 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!"); | ||
// As it's the same instance being returned each time, you don't have to store a reference: | ||
Logger.get('ModuleA').warn('FizzWozz combombulated!'); | ||
``` | ||
Note that `Logger.setLevel()` will also change the current log filter level for all named logger instances; so typically you would configure your logger levels like so: | ||
// Create a couple of named loggers (typically in their own module) | ||
var loggerA = Logger.get('LoggerA'); | ||
var loggerB = Logger.get('LoggerB'); | ||
```js | ||
// Create a couple of named loggers (typically in their own module) | ||
var loggerA = Logger.get('LoggerA'); | ||
var loggerB = Logger.get('LoggerB'); | ||
// Configure log levels. | ||
Logger.setLevel(Logger.WARN); // Global logging level. | ||
Logger.get('LoggerB').setLevel(Logger.DEBUG); // Enable debug logging for LoggerB | ||
// Configure log levels. | ||
Logger.setLevel(Logger.WARN); // Global logging level. | ||
Logger.get('LoggerB').setLevel(Logger.DEBUG); // Enable debug logging for LoggerB | ||
``` | ||
@@ -86,10 +132,12 @@ ## Profiling | ||
// Start timing something | ||
Logger.time('self destruct sequence'); | ||
```js | ||
// Start timing something | ||
Logger.time('self destruct sequence'); | ||
// ... Some time passes ... | ||
// ... Some time passes ... | ||
// Stop timing something. | ||
Logger.timeEnd('self destruct sequence'); // logs: 'self destruct sequence: 1022ms'. | ||
// 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. |
@@ -13,3 +13,3 @@ /*! | ||
// For those that are at home that are keeping score. | ||
Logger.VERSION = "1.2.0"; | ||
Logger.VERSION = "1.3.0"; | ||
@@ -163,5 +163,6 @@ // Function which handles all incoming log messages. | ||
// 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) { | ||
// CreateDefaultHandler returns a handler function which can be passed to `Logger.setHandler()` which will | ||
// write to the window's console object (if present); the optional options object can be used to customise the | ||
// formatter used to format each log message. | ||
Logger.createDefaultHandler = function (options) { | ||
options = options || {}; | ||
@@ -176,7 +177,2 @@ | ||
// Check for the presence of a logger. | ||
if (typeof console === "undefined") { | ||
return; | ||
} | ||
// Map of timestamps by timer labels used to track `#time` and `#timeEnd()` invocations in environments | ||
@@ -191,4 +187,8 @@ // that don't offer a native console method. | ||
Logger.setLevel(options.defaultLevel || Logger.DEBUG); | ||
Logger.setHandler(function(messages, context) { | ||
// Check for the presence of a logger. | ||
if (typeof console === "undefined") { | ||
return function () { /* no console */ }; | ||
} | ||
return function(messages, context) { | ||
// Convert arguments object to Array. | ||
@@ -234,5 +234,12 @@ messages = Array.prototype.slice.call(messages); | ||
} | ||
}); | ||
}; | ||
}; | ||
// 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) { | ||
Logger.setLevel(options && options.defaultLevel || Logger.DEBUG); | ||
Logger.setHandler(Logger.createDefaultHandler(options)); | ||
}; | ||
// Export to popular environments boilerplate. | ||
@@ -239,0 +246,0 @@ if (typeof define === 'function' && define.amd) { |
@@ -1,1 +0,1 @@ | ||
!function(e){"use strict";var n={};n.VERSION="1.2.0";var t,o={},r=function(e,n){return function(){return n.apply(e,arguments)}},i=function(){var e,n,t=arguments,o=t[0];for(n=1;n<t.length;n++)for(e in t[n])e in o||!t[n].hasOwnProperty(e)||(o[e]=t[n][e]);return o},l=function(e,n){return{value:e,name:n}};n.DEBUG=l(1,"DEBUG"),n.INFO=l(2,"INFO"),n.TIME=l(3,"TIME"),n.WARN=l(4,"WARN"),n.ERROR=l(8,"ERROR"),n.OFF=l(99,"OFF");var f=function(e){this.context=e,this.setLevel(e.filterLevel),this.log=this.info};f.prototype={setLevel:function(e){e&&"value"in e&&(this.context.filterLevel=e)},enabledFor:function(e){var n=this.context.filterLevel;return e.value>=n.value},debug:function(){this.invoke(n.DEBUG,arguments)},info:function(){this.invoke(n.INFO,arguments)},warn:function(){this.invoke(n.WARN,arguments)},error:function(){this.invoke(n.ERROR,arguments)},time:function(e){"string"==typeof e&&e.length>0&&this.invoke(n.TIME,[e,"start"])},timeEnd:function(e){"string"==typeof e&&e.length>0&&this.invoke(n.TIME,[e,"end"])},invoke:function(e,n){t&&this.enabledFor(e)&&t(n,i({level:e},this.context))}};var s=new f({filterLevel:n.OFF});!function(){var e=n;e.enabledFor=r(s,s.enabledFor),e.debug=r(s,s.debug),e.time=r(s,s.time),e.timeEnd=r(s,s.timeEnd),e.info=r(s,s.info),e.warn=r(s,s.warn),e.error=r(s,s.error),e.log=e.info}(),n.setHandler=function(e){t=e},n.setLevel=function(e){s.setLevel(e);for(var n in o)o.hasOwnProperty(n)&&o[n].setLevel(e)},n.get=function(e){return o[e]||(o[e]=new f(i({name:e},s.context)))},n.useDefaults=function(e){if(e=e||{},e.formatter=e.formatter||function(e,n){n.name&&e.unshift("["+n.name+"]")},"undefined"!=typeof console){var t={},o=function(e,n){Function.prototype.apply.call(e,console,n)};n.setLevel(e.defaultLevel||n.DEBUG),n.setHandler(function(r,i){r=Array.prototype.slice.call(r);var l,f=console.log;i.level===n.TIME?(l=(i.name?"["+i.name+"] ":"")+r[0],"start"===r[1]?console.time?console.time(l):t[l]=(new Date).getTime():console.timeEnd?console.timeEnd(l):o(f,[l+": "+((new Date).getTime()-t[l])+"ms"])):(i.level===n.WARN&&console.warn?f=console.warn:i.level===n.ERROR&&console.error?f=console.error:i.level===n.INFO&&console.info&&(f=console.info),e.formatter(r,i),o(f,r))})}},"function"==typeof define&&define.amd?define(n):"undefined"!=typeof module&&module.exports?module.exports=n:(n._prevLogger=e.Logger,n.noConflict=function(){return e.Logger=n._prevLogger,n},e.Logger=n)}(this); | ||
!function(e){"use strict";var n={};n.VERSION="1.3.0";var t,o={},r=function(e,n){return function(){return n.apply(e,arguments)}},i=function(){var e,n,t=arguments,o=t[0];for(n=1;n<t.length;n++)for(e in t[n])e in o||!t[n].hasOwnProperty(e)||(o[e]=t[n][e]);return o},l=function(e,n){return{value:e,name:n}};n.DEBUG=l(1,"DEBUG"),n.INFO=l(2,"INFO"),n.TIME=l(3,"TIME"),n.WARN=l(4,"WARN"),n.ERROR=l(8,"ERROR"),n.OFF=l(99,"OFF");var u=function(e){this.context=e,this.setLevel(e.filterLevel),this.log=this.info};u.prototype={setLevel:function(e){e&&"value"in e&&(this.context.filterLevel=e)},enabledFor:function(e){var n=this.context.filterLevel;return e.value>=n.value},debug:function(){this.invoke(n.DEBUG,arguments)},info:function(){this.invoke(n.INFO,arguments)},warn:function(){this.invoke(n.WARN,arguments)},error:function(){this.invoke(n.ERROR,arguments)},time:function(e){"string"==typeof e&&e.length>0&&this.invoke(n.TIME,[e,"start"])},timeEnd:function(e){"string"==typeof e&&e.length>0&&this.invoke(n.TIME,[e,"end"])},invoke:function(e,n){t&&this.enabledFor(e)&&t(n,i({level:e},this.context))}};var a=new u({filterLevel:n.OFF});!function(){var e=n;e.enabledFor=r(a,a.enabledFor),e.debug=r(a,a.debug),e.time=r(a,a.time),e.timeEnd=r(a,a.timeEnd),e.info=r(a,a.info),e.warn=r(a,a.warn),e.error=r(a,a.error),e.log=e.info}(),n.setHandler=function(e){t=e},n.setLevel=function(e){a.setLevel(e);for(var n in o)o.hasOwnProperty(n)&&o[n].setLevel(e)},n.get=function(e){return o[e]||(o[e]=new u(i({name:e},a.context)))},n.createDefaultHandler=function(e){e=e||{},e.formatter=e.formatter||function(e,n){n.name&&e.unshift("["+n.name+"]")};var t={},o=function(e,n){Function.prototype.apply.call(e,console,n)};return"undefined"==typeof console?function(){}:function(r,i){r=Array.prototype.slice.call(r);var l,u=console.log;i.level===n.TIME?(l=(i.name?"["+i.name+"] ":"")+r[0],"start"===r[1]?console.time?console.time(l):t[l]=(new Date).getTime():console.timeEnd?console.timeEnd(l):o(u,[l+": "+((new Date).getTime()-t[l])+"ms"])):(i.level===n.WARN&&console.warn?u=console.warn:i.level===n.ERROR&&console.error?u=console.error:i.level===n.INFO&&console.info&&(u=console.info),e.formatter(r,i),o(u,r))}},n.useDefaults=function(e){n.setLevel(e&&e.defaultLevel||n.DEBUG),n.setHandler(n.createDefaultHandler(e))},"function"==typeof define&&define.amd?define(n):"undefined"!=typeof module&&module.exports?module.exports=n:(n._prevLogger=e.Logger,n.noConflict=function(){return e.Logger=n._prevLogger,n},e.Logger=n)}(this); |
345755
18
9004
140