This repository has been archived by the owner on Mar 3, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLogger.js
166 lines (159 loc) · 7.15 KB
/
Logger.js
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
/**
* A Logger component providing logging methods that won't crash even if the browser's console is undefined.
* Setting the log level will mute lower-prioritized logging methods and enable others.
* Default log level is DEV for localhost, otherwise WARN . Log levels in ascending priority order:
*
* DEBUG < INFO < DEV < WARN < ERROR < OFF
*
* @version 1.1.0
*
* @author Lennart Pegel <[email protected]>
*
* Example (AMD):
* require(['Logger'], function(LOG) {
* LOG.debug('a debug message');
* LOG.info('an info message'); // is NOT output due to higher default log level WARN
* LOG.setLogLevel(LOG.LEVEL.DEBUG);
* LOG.info('another info message'); // IS output
* LOG.dev('some info only relevant during development');
* LOG.warn('a warning');
* LOG.error('an error'); // mostly output in the console including a stacktrace
* });
*
* Example (CommonJS):
* var log = require('neo-log/src/Logger');
* log.debug('hello');
*
* In live environment, the log level can be overridden by placing 'overrideloglevel={level-name>}'
* anywhere in the browser URL. A (session) cookie will save it as the new default log level.
* The cookie can be cleared by placing 'overrideloglevel=default' into the browser URL.
*
* LOG.dev() is intended for development phase and should not be present in final code.
*/
;(function (factory) {
'use strict';
var useDefine = (typeof define === 'function' && define.amd),
useExports = !useDefine && (typeof module === 'object' && typeof (module||{}).exports === 'object');
if (useDefine) {
define([], factory);
} else if (useExports) {
module.exports = factory();
} else {
window.Logger = factory();
}
})(function() {
'use strict';
var isLocalhost = (location.hostname === 'localhost'),
DEFAULT_LOG_LEVEL_NAME = isLocalhost ? 'DEV' : 'WARN',
LOG_LEVEL_OVERRIDE_URL_PARAM = 'overrideloglevel',
LOG_LEVEL_OVERRIDE_COOKIE_NAME = '__overrideloglevel__',
CONSOLE_ENABLED = (typeof console !== 'undefined'),
NOP = function(){},
Logger,
contextSafe = (function() {
var needsBind = false,
testFn = (CONSOLE_ENABLED && typeof console.log === 'function') ? console.log : null;
if (testFn) {
try {
testFn('Logger init'); // Chrome will throw an error here
} catch (e) {
needsBind = true;
console.log('Logger init (context-safe)');
}
}
return function(consoleFnToMakeContextSafe) {
return needsBind ? consoleFnToMakeContextSafe.bind(console) : consoleFnToMakeContextSafe;
}
})(),
getContextSafeConsoleMethodOrDefault = function(consoleMethodName) {
if (CONSOLE_ENABLED && typeof console[consoleMethodName] === 'function') {
return contextSafe(console[consoleMethodName]);
} else if (CONSOLE_ENABLED && typeof console.log === 'function') {
return contextSafe(console.log);
}
return NOP;
},
getLogLevelObjectByNameOrObject = function(nameOrObject) {
var wishedLevelObject = (typeof nameOrObject === 'string') ? Logger.LEVEL[nameOrObject] : nameOrObject;
for (var logLevelKey in Logger.LEVEL) {
if (!Logger.LEVEL.hasOwnProperty(logLevelKey)) {
continue;
}
var levelObject = Logger.LEVEL[logLevelKey];
if (levelObject === wishedLevelObject) {
return levelObject;
}
}
Logger.LEVEL.ERROR.fn('Invalid log level - defaulting to ' + DEFAULT_LOG_LEVEL_NAME);
return Logger.LEVEL[DEFAULT_LOG_LEVEL_NAME];
},
getDefaultLogLevel = function() {
var URL_REGEX = new RegExp(LOG_LEVEL_OVERRIDE_URL_PARAM + '=(DEBUG|INFO|DEV|WARN|ERROR|DEFAULT)', 'i'),
COOKIE_REGEX = new RegExp(LOG_LEVEL_OVERRIDE_COOKIE_NAME + '=(DEBUG|INFO|DEV|WARN|ERROR)'),
logLevelFromUrl = URL_REGEX.test(location.href) && RegExp.$1.toUpperCase(),
logLevelFromCookie = !logLevelFromUrl && COOKIE_REGEX.test(document.cookie||'') && RegExp.$1;
if (logLevelFromUrl==='DEFAULT') {
var cookieExpiryDate = new Date();
cookieExpiryDate.setDate(cookieExpiryDate.getDate() - 1);
document.cookie = LOG_LEVEL_OVERRIDE_COOKIE_NAME + '=; expires=' + cookieExpiryDate.toUTCString();
Logger.LEVEL.INFO.fn('[Log level cookie cleared]');
return DEFAULT_LOG_LEVEL_NAME;
}
if (logLevelFromUrl) {
document.cookie = LOG_LEVEL_OVERRIDE_COOKIE_NAME + '=' + encodeURIComponent(logLevelFromUrl);
Logger.LEVEL.INFO.fn('[Log level overridden by URL parameter]');
return logLevelFromUrl;
}
if (logLevelFromCookie) {
Logger.LEVEL.INFO.fn('[Log level overridden by Cookie. ' +
'To reset add \'' + LOG_LEVEL_OVERRIDE_URL_PARAM + '=default\' to the URL]');
return logLevelFromCookie;
}
return DEFAULT_LOG_LEVEL_NAME;
};
Logger = {
LEVEL: {
DEBUG: {prio: 10, fn: getContextSafeConsoleMethodOrDefault('debug')},
INFO: {prio: 20, fn: getContextSafeConsoleMethodOrDefault('info')},
DEV: {prio: 25, fn: getContextSafeConsoleMethodOrDefault('log')},
WARN: {prio: 30, fn: getContextSafeConsoleMethodOrDefault('warn')},
ERROR: {prio: 40, fn: getContextSafeConsoleMethodOrDefault('error')},
OFF: {prio: 50, fn: NOP}
},
/** @static */
debug: NOP,
/** @static */
info: NOP,
/** @static */
dev: NOP,
/** @static */
warn: NOP,
/** @static */
error: NOP,
/**
* Sets a new log level. If an invalid level is given, {@link DEFAULT_LOG_LEVEL_NAME} will be used.
* @param newLogLevelNameOrObject (Object|String) the name of the log level OR the LEVEL.* object itself
* @static
*/
setLogLevel: function(newLogLevelNameOrObject) {
var newLogLevel = getLogLevelObjectByNameOrObject(newLogLevelNameOrObject),
newPrio = newLogLevel.prio,
logLevel,
logMethodName,
isMethodEnabled;
for (var logLevelKey in Logger.LEVEL) {
if (Logger.LEVEL.hasOwnProperty(logLevelKey)) {
logLevel = Logger.LEVEL[logLevelKey];
if (logLevel === newLogLevel) {
Logger.LEVEL.INFO.fn('[Log level: ' + logLevelKey + ']');
}
logMethodName = logLevelKey.toLowerCase();
isMethodEnabled = (logLevel.prio >= newPrio);
Logger[logMethodName] = (isMethodEnabled) ? logLevel.fn : NOP;
}
}
}
};
Logger.setLogLevel(getDefaultLogLevel());
return Logger;
});