:ledger: Minimal lightweight logging for JavaScript, adding reliable log level methods to wrap any available console.log methods

View the Project on GitHub pimterry/loglevel

loglevel NPM version NPM downloads Build status Coveralls percentage

Don’t debug with logs alone - check out HTTP Toolkit: beautiful, powerful & open-source tools for building, testing & debugging HTTP(S)

Minimal lightweight simple logging for JavaScript. loglevel replaces console.log() and friends with level-based logging and filtering, with none of console’s downsides.

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:





Downloading loglevel

If you’re using NPM, you can just run npm install loglevel.

Alternatively, loglevel is also available via Bower (bower install loglevel), as a Webjar, or an Atmosphere package (for Meteor)

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 unpkg at https://unpkg.com/loglevel/dist/loglevel.min.js (this will redirect to a latest version, use the resulting redirected URL if you want to pin that version).

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.

Setting it up

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:

CommonsJS (e.g. Node)

var log = require('loglevel');
log.warn("unreasonably simple");

AMD (e.g. RequireJS)

define(['loglevel'], function(log) {
   log.warn("dangerously convenient");

Directly in your web page:

<script src="loglevel.min.js"></script>
log.warn("too easy");

As an ES6 module:

loglevel is written as a UMD module, with a single object exported. Unfortunately ES6 module loaders & transpilers don’t all handle this the same way. Some will treat the object as the default export, while others use it as the root exported object. In addition, loglevel includes default property on the root object, designed to help handle this differences. Nonetheless, there’s two possible syntaxes that might work for you:

For most tools, using the default import is the most convenient and flexible option:

import log from 'loglevel';

For some tools though, it might better to wildcard import the whole object:

import * as log from 'loglevel';

There’s no major difference, unless you’re using TypeScript & building a loglevel plugin (in that case, see https://github.com/pimterry/loglevel/issues/149). In general though, just use whichever suits your environment, and everything should work out fine.

With noConflict():

If you’re using another JavaScript library that exposes a ‘log’ global, you can run into conflicts with loglevel. Similarly to jQuery, you can solve this by putting loglevel into no-conflict mode immediately after it is loaded onto the page. This resets to ‘log’ global to its value before loglevel was loaded (typically undefined), and returns the loglevel object, which you can then bind to another name yourself.

For example:

<script src="loglevel.min.js"></script>
var logging = log.noConflict();

logging.warn("still pretty easy");


loglevel includes its own type definitions, assuming you’re using a modern module environment (e.g. Node.JS, webpack, etc), you should be able to use the ES6 syntax above, and everything will work immediately. If not, file a bug!

If you really want to use LogLevel as a global however, but from TypeScript, you’ll need to declare it as such first. To do that:


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:


Existing plugins:

loglevel-plugin-prefix - plugin for loglevel message prefixing.

loglevel-plugin-remote - plugin for sending loglevel messages to a remote log server.

ServerSend - https://github.com/artemyarulin/loglevel-serverSend - Forward your log messages to a remote server.

DEBUG - https://github.com/vectrlabs/loglevel-debug - Control logging from a DEBUG environmental variable (similar to the classic Debug module)

Writing plugins:

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 methodName, at the given configured (not actual) level logLevel, for a logger with the given name loggerName. If you’d like to retain all the reliability and features of loglevel, it’s recommended that this wraps the initially provided value of log.methodFactory.

For example, a plugin to prefix all log messages with “Newsflash: “ would look like:

var originalFactory = log.methodFactory;
log.methodFactory = function (methodName, logLevel, loggerName) {
    var rawMethod = originalFactory(methodName, logLevel, loggerName);

    return function (message) {
        rawMethod("Newsflash: " + message);
log.setLevel(log.getLevel()); // Be sure to call setLevel method in order to apply plugin

(The above supports only a single string log.warn("...") argument for clarity, but it’s easy to extend to a fuller variadic version.)

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

Developing & Contributing

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 npm: run npm run dist to build a distributable version of the project (in /dist), or npm test to just run the tests and linting. During development you can run npm run 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!

Release process

To do a release of loglevel:

Release History

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.0 - Add getLevel(), setDefaultLevel() and getLogger() functionality for more fine-grained log level control

v1.4.1 - Reorder UMD (#92) to improve bundling tool compatibility

v1.5.0 - Fix log.debug (#111) after V8 changes deprecating console.debug, check for window upfront (#104), and add .log alias for .debug (#64)

v1.5.1 - Fix bug (#112) in level-persistence cookie fallback, which failed if it wasn’t the first cookie present

v1.6.0 - Add a name property to loggers and add log.getLoggers() (#114), and recommend unpkg as CDN instead of CDNJS.

v1.6.1 - Various small documentation & test updates

v1.6.2 - Include TypeScript type definitions in the package itself

v1.6.3 - Avoid TypeScript type conflicts with other global log types (e.g. core-js)

v1.6.4 - Ensure package.json’s ‘main’ is a fully qualified path, to fix webpack issues

v1.6.5 - Ensure the provided message is included when calling trace() in IE11

v1.6.6 - Fix bugs in v1.6.5, which caused issues in node.js & IE < 9

v1.6.7 - Fix a bug in environments with window defined but no window.navigator

v1.6.8 - Update TypeScript type definitions to include log.log().

v1.7.0 - Add support for Symbol-named loggers, and a .default property to help with ES6 module usage.

v1.7.1 - Update TypeScript types to support Symbol-named loggers.

v1.8.0 - Add resetLevel() method to clear persisted levels & reset to defaults

v1.8.1 - Fix incorrect type definitions for MethodFactory

loglevel for enterprise

Available as part of the Tidelift Subscription.

The maintainers of loglevel and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. Learn more.


Copyright (c) 2013 Tim Perry Licensed under the MIT license.