-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathlogger.js
More file actions
191 lines (159 loc) · 5.91 KB
/
logger.js
File metadata and controls
191 lines (159 loc) · 5.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
/*!
* js-logger - http://github.com/jonnyreeves/js-logger
* Jonny Reeves, http://jonnyreeves.co.uk/
* js-logger may be freely distributed under the MIT license.
*/
/*jshint sub:true*/
/*global window:true,define:true, module:true*/
(function (window) {
"use strict";
// Top level module for the global, static logger instance.
var Logger = { };
// For those that are at home that are keeping score.
Logger.VERSION = "0.9.2";
// Function which handles all incoming log messages.
var logHandler;
// Map of ContextualLogger instances by name; used by Logger.get() to return the same named instance.
var contextualLoggersByNameMap = {};
// Polyfill for ES5's Function.bind.
var bind = function(scope, func) {
return function() {
return func.apply(scope, arguments);
};
};
// Super exciting object merger-matron 9000 adding another 100 bytes to your download.
var merge = function () {
var args = arguments, target = args[0], key, i;
for (i = 1; i < args.length; i++) {
for (key in args[i]) {
if (!(key in target) && args[i].hasOwnProperty(key)) {
target[key] = args[i][key];
}
}
}
return target;
};
// Helper to define a logging level object; helps with optimisation.
var defineLogLevel = function(value, name) {
return { value: value, name: name };
};
// Predefined logging levels.
Logger.DEBUG = defineLogLevel(1, 'DEBUG');
Logger.INFO = defineLogLevel(2, 'INFO');
Logger.WARN = defineLogLevel(4, 'WARN');
Logger.ERROR = defineLogLevel(8, 'ERROR');
Logger.OFF = defineLogLevel(99, 'OFF');
// Inner class which performs the bulk of the work; ContextualLogger instances can be configured independently
// of each other.
var ContextualLogger = function(defaultContext) {
this.context = defaultContext;
this.setLevel(defaultContext.filterLevel);
this.log = this.debug; // Convenience alias.
};
ContextualLogger.prototype = {
// Changes the current logging level for the logging instance.
setLevel: function(newLevel) {
// Ensure the supplied Level object looks valid.
if (newLevel && "value" in newLevel) {
this.context.filterLevel = newLevel;
}
},
// Is the logger configured to output messages at the supplied level?
enabledFor: function (lvl) {
var filterLevel = this.context.filterLevel;
return lvl.value >= filterLevel.value;
},
debug: function () {
this.invoke(Logger.DEBUG, arguments);
},
info: function () {
this.invoke(Logger.INFO, arguments);
},
warn: function () {
this.invoke(Logger.WARN, arguments);
},
error: function () {
this.invoke(Logger.ERROR, arguments);
},
// Invokes the logger callback if it's not being filtered.
invoke: function (level, msgArgs) {
if (logHandler && this.enabledFor(level)) {
logHandler(msgArgs, merge({ level: level }, this.context));
}
}
};
// Protected instance which all calls to the to level `Logger` module will be routed through.
var globalLogger = new ContextualLogger({ filterLevel: Logger.OFF });
// Configure the global Logger instance.
(function() {
// Shortcut for optimisers.
var L = Logger;
L.enabledFor = bind(globalLogger, globalLogger.enabledFor);
L.debug = bind(globalLogger, globalLogger.debug);
L.info = bind(globalLogger, globalLogger.info);
L.warn = bind(globalLogger, globalLogger.warn);
L.error = bind(globalLogger, globalLogger.error);
// Don't forget the convenience alias!
L.log = L.debug;
}());
// Set the global logging handler. The supplied function should expect two arguments, the first being an arguments
// object with the supplied log messages and the second being a context object which contains a hash of stateful
// parameters which the logging function can consume.
Logger.setHandler = function (func) {
logHandler = func;
};
// Sets the global logging filter level which applies to *all* previously registred, and future Logger instances.
// (note that named loggers (retrieved via `Logger.get`) can be configured indendently if required).
Logger.setLevel = function(level) {
// Set the globalLogger's level.
globalLogger.setLevel(level);
// Apply this level to all registered contextual loggers.
for (var key in contextualLoggersByNameMap) {
if (contextualLoggersByNameMap.hasOwnProperty(key)) {
contextualLoggersByNameMap[key].setLevel(level);
}
}
};
// Retrieve a ContextualLogger instance. Note that named loggers automatically inherit the global logger's level,
// default context and log handler.
Logger.get = function (name) {
// All logger instances are cached so they can be configured ahead of use.
return contextualLoggersByNameMap[name] ||
(contextualLoggersByNameMap[name] = new ContextualLogger(merge({ name: name }, globalLogger.context)));
};
// Configure and example a Default implementation which writes to the `window.console` (if present).
Logger.useDefaults = function(defaultLevel) {
// Check for the presence of a logger.
if (!("console" in window)) {
return;
}
var console = window.console;
Logger.setLevel(defaultLevel || Logger.DEBUG);
Logger.setHandler(function(messages, context) {
var hdlr = console.log;
// Prepend the logger's name to the log message for easy identification.
if (context.name) {
Array.prototype.splice.call(messages, 0, 0, "[" + context.name + "]");
}
// Delegate through to custom warn/error loggers if present on the console.
if (context.level === Logger.WARN && console.warn) {
hdlr = console.warn;
} else if (context.level === Logger.ERROR && console.error) {
hdlr = console.error;
} else if (context.level === Logger.INFO && console.info) {
hdlr = console.info;
}
hdlr.apply(console, messages);
});
};
// Export to popular environments boilerplate.
if (typeof define === 'function' && define.amd) {
define(Logger);
}
else if (typeof module !== 'undefined' && module.exports) {
module.exports = Logger;
}
else {
window['Logger'] = Logger;
}
}(window));