This is a barebones reliable everyday logging library. It does not do fancy things, it does not let you reconfigure appenders or add complex log filtering rules or boil tea (more's the pity), but it does have the all core functionality that you actually use:
If you're using NPM, you can just run
npm install loglevel.
Alternatively if you just want to grab the file yourself, you can download either the current stable production version or the development version directly, or reference it remotely on CDNJS at
Finally, if you want to tweak loglevel to your own needs or you immediately need the cutting-edge version, clone this repo and see Developing & Contributing below for build instructions.
loglevel supports AMD (e.g. RequireJS), CommonJS (e.g. Node.js) and direct usage (e.g. loading globally with a <script> tag) loading methods. You should be able to do nearly anything, and then skip to the next section anyway and have it work. Just in case though, here's some specific examples that definitely do the right thing:
var log = require'loglevel';log.info"unreasonably simple";
undefined), and returns the loglevel object, which you can then bind to another name yourself.
The loglevel API is extremely minimal. All methods are available on the root loglevel object, which it's suggested you name 'log' (this is the default if you import it in globally, and is what's set up in the above examples). The API consists of:
5 actual logging methods, ordered and available as:
Exact output formatting of these will depend on the console available in the current context of your application. Notably, many environments will include a full stack trace with all trace() calls, and icons or similar to highlight other calls.
These methods should never fail in any environment, even if no console object is currently available, and should always fall back to an available log method even if the specific method called (e.g. warn) isn't available.
log.setLevel(level, [persist]) method.
This disables all logging below the given level, so that after a log.setLevel("warn") call log.warn("something") or log.error("something") will output messages, but log.info("something") will not.
This can take either a log level name or 'silent' (which disables everything) in one of a few forms:
Where possible the log level will be persisted. LocalStorage will be used if available, falling back to cookies if not. If neither is available in the current environment (i.e. in Node), or if you pass
false as the optional 'persist' second argument, persistence will be skipped.
If log.setLevel() is called when a console object is not available (in IE 8 or 9 before the developer tools have been opened, for example) logging will remain silent until the console becomes available, and then begin logging at the requested level.
This sets the current log level only if one has not been persisted and can’t be loaded. This is useful when initializing scripts; if a developer or user has previously called
setLevel(), this won’t alter their settings. For example, your application might set the log level to
error in a production environment, but when debugging an issue, you might call
setLevel("trace") on the console to see all the logs. If that
error setting was set using
setDefaultLevel(), it will still say as
trace on subsequent page loads and refreshes instead of resetting to
level argument takes is the same values that you might pass to
setLevel(). Levels set using
setDefaultLevel() never persist to subsequent page loads.
These enable or disable all log messages, and are equivalent to log.setLevel("trace") and log.setLevel("silent") respectively.
Returns the current logging level, as a number from 0 (trace) to 5 (silent)
It's very unlikely you'll need to use this for normal application logging; it's provided partly to help plugin development, and partly to let you optimize logging code as below, where debug data is only generated if the level is set such that it'll actually be logged. This probably doesn't affect you, unless you've run profiling on your code and you have hard numbers telling you that your log data generation is a real performance problem.
if loggetLevel <= loglevelsDEBUGvar logData = runExpensiveDataGeneration;logdebuglogData;
This notably isn't the right solution to avoid the cost of string concatenation in your logging. Firstly, it's very unlikely that string concatenation in your logging is really an important performance problem. Even if you do genuinely have hard metrics showing that it is though, the better solution that wrapping your log statements in this is to use multiple arguments, as below. The underlying console API will automatically concatenate these for you if logging is enabled, and if it isn't then all log methods are no-ops, and no concatenation will be done at all.
// Prints 'My concatenated log message'logdebug"My " "concatenated " "log message";
This gets you a new logger object that works exactly like the root
log object, but can have its level and logging methods set independently. All loggers must have a name (which is a non-empty string). Calling
getLogger() multiple times with the same name will return an identical logger object.
In large applications, it can be incredibly useful to turn logging on and off for particular modules as you are working with them. Using the
getLogger() method lets you create a separate logger for each part of your application with its own logging level.
Likewise, for small, independent modules, using a named logger instead of the default root logger allows developers using your module to selectively turn on deep, trace-level logging when trying to debug problems, while logging only errors or silencing logging altogether under normal circumstances.
Example usage (using CommonJS modules, but you could do the same with any module system):
// In module-one.js:var log = require"loglevel"getLogger"module-one";logdebug"Amazing message from module one.";// In module-two.js:var log = require"loglevel"getLogger"module-two";logdebug"Special message from module two.";// In your main application module:var log = require"loglevel";var moduleOne = require"module-one";var moduleTwo = require"module-two";loggetLogger"module-two"setLevel"TRACE";moduleOnedoSomethingAmazing;moduleTwodoSomethingSpecial;// logs "Special message from module two."// (but nothing from module one.)
Loggers returned by
getLogger() support all the same properties and methods as the default root logger, excepting
noConflict() and the
getLogger() method itself.
Like the root logger, other loggers can have their logging level saved. If a logger’s level has not been saved, it will inherit the root logger’s level when it is first created. If the root logger’s level changes later, the new level will not affect other loggers that have already been created.
Likewise, loggers will inherit the root logger’s
methodFactory. After creation, each logger can have its
methodFactory independently set. See the plugins section below for more about
ServerSend - https://github.com/artemyarulin/loglevel-serverSend - Forward your log messages to a remote server
Loglevel provides a simple reliable minimal base for console logging that works everywhere. This means it doesn't include lots of fancy functionality that might be useful in some cases, such as log formatting and redirection (e.g. also sending log messages to a server over AJAX)
Including that would increase the size and complexity of the library, but more importantly would remove stacktrace information. Currently log methods are either disabled, or enabled with directly bound versions of the console.log methods (where possible). This means your browser shows the log message as coming from your code at the call to
log.info("message!") not from within loglevel, since it really calls the bound console method directly, without indirection. The indirection required to dynamically format, further filter, or redirect log messages would stop this.
There's clearly enough enthusiasm for this even at that cost though that loglevel now includes a plugin API. To use it, redefine log.methodFactory(methodName, logLevel, loggerName) with a function of your own. This will be called for each enabled method each time the level is set (including initially), and should return a function to be used for the given log method, at the given level, for a logger with the given name. If you'd like to retain all the reliability and features of loglevel, it's recommended that this wraps the initially provided value of
For example, a plugin to prefix all log messages with "Newsflash: " would look like:
var originalFactory = logmethodFactory;var rawMethod = originalFactorymethodName logLevel loggerName;returnrawMethod"Newsflash: " + message;;;logsetLevel"warn"; // Be sure to call setLevel method in order to apply plugin
If you develop and release a plugin, please get in contact! I'd be happy to reference it here for future users. Some consistency is helpful; naming your plugin 'loglevel-PLUGINNAME' (e.g. loglevel-newsflash) is preferred, as is giving it the 'loglevel-plugin' keyword in your package.json
In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality.
Builds can be run with grunt: run
grunt dist to build a distributable version of the project (in /dist), or
grunt test to just run the tests and linting. During development you can run
grunt watch and it will monitor source files, and rerun the tests and linting as appropriate when they're changed.
Also, please don't manually edit files in the "dist" subdirectory as they are generated via Grunt. You'll find source code in the "lib" subdirectory!
To do a release of loglevel:
grunt distto build a distributable version in dist/
npm publish .to publish to NPM
jam publishto publish to JamJS
v0.1.0 - First working release with apparent compatibility with everything tested
v0.2.0 - Updated release with various tweaks and polish and real proper documentation attached
v0.3.0 - Some bugfixes (#12, #14), cookie-based log level persistence, doc tweaks, support for Bower and JamJS
v0.3.1 - Fixed incorrect text in release build banner, various other minor tweaks
v0.4.0 - Use LocalStorage for level persistence if available, compatibility improvements for IE, improved error messages, multi-environment tests
v0.5.0 - Fix for Modernizr+IE8 issues, improved setLevel error handling, support for auto-activation of desired logging when console eventually turns up in IE8
v0.6.0 - Handle logging in Safari private browsing mode (#33), fix TRACE level persistence bug (#35), plus various minor tweaks
v1.0.0 - Official stable release! Fixed a bug with localStorage in Android webviews, improved CommonJS detection, and added noConflict().
v1.1.0 - Added support for including loglevel with preprocessing and .apply() (#50), and fixed QUnit dep version which made tests potentially unstable.
v1.2.0 - New plugin API! Plus various bits of refactoring and tidy up, nicely simplifying things and trimming the size down.
v1.3.0 - Make persistence optional in setLevel, plus lots of documentation updates and other small tweaks
v1.3.1 - With the new optional persistence, stop unnecessarily persisting the initially set default level (warn)
v1.4 - Add getLevel(), setDefaultLevel() and getLogger() functionality for more fine-grained log level control
Copyright (c) 2013 Tim Perry
Licensed under the MIT license.