UNPKG

6.99 kBJavaScriptView Raw
1/*! loglevel - v1.4.0 - https://github.com/pimterry/loglevel - (c) 2015 Tim Perry - licensed MIT */
2(function (root, definition) {
3 "use strict";
4 if (typeof module === 'object' && module.exports && typeof require === 'function') {
5 module.exports = definition();
6 } else if (typeof define === 'function' && typeof define.amd === 'object') {
7 define(definition);
8 } else {
9 root.log = definition();
10 }
11}(this, function () {
12 "use strict";
13 var noop = function() {};
14 var undefinedType = "undefined";
15
16 function realMethod(methodName) {
17 if (typeof console === undefinedType) {
18 return false; // We can't build a real method without a console to log to
19 } else if (console[methodName] !== undefined) {
20 return bindMethod(console, methodName);
21 } else if (console.log !== undefined) {
22 return bindMethod(console, 'log');
23 } else {
24 return noop;
25 }
26 }
27
28 function bindMethod(obj, methodName) {
29 var method = obj[methodName];
30 if (typeof method.bind === 'function') {
31 return method.bind(obj);
32 } else {
33 try {
34 return Function.prototype.bind.call(method, obj);
35 } catch (e) {
36 // Missing bind shim or IE8 + Modernizr, fallback to wrapping
37 return function() {
38 return Function.prototype.apply.apply(method, [obj, arguments]);
39 };
40 }
41 }
42 }
43
44 // these private functions always need `this` to be set properly
45
46 function enableLoggingWhenConsoleArrives(methodName, level, loggerName) {
47 return function () {
48 if (typeof console !== undefinedType) {
49 replaceLoggingMethods.call(this, level, loggerName);
50 this[methodName].apply(this, arguments);
51 }
52 };
53 }
54
55 function replaceLoggingMethods(level, loggerName) {
56 /*jshint validthis:true */
57 for (var i = 0; i < logMethods.length; i++) {
58 var methodName = logMethods[i];
59 this[methodName] = (i < level) ?
60 noop :
61 this.methodFactory(methodName, level, loggerName);
62 }
63 }
64
65 function defaultMethodFactory(methodName, level, loggerName) {
66 /*jshint validthis:true */
67 return realMethod(methodName) ||
68 enableLoggingWhenConsoleArrives.apply(this, arguments);
69 }
70
71 var logMethods = [
72 "trace",
73 "debug",
74 "info",
75 "warn",
76 "error"
77 ];
78
79 function Logger(name, defaultLevel, factory) {
80 var self = this;
81 var currentLevel;
82 var storageKey = "loglevel";
83 if (name) {
84 storageKey += ":" + name;
85 }
86
87 function persistLevelIfPossible(levelNum) {
88 var levelName = (logMethods[levelNum] || 'silent').toUpperCase();
89
90 // Use localStorage if available
91 try {
92 window.localStorage[storageKey] = levelName;
93 return;
94 } catch (ignore) {}
95
96 // Use session cookie as fallback
97 try {
98 window.document.cookie =
99 encodeURIComponent(storageKey) + "=" + levelName + ";";
100 } catch (ignore) {}
101 }
102
103 function getPersistedLevel() {
104 var storedLevel;
105
106 try {
107 storedLevel = window.localStorage[storageKey];
108 } catch (ignore) {}
109
110 if (typeof storedLevel === undefinedType) {
111 try {
112 var cookie = window.document.cookie;
113 var location = cookie.indexOf(
114 encodeURIComponent(storageKey) + "=");
115 if (location) {
116 storedLevel = /^([^;]+)/.exec(cookie.slice(location))[1];
117 }
118 } catch (ignore) {}
119 }
120
121 // If the stored level is not valid, treat it as if nothing was stored.
122 if (self.levels[storedLevel] === undefined) {
123 storedLevel = undefined;
124 }
125
126 return storedLevel;
127 }
128
129 /*
130 *
131 * Public API
132 *
133 */
134
135 self.levels = { "TRACE": 0, "DEBUG": 1, "INFO": 2, "WARN": 3,
136 "ERROR": 4, "SILENT": 5};
137
138 self.methodFactory = factory || defaultMethodFactory;
139
140 self.getLevel = function () {
141 return currentLevel;
142 };
143
144 self.setLevel = function (level, persist) {
145 if (typeof level === "string" && self.levels[level.toUpperCase()] !== undefined) {
146 level = self.levels[level.toUpperCase()];
147 }
148 if (typeof level === "number" && level >= 0 && level <= self.levels.SILENT) {
149 currentLevel = level;
150 if (persist !== false) { // defaults to true
151 persistLevelIfPossible(level);
152 }
153 replaceLoggingMethods.call(self, level, name);
154 if (typeof console === undefinedType && level < self.levels.SILENT) {
155 return "No console available for logging";
156 }
157 } else {
158 throw "log.setLevel() called with invalid level: " + level;
159 }
160 };
161
162 self.setDefaultLevel = function (level) {
163 if (!getPersistedLevel()) {
164 self.setLevel(level, false);
165 }
166 };
167
168 self.enableAll = function(persist) {
169 self.setLevel(self.levels.TRACE, persist);
170 };
171
172 self.disableAll = function(persist) {
173 self.setLevel(self.levels.SILENT, persist);
174 };
175
176 // Initialize with the right level
177 var initialLevel = getPersistedLevel();
178 if (initialLevel == null) {
179 initialLevel = defaultLevel == null ? "WARN" : defaultLevel;
180 }
181 self.setLevel(initialLevel, false);
182 }
183
184 /*
185 *
186 * Package-level API
187 *
188 */
189
190 var defaultLogger = new Logger();
191
192 var _loggersByName = {};
193 defaultLogger.getLogger = function getLogger(name) {
194 if (typeof name !== "string" || name === "") {
195 throw new TypeError("You must supply a name when creating a logger.");
196 }
197
198 var logger = _loggersByName[name];
199 if (!logger) {
200 logger = _loggersByName[name] = new Logger(
201 name, defaultLogger.getLevel(), defaultLogger.methodFactory);
202 }
203 return logger;
204 };
205
206 // Grab the current global log variable in case of overwrite
207 var _log = (typeof window !== undefinedType) ? window.log : undefined;
208 defaultLogger.noConflict = function() {
209 if (typeof window !== undefinedType &&
210 window.log === defaultLogger) {
211 window.log = _log;
212 }
213
214 return defaultLogger;
215 };
216
217 return defaultLogger;
218}));