npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@cardstack/logger

v0.2.1

Published

Library and application logging utility

Downloads

94

Readme

@cardstack/logger

The logging library used by the Cardstack Hub and official plugins. Per-channel logging level support, graceful co-operation and configuration sharing between multiple loaded instances (even across versions), and first-class test assertion support.

Inspiration (and a little code) taken from tj's debug.

Installation

$ npm install @cardstack/logger

Browser support

We're focused on node.js logging, though we may add browser support in the future.

Log levels

Some log messages are useful more often than others, some are more noisy than others, and some are urgent and always require attention. We add several logging levels to enable effectively listening to or silencing certain channels at runtime.

  • error - A fatal error has occurred. The application won't function without user attention.
  • warn - Something that may be a problem under certain conditions has occurred.
  • info - Information that provides feedback to the user, or is likely to be useful in recorded logs when investigating surprising behavior after the fact.
  • debug - Information likely to be useful during development or debugging.
  • trace - Dense, noisy information only useful when digging deeply into a system.
  • log - A convenience for active development. These messages are always displayed regardless of configuration, and aren't considered by the expectation system.

Logging usage

The main export of @cardstack/logger is a function which creates namespaced loggers. These loggers have a method for each logging level:

let log = require('@cardstack/logger')('my-module:subsystem');

log.log("ok, this file is actually required at least");

log.info('Application starting');
if (typeof GlobalCache === 'undefined') {
  log.warn("The GlobalCache module hasn't been loaded. The application may run slower than expected");
}

try {
  require('dependency');
} catch (e) {
  log.error('Could not load dependency! Please install it');
  process.exit(1);
}

if (loadOptionalModules) {
  log.debug('Loading the optional modules');
} else {
  log.debug('Skipping optional modules');
}

setInterval(function() {
  log.trace('refreshing plugins');
  refreshPlugins();
}, 50);

Application and run-time configuration

You can specify default logging levels for channels in your application's entry point. Try to do this as early as you can, before requiring other modules, to avoid messages being logged before you set the configuration.

When you set a logging level, all messages of that level and higher will be displayed (lowest is trace, and highest is error). You can also set the level to none to suppress all messages.

The default logging level is info.

Even if multiple versions are installed via different dependencies, we take care to co-ordinate and make sure this configuration is applied to all of them.

If multiple patterns match a channel, the last-specified one will apply.

Note - this should only be done in an application. If you're shipping a library to be consumed by others, you should not call this function - you should leave users to decide it at the application level.

// app.js
const logger = require('@cardstack/logger');
const dep = require('dependency');

logger.configure({
  defaultLevel: 'warn',
  logLevels: [
    ['app:*', 'info'], // Our info messages are all pretty useful
    ['dependency', 'error'] // This lib spams warnings that aren't actually important
  ]
});

let log = logger('app:index');
log.info('starting up');

if (dep.shouldRun()) {
  log.debug('running dependency');
  dep.fn();
}

log.info('all done');
$ node app.js
  app:index starting up
  app:index all done

You can then override these at runtime via environment variables:

$ LOG_LEVELS='*=none,app:*=debug,dependency=warn' node app.js
  app:index starting up
  app:index running dependency
  dependency Woah this isn't linux, don't you believe in free software?!
  app:index all done

Test expectations

Error messages and logs are an important part of developer experience, and worth testing. So, we include expectation helpers to assert that certain log messages occur, and that unexpected ones don't. As a bonus, it's sometimes easier to test that a given log message occurs, than to inspect private state.

There exists an expect... method on the logger module for each logging level. It accepts a regex to match against the message, an optional set of options, and a function to execute to trigger the expected logging.

const logger = require('@cardstack/logger');
let log = logger('test');
// simple usage
await logger.expectInfo(/message/, async function() {
  await someAsyncSetup();
  log.trace('ignored');
  log.info('message');
});

// advanced usage
await logger.expectWarn(/whoops/, { count: 2, allowed: ['error']}, someFunctionThatLogsAnError);