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

Overview

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:

Features

Simple

  • Log things at a given level (trace/debug/info/warn/error) to the console object (as seen in all modern browsers & node.js)
  • Filter logging by level (all the above or 'silent'), so you can disable all but error logging in production, and then run log.setLevel("trace") in your console to turn it all back on for a furious debugging session
  • Single file, no dependencies, weighs in at 1.1KB minified and gzipped

Effective

  • Log methods gracefully fall back to simpler console logging methods if more specific ones aren't available: so calls to log.debug() go to console.debug() if possible, or console.log() if not
  • Logging calls still succeed even if there's no console object at all, so your site doesn't break when people visit with old browsers that don't support the console object (here's looking at you IE) and similar
  • This then comes together giving a consistent reliable API that works in every JavaScript environment with a console available, and never breaks anything anywhere else

Convenient

  • Log output keeps line numbers: most JS logging frameworks call console.log methods through wrapper functions, clobbering your stacktrace and making the extra info many browsers provide useless. We'll have none of that thanks.
  • It works with all the standard JavaScript loading systems out of the box (CommonJS, AMD, or just as a global)
  • Logging is filtered to "warn" level by default, to keep your live site clean in normal usage (or you can trivially re-enable everything with an initial log.enableAll() call)
  • Magically handles situations where console logging is not initially available (IE8/9), and automatically enables logging as soon as it does become available (when developer console is opened)
  • TypeScript type definitions included, so no need for extra @types packages
  • Extensible, to add other log redirection, filtering, or formatting functionality, while keeping all the above (except you will clobber your stacktrace, see Plugins below)

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>
<script>
log.warn("too easy");
</script>

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';
log.warn("module-tastic");

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

import * as log from 'loglevel';
log.warn("module-tastic");

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>
<script>
var logging = log.noConflict();

logging.warn("still pretty easy");
</script>

TypeScript:

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:

  • Create a loglevel.d.ts file
  • Ensure that file is included in your build (e.g. add it to include in your tsconfig, pass it on the command line, or use ///<reference path="./loglevel.d.ts" />)
  • In that file, add:
    import * as log from 'loglevel';
    export as namespace log;
    export = log;

Documentation

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:

    • log.trace(msg)
    • log.debug(msg)
    • log.info(msg)
    • log.warn(msg)
    • log.error(msg)

    log.log(msg) is also available, as an alias for log.debug(msg), to improve compatibility with console, and make migration easier.

    Exact output formatting of these will depend on the console available in the current context of your application. For example, 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.

    Be aware that all this means that these method won't necessarily always produce exactly the output you expect in every environment; loglevel only guarantees that these methods will never explode on you, and that it will call the most relevant method it can find, with your argument. For example, log.trace(msg) in Firefox before version 64 prints the stacktrace by itself, and doesn't include your message (see #84).

  • A 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:

    • As a log level from the internal levels list, e.g. log.levels.SILENT ← for type safety
    • As a string, like 'error' (case-insensitive) ← for a reasonable practical balance
    • As a numeric index from 0 (trace) to 5 (silent) ← deliciously terse, and more easily programmable (...although, why?)

    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.

  • A log.setDefaultLevel(level) method.

    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 stay as trace on subsequent page loads and refreshes instead of resetting to error.

    The level argument takes is the same values that you might pass to setLevel(). Levels set using setDefaultLevel() never persist to subsequent page loads.

  • log.enableAll() and log.disableAll() methods.

    These enable or disable all log messages, and are equivalent to log.setLevel("trace") and log.setLevel("silent") respectively.

  • A log.getLevel() method.

    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 (log.getLevel() <= log.levels.DEBUG) {
      var logData = runExpensiveDataGeneration();
      log.debug(logData);
    }

    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'
    log.debug("My ", "concatenated ", "log message");
  • A log.getLogger(loggerName) method.

    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, or a Symbol). 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");
    function doSomethingAmazing() {
      log.debug("Amazing message from module one.");
    }
    
    // In module-two.js:
    var log = require("loglevel").getLogger("module-two");
    function doSomethingSpecial() {
      log.debug("Special message from module two.");
    }
    
    // In your main application module:
    var log = require("loglevel");
    var moduleOne = require("module-one");
    var moduleTwo = require("module-two");
    log.getLogger("module-two").setLevel("TRACE");
    
    moduleOne.doSomethingAmazing();
    moduleTwo.doSomethingSpecial();
    // 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. Loggers with Symbol names (rather than string names) will be always considered as unique instances, and will never have their logging level saved or restored.

    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 methodFactory.

  • A log.getLoggers() method.

    This will return you the dictionary of all loggers created with getLogger, keyed off of their names.

Plugins

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, 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 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 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:

  • Update the version number in package.json and bower.json
  • Run npm run dist to build a distributable version in dist/
  • Update the release history in this file (below)
  • Commit the built code, tagging it with the version number and a brief message about the release
  • Push to Github
  • Run npm publish . to publish to NPM

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.

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.

License

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

Comments
  • Missing 'log' method to serve as a drop-in replacement for 'console'

    Missing 'log' method to serve as a drop-in replacement for 'console'

    I'd like to replace all console.* calls to loglevel.* calls but I discovered that there is no log method which is widely used with console. The info method does not fit well because the browser console highlights the info message with an icon making these messages somewhat more specific than default logging.

    Any chance adding log?

    opened by sompylasar 19
  • Supporting multiple loggers

    Supporting multiple loggers

    Hey,

    In large projects it is extremely useful to have the flexibility of defining different log levels for different modules / subsystems / files / objects, especially during debugging or bug chasing, in order to only see debug and trace log levels for a specific object / module. I have already implemented something like that in our wrapped loglevel meteor package:

    https://github.com/practicalmeteor/meteor-loglevel

    It also gave me the flexibility to define log prefixes that maintain line numbers (pushing the prefix as the first argument to apply), which, I suspect, is one of the more asked for features.

    Will you accept a PR that allows to create new loglevel() objects? Regarding persistence, the constructor can receive an options object that include a namespace string that will be used to load the log level for that namespace. It can also accept a prefix option and even a map of custom log levels to console log methods.

    opened by rbabayoff 15
  • Get current logging level.

    Get current logging level.

    For some operations it is good to know the current logging level.

    For example, if you do string concatenation in your logging statements that are in sections of code that get called a lot, Javascript does the relatively-expensive string concatenation even if the current logging level won't actually output the string.

    I think something like log.getLevel() would be useful so you could do the expensive operation only when needed.

    opened by dmwyatt 14
  • loglevel doesn't play nice with modernizr on ie8

    loglevel doesn't play nice with modernizr on ie8

    modernizr introduces the bind method to Function.prototype in IE8 which then throws errors when loglevel library is loaded. this seems to happen because in IE8 methods like console.log and console.error have types object (i.e. "typeof console.log === 'object' and typeof console.log !== 'function').

    opened by kraf 14
  • [Feature]: Add formatted Suffix

    [Feature]: Add formatted Suffix

    • Modification in order to add suffix to logging without loss console log main functionality such as tracing:

    Basic example:

    
    const  socketLog = logger.getLogger('socketLog');
    socketLog.setPrefix("[SocketLog]");
    socketLog.info("test");
    
    

    Formating text:

    const  socketLog = logger.getLogger('socketLog');
    chicken.setPrefix(formating.bind(socketLog,"socketLog"));
    socketLog.info("test");
    function formating(name){ 
       return  new Date().toTimeString().replace(/.*(\d{2}:\d{2}:\d{2}).*/, '$1') + `(${name || this.name})`
    }
    
    opened by itamayo 11
  • added ability to replace console

    added ability to replace console

    This push implements two functions allowing loglevel to replace window.console but also restore it if required. I have done a manual test and both functions worked correctly.

    This is to add the feature requested here: #42

    opened by VizuaaLOG 11
  • Debug level is not showing in console

    Debug level is not showing in console

    As the title states, calls to log.debug do not print results to the console. The following script index.js was run with node index.js:

    var log = require('loglevel');
    
    log.setLevel(log.levels.TRACE);
    
    log.error('error');
    log.warn('warn')
    log.info('info');
    log.debug('debug');
    log.trace('trace');
    

    and the following was displayed on the console:

    error
    warn
    info
    Trace: trace
        at Object.<anonymous> (/some/random/directory/index.js:9:5)
        at Module._compile (module.js:569:30)
        at Object.Module._extensions..js (module.js:580:10)
        at Module.load (module.js:503:32)
        at tryModuleLoad (module.js:466:12)
        at Function.Module._load (module.js:458:3)
        at Function.Module.runMain (module.js:605:10)
        at startup (bootstrap_node.js:158:16)
        at bootstrap_node.js:575:3
    

    As the output shows, the DEBUG level is skipped.

    I am using loglevel v1.4.1 with Node.js 8.2.1 and npm 5.3.0 on macOS 10.12.6.

    opened by asasine 9
  • Add ES6/browserify/vuejs docs to README?

    Add ES6/browserify/vuejs docs to README?

    Since more and more people are starting to use Vuejs it may be an idea to add something to the docs to let them know how to get this library working.

    import * as log from 'loglevel';
    window.log = log.noConflict();
    
    opened by OmgImAlexis 9
  • Adjustment for scoping

    Adjustment for scoping

    The code was wrapped in two anonymous functions, which could cause this to be undefined depending on how the loglevel code was included in a project.

    Only using one anonymous function and having this be at the "top-level" allows the code to be wrapped and invoked with apply like so:

    var myScope = {}:
    (function(){
     // loglevel.js source
     // "this" will equal myScope, since the "this" in loglevel.js is in this scope.
    }).apply(myScope);
    myScope.log.debug("log was defined on myScope");
    

    The code change follows the same pattern as this: https://github.com/marionettejs/backbone.marionette/blob/master/src/build/marionette.core.js

    I'd love to write a unit test but I'd have to adjust the Gruntfile.js and include grunt-preprocess or grunt-rigger, which are code injection/include tools, to generate a test that includes the loglevel.js wrapped in a function invoked with apply. If you want me to do this I will.

    I also hope that my change doesn't affect anything that the undefined argument was doing. https://github.com/pimterry/loglevel/blob/master/lib/loglevel.js#L8

    Thanks, Gianni

    opened by giannif 9
  • Added fix for Private mode in Safari

    Added fix for Private mode in Safari

    Running loglevel in Safari with Private mode (which I often do for testing) creates a DOM 22 Exception. I assume this is because you can't use local storage in Private Mode.

    The added code will cause the exception in the localStorageAvailable check. It's not terribly elegant and seems strange before running the checks for the localStorage object, but it does work.

    opened by smallhadroncollider 8
  • loglevel.trace() does not print message in IE11

    loglevel.trace() does not print message in IE11

    @pimterry Kudos for the awesome library you've created. Thank you 😄 I've got a hopefully small request that I don't think has been addressed before.

    Issue

    On my current project where I'm trying to use loglevel we unfortunately need to support IE11. Ideally it would log everything similarly to Chrome and other modern browsers. Of course, IE11 treats console.trace differently.

    When using loglevel.trace("message") I'm not able to see the message. Instead, it literally prints "console.trace()" followed by the stack information.

    Expected result

    When console.trace won't output a log message, call console.log with the message before console.trace.

    Even if this is only a fix for IE11 I would be satisfied (besides, it's probably the only browser that doesn't handle it correctly).

    opened by CaitlinWeb 7
  • LogLevel output doesn't show when running in a test

    LogLevel output doesn't show when running in a test

    First off, thanks for this module -- been using it for some time now and it really works great!

    However, when I'm testing a module that has a logger, any output logged by the logger is MIA, while logs created via simple console.log appear just fine. I'm using: Loglevel 1.8.0 React TestingLibrary 11.2.6 MacOS BigSur 11.6.8

    Here's my logger component:

    /* eslint-disable func-names */
    import * as log from 'loglevel';
    
    // Log levels are: trace/debug/info/warn/error
    const loggerLevel = process.env.REACT_APP_LOG_LEVEL || 'info';
    
    const originalFactory = log.methodFactory;
    /* eslint-disable-next-line no-import-assign */
    log.methodFactory = function (methodName, logLevel, loggerName) {
      const rawMethod = originalFactory(methodName, logLevel, loggerName);
    
      return function (...args) {
        const messages = [`CDE ${new Date().toISOString()}: `];
        const elements = Object.getOwnPropertyNames(args[0]);
        for (let i = 0; i < elements.length; i++) {
          const elementName = elements[i];
          const elementValue = args[0][elements[i]];
          messages.push(`${elementName}:`);
          switch (typeof elementValue) {
            case 'string':
              messages.push(`'${elementValue}'`);
              break;
            case 'number':
            case 'boolean':
              messages.push(elementValue);
              break;
            case 'undefined':
              messages.push('undefined');
              break;
            case 'null':
              messages.push('null');
              break;
            default:
              messages.push(elementValue);
          }
        }
        rawMethod.apply(undefined, messages); /* eslint-disable-line */
      };
    };
    log.setLevel(loggerLevel); // Be sure to call setLevel method in order to apply plugin
    log.noConflict();
    
    export default log;
    

    Here's some sample code; notice that I'm using logger.enableAll() and confirming that the legLevel is as expected (0) in the component under test. Test module:

    import React from 'react';
    import {MockedProvider} from '@apollo/client/testing';
    
    import DefaultLayoutNoPeriods from './DefaultLayoutNoPeriods';
    import {render, act, getByText} from '../utils/testHelpers';
    import {mockGetClientNames, mockGetPeriods} from '../graphql/mocks';
    import {AppProvider} from '../context/AppContext';
    import EntityRibbon from '../components/EntityRibbon';
    import logger from '../logger';
    
    logger.enableAll();
    
    const TestComponent = () => {
      return <div>Hello World</div>;
    };
    const mocks = [mockGetClientNames, mockGetPeriods, mockGetClientNames];
    describe('DefaultLayoutNoPeriods', () => {
    
      // This test works and displays the expected 'Hello World'
      it('displays "Hello World" with TestComponent', async () => {
        const {container, debug} = await render(
          <AppProvider>
            <MockedProvider mocks={mocks} addtypename={false}>
              <TestComponent />
            </MockedProvider>
          </AppProvider>
        );
    
        await act(async () => {
          await new Promise(resolve => setTimeout(resolve, 0));
        });
        debug();
        const homeElement = await getByText(container, 'Hello World');
        expect(homeElement).toBeInTheDocument();
      });
    
      // This test fails; any logger.debug output is lost, but
      // console.log() output is displayed in the test output
      it('displays "Portfolio" with EntityRibbon', async () => {
        const {container, debug} = await render(
          <AppProvider>
            <MockedProvider mocks={mocks} addtypename={false}>
              <EntityRibbon />
            </MockedProvider>
          </AppProvider>
        );
    
        await act(async () => {
          await new Promise(resolve => setTimeout(resolve, 0));
        });
        debug();
        const homeElement = await getByText(container, 'Portfolio');
        expect(homeElement).toBeInTheDocument();
      });
    });
    

    Here are relevant snippets from the EntityRibbon component:

    import React, {useContext} from 'react';
    import * as R from 'ramda';
    import {Menu} from 'antd';
    import styled from '@emotion/styled';
    
    import logger from '../../logger';
    import {AppContext} from '../../context/AppContext';
    import {client} from '../../graphql/queries/client';
    import {setNewEntity} from '../../utils/utilHelpers';
    import COLORS from '../../theme/colors';
    
    const EntityRibbon = () => {
      const {state, dispatch} = useContext(AppContext);
    
      const entitiesList = state.entitiesList;
      console.log('EntityRibbon/getLevel', logger.getLevel());
      logger.debug({
        method: 'entityRibbon/logger',
        entitiesList: state.entitiesList,
        selectedEntityId: state.selectedEntityId,
        selectedPortfolioId: state.selectedPortfolioId
      });
      console.log({
        method: 'entityRibbon/console.log',
        entitiesList: state.entitiesList,
        selectedEntityId: state.selectedEntityId,
        selectedPortfolioId: state.selectedPortfolioId
      });
    ...
    };
    
    export default EntityRibbon;
    

    And here's the test output showing the problem:

        EntityRibbon/getLevel 0
    
          at EntityRibbon (src/components/EntityRibbon/index.js:61:11)
    
      console.log
        {
          method: 'entityRibbon/console.log',
          entitiesList: [
            {
              entity: 'XXXX',
              displayName: 'XXXX',
              ribbonName: 'XXXX'
            }
          ],
          selectedEntityId: 'XXXX',
          selectedPortfolioId: 'XXXX'
        }
    

    In normal operation, these logs display perfectly fine!

    opened by JESii 9
  • Configurable persistence

    Configurable persistence

    getPersistedLevel is called for each logger. I do not need that. I think the persistence should be configurable same way as methodFactory for plugins - i.e. it should be possible to switch it off, use only cookies, etc.

    opened by xmedeko 4
  • ESM - Angular 10 Tree Shaking Support?

    ESM - Angular 10 Tree Shaking Support?

    WARNING in MyLogging.js depends on 'loglevel'. CommonJS or AMD dependencies can cause optimization bailouts. For more info see: https://angular.io/guide/build#configuring-commonjs-dependencies

    How would I get rid of the warning? This happens during tree shaking and I'd like ascertain that optimization does take place?

    Thank-you

    opened by anh-rivergon 3
  • log.debug should map to console debug in Chrome

    log.debug should map to console debug in Chrome

    Although the documentation for Chrome console specifies that console.debug has a log level of "info", it actually has log level of "verbose".

    With the current loglevel implementation, debug messages are mapped to console.info. This behavior doesn't allow filtering messages in the dev console which are actually "verbose", and hence causing console.debug and log.debug to have different behaviors.

    I suggest that log.debug would map to console debug.

    opened by dorhugiEvinced 6
  • Jasmine:requirejs test is hanging

    Jasmine:requirejs test is hanging

    Hello Team,

    The grunt-contrib-jasmine and grunt-contrib-qunit used as a development dependency of the package are currently supporting phantomjs as a browser testing environment and phantomjs is an unmaintained project so it will be good to replace it with some maintained alternatives like chrome headless.

    Updating the grunt-contrib-qunit and grunt-contrib-jasmine version to latest will provide support for chrome headless for the package and it is good to use the updated dependencies in the package.

    I was checking the package on my local environment with these changes, facing an issue in running jasmine: requirejs test case as it is not proceeding further with chrome headless. To test all the test cases with chromeHeadless browser I have commented the (jasmine:requirejs) test case, as a result, I could see all the other jasmine test case are passing successfully.

    In my view, the issue is with jasmine:requirejs test case only I will be glad if you could share any input regarding this.

    opened by ossdev07 2
  • React Native support

    React Native support

    I don't exactly see why it shouldn't but this module appears not to work with react native,

    Well, log.warn() and log.error() work, but nothing below that level gets output, -even if I call loglevel.setDefaultLevel('trace'); or loglevel.setLevel('trace');

    log.debug() and log.info() still equal noop

    I don't know if it has something to do with the persisting, as react-native had no localstorage..

    opened by vidhill 9
Releases(v1.8.1)
Owner
Tim Perry
Creator of @httptoolkit: Powerful tools to debug, test & build with HTTP(S). Keen open-source contributor, and maintainer of Loglevel, notes, & Mockttp.
Tim Perry
A lightweight structured logging tool for Node.js without any dependencies

structlog A lightweight structured logging tool for Node.js without any dependencies. Example By default this tool will generate logs like the followi

Yakko Majuri 4 May 26, 2022
Console.log with style.

Log Console.log with style Demo Features Safely call log (instead of console.log) in any browser. Use markdown syntax for quick formatting: italic — l

Adam Schwartz 3k Dec 30, 2022
A small logging proxy server for intercepting and logging code completion requests from copilot.

PilotWatch PilotWatch is a small logging proxy server written in node.js for intercepting and logging code completion requests from Github's Copilot.

John Robinson 7 May 8, 2023
Clear console logging for every browser

Console.log wrapper Safe, clear console logging for every browser Log to the console — even legacy browsers without a console. Just pass any data to l

Craig Patik 407 Sep 24, 2022
A lightweight structured logging tool for Node.js without any dependencies

structlog A lightweight structured logging tool for Node.js without any dependencies. Example By default this tool will generate logs like the followi

Yakko Majuri 4 May 26, 2022
Grupprojekt för kurserna 'Javascript med Ramverk' och 'Agil Utveckling'

JavaScript-med-Ramverk-Laboration-3 Grupprojektet för kurserna Javascript med Ramverk och Agil Utveckling. Utvecklingsguide För information om hur utv

Svante Jonsson IT-Högskolan 3 May 18, 2022
Wrap a function with bun-livereload to automatically reload any imports inside the function the next time it is called

bun-livereload Wrap a function with bun-livereload to automatically reload any imports inside the function the next time it is called. import liveRelo

Jarred Sumner 19 Dec 19, 2022
Hemsida för personer i Sverige som kan och vill erbjuda boende till människor på flykt

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

null 4 May 3, 2022
Kurs-repo för kursen Webbserver och Databaser

Webbserver och databaser This repository is meant for CME students to access exercises and codealongs that happen throughout the course. I hope you wi

null 14 Jan 3, 2023
Lightweight WebSocketServer wrapper lib using ws-wrapper to wrap connected WebSockets

ws-server-wrapper Lightweight WebSocketServer wrapper lib using ws-wrapper and ws to wrap connected WebSockets. The only dependency is ws-wrapper itse

Blake Miner 17 May 9, 2022
chain-syncer is a module which allows you to synchronize your app with any ethereum-compatible blockchain/contract state. Fast. Realtime. Reliable.

Chain Syncer Chain Syncer is a JS module which allows you to synchronize your app with any ethereum-compatible blockchain/contract state. Fast. Realti

Miroslaw Shpak 10 Dec 15, 2022
Extends Bootstrap Tooltips and Popovers by adding custom classes. Available for Bootstrap 3 and Bootstrap 4.

Bootstrap Tooltip Custom Class Extends Bootstrap Tooltips and Popovers by adding custom classes. Available for Bootstrap 3 and Bootstrap 4. Define you

Andrei Victor Bulearca 14 Feb 10, 2022
Input a list of Handshake top-level domains, outputs names sorted into 4 arrays: available, registered, reserved, or invalid.

name-check A simple NodeJS package that, given a flat list of top-level domain names, queries the Handshake (HNS) blockchain in order to classify each

Neel Yadav 2 Jan 8, 2022
Console.log with style.

Log Console.log with style Demo Features Safely call log (instead of console.log) in any browser. Use markdown syntax for quick formatting: italic — l

Adam Schwartz 3k Dec 30, 2022
Console log to terminal

Termlog Console log to terminal What it does termlog send the browser console log to your terminal It also comes with a nodejs REPL so you can do some

Quang Ngoc 16 Jan 21, 2022
Another logger in JS. This one offers a console.log-like API and formatting, colored lines and timestamps (or not if desired), all that with 0 dependencies.

hellog Your new logger ! hellog is a general-purpose logging library. It offers a console.log-like API and formatting, extensible type-safety colored

Maxence Lecanu 4 Jan 5, 2022
A vite plugin that deletes console.log in the production environment

vite-plugin-remove-console A vite plugin that deletes console.log in the production environment English | 中文 Install npm install vite-plugin-remove-co

啝裳 49 Dec 22, 2022
Style templates for console.log

sttyl Style templates for console.log. Usage This module is primarily intended for Deno and browsers. import { sttyl } from "https://deno.land/x/sttyl

Wayne Bloss 8 Dec 27, 2022
This is a toy, it is an enhanced version of console.log

uu-console Hi, this is a toy. When you use console.log to print some logs, this can help you do some useless things. What is uu-console Support built-

KK Liu 2 Sep 25, 2022