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

gapminder-log-manager

v0.1.3

Published

Log manager with 3 levels of logging and the possibility to combine different log managers or loggers

Downloads

4

Readme

log-manager

A module for passing diagnostics messages between different parts of the tools page ecosystem

Install it

npm i gapminder-log-manager

API

The base functionality of this module is located in the LogManager class.

So, simple example that illustrates how to create and use LogManager is following

import { LogManager, LogLevel } from 'gapminder-log-manager';

const logger = new LogManager('who am I', LogLevel.ALL);

logger.addOutputTo(console);

logger.log('message 1');
logger.log('message 2', LogLevel.REPLICATION, 'additional data for message 2');

The output is the following:

LogRecord {
  id: 'who am I',
  message: 'message 1',
  extraData: undefined,
  time: '2018-11-01T14:19:16.824Z' }
LogRecord {
  id: 'who am I',
  message: 'message 2',
  extraData: 'additional data for message 2',
  time: '2018-11-01T14:19:16.826Z' }

LogManager class

Constructor of this class takes two parameters:

  1. Logger ID is a string that describes this logger or its module. This parameter is especially actual when we are using logger combination.
  2. Logging Level indicates what kind of messages would be appropriate for the instance of LogManager class. LogLevel enum will be described a little bit later.

Also LogManager class has two methods:

  • addOutputTo is a very important method because without using it the logging system will not be working. It takes only one parameter. It can be any object with mandatory log method that takes a least one parameter as message string. The simplest example of it is Javascript console (see example above). Apart from that gapminder-log-manager contains a special type of logging object StorageLogger. The main purpose of an instance of this class is the ability to collect all log data to the persistent storage (array).

  • log method passes a message to LogManager. The method has 3 parameters:

    1. String message is mandatory
    2. LogLevel of the current message
    3. Extra data

    You can see more details in the example above.

LogLevel

LogLevel in an enum that describes Log Level states. It has the following constant values:

  • ERROR - error level
  • REPLICATION - replication (notice) level
  • DEBUG - debug level. Additional data using is preferable at this level.
  • ALL - all of them

The main feature of LogLevel is an ability to combine them during LogManager instance creation. So if we need to work with, for example, REPLICATION and DEBUG at the same time you can construct your own level via REPLICATION | DEBUG.

Following examples illustrate some important cases regarding LogLevel.

Case 1.

import { LogManager, LogLevel } from 'gapminder-log-manager';

const logger = new LogManager('who am I', LogLevel.ERROR);

logger.addOutputTo(console);

logger.log('message 1', LogLevel.DEBUG);
logger.log('message 2', LogLevel.REPLICATION, 'additional data for message 2');

In this case, an empty output should be given. The reason is simple. There is no any intersection between logger's LogLevel and LogLevels of the messages.

Case 2.

import { LogManager, LogLevel } from 'gapminder-log-manager';

const logger = new LogManager('who am I', LogLevel.DEBUG | LogLevel.REPLICATION);

logger.addOutputTo(console);

logger.log('message 1', LogLevel.DEBUG);
logger.log('message 2', LogLevel.REPLICATION, 'additional data for message 2');
logger.log('message 3', LogLevel.ERROR);

The result should look like

LogRecord {
  id: 'who am I',
  message: 'message 1',
  extraData: undefined,
  time: '2018-11-02T11:44:29.234Z' }
LogRecord {
  id: 'who am I',
  message: 'message 2',
  extraData: 'additional data for message 2',
  time: '2018-11-02T11:44:29.237Z' }

Let's explain what happens. First of all, the logger is able to receive two kinds of messages: DEBUG or (| bitwise operator) REPLICATION. In the first log calls we are sending appropriate messages, but in the third case aren't (ERROR). That's why our logger processed the only first couple of them.

Custom output

All of the previous examples are using Javascript console as output. But as far as previously said, method addOutputTo that should take any object with mandatory log method that takes a least one parameter as message string.

gapminder-log-manager has one useful custom logg object StorageLogger.

You can see its code here.

Apart from log method it has an additional one: getContent. This method returns all log data at the same time by user request.

Let's look at:

import { LogManager, LogLevel, StorageLogger } from 'gapminder-log-manager';

const logger = new LogManager('who am I', LogLevel.ALL);
const storageLogger = new StorageLogger();

logger.addOutputTo(storageLogger);

logger.log('message 1', LogLevel.ALL);
logger.log('message 2', LogLevel.REPLICATION, 'additional data for message 2');
logger.log('message 3', LogLevel.ERROR);

console.log(storageLogger.getContent());

Result is following:

[ { time: '2018-11-02T12:29:56.332Z',
    message: 'message 1',
    id: 'who am I' },
  { time: '2018-11-02T12:29:56.332Z',
    message: 'message 2',
    id: 'who am I',
    extraData: 'additional data for message 2' },
  { time: '2018-11-02T12:29:56.332Z',
    message: 'message 3',
    id: 'who am I' } ]

Pay attention that type of the result is an array and its content is stored in the storageLogger object.

Moreover, we can add more that one output to LogManager:

import { LogManager, LogLevel, StorageLogger } from 'gapminder-log-manager';

const logger = new LogManager('who am I', LogLevel.ALL);
const storageLogger = new StorageLogger();

logger.addOutputTo(console);
logger.addOutputTo(storageLogger);

logger.log('message 1', LogLevel.ALL);
logger.log('message 2', LogLevel.REPLICATION, 'additional data for message 2');
logger.log('message 3', LogLevel.ERROR);

console.log('"storageLogger" content', storageLogger.getContent());
LogRecord {
  id: 'who am I',
  message: 'message 1',
  extraData: undefined,
  time: '2018-11-02T12:38:54.174Z' }
LogRecord {
  id: 'who am I',
  message: 'message 2',
  extraData: 'additional data for message 2',
  time: '2018-11-02T12:38:54.177Z' }
LogRecord {
  id: 'who am I',
  message: 'message 3',
  extraData: undefined,
  time: '2018-11-02T12:38:54.177Z' }
"storageLogger" content [ { time: '2018-11-02T12:38:54.177Z',
    message: 'message 1',
    id: 'who am I' },
  { time: '2018-11-02T12:38:54.177Z',
    message: 'message 2',
    id: 'who am I',
    extraData: 'additional data for message 2' },
  { time: '2018-11-02T12:38:54.177Z',
    message: 'message 3',
    id: 'who am I' } ]

Output before "storageLogger" point is related to Javascript console and rest of the output is related to storageLogger based output.

Output sharing between modules

This feature is more complex and flexible.

Imagine, that we have 3 kinds of an object with own loggers and at the same time we need to combine their output:

import { LogManager, LogLevel } from 'gapminder-log-manager';

class Child {
  logger: LogManager;

  constructor(public readonly externalLogManager) {
    this.logger = new LogManager('Child', LogLevel.ALL);
    this.logger.addOutputTo(externalLogManager);
    this.logger.log('Hi, Parent!');
  }
}

class Parent {
  logger: LogManager;
  child: Child;

  constructor(public readonly externalLogManager) {
    this.logger = new LogManager('Parent', LogLevel.ALL);
    this.logger.addOutputTo(externalLogManager);
    this.logger.log('Hi, Child!');
    this.child = new Child(externalLogManager);
  }
}

class GrandParent {
  logger: LogManager;
  parent: Parent;

  constructor(public readonly externalLogManager) {
    this.logger = new LogManager('GrandParent', LogLevel.ALL);
    this.logger.addOutputTo(externalLogManager);
    this.parent = new Parent(externalLogManager);
  }
}

const dialogs = new LogManager('who am I', LogLevel.ALL);

dialogs.addOutputTo(console);

const grandParent = new GrandParent(dialogs);

grandParent.logger.log('Hello, Parent!');

Output is following in this case:

LogRecord {
  id: 'Parent',
  message: 'Hi, Child!',
  extraData: undefined,
  time: '2018-11-02T13:26:30.726Z' }
LogRecord {
  id: 'Child',
  message: 'Hi, Parent!',
  extraData: undefined,
  time: '2018-11-02T13:26:30.729Z' }
LogRecord {
  id: 'GrandParent',
  message: 'Hello, Parent!',
  extraData: undefined,
  time: '2018-11-02T13:26:30.729Z' }

So, let's explain what happens.

First of all, the instance of GrandParent creates an instance of Parent and Parent instance, in turn, create an instance of Child. Apart from that Parent and Child instances call their log directly. And before they add "parent/external" (this.logger.addOutputTo(externalLogManager);) loggers to own logger. That's why we can see messages from all 3 objects at the result log output.