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

@ayanaware/logger

v2.3.8

Published

Useful and great looking logging made easy

Downloads

406

Readme

@ayanaware/logger NPM Discord Install size

Useful and great looking logging made easy

What is this?

This is a logging library inspired by the easy use of slf4j.

How does it help?

Besides coloring your output, this logger makes it easy to log where you are logging from. This is done by analyzing an error stack trace when a Logger is created. Using that we can find out the module name and the path of your file in the module. This also works for modules in the node_modules folder (And probably also with yarn pnp or pnpm). In addition the config is global, which makes it easy to control which modules and even single loggers are allowed to log at which levels.

Limitations

  • There is currently no way to change the logging levels (This can be changed if needed)

For library developers

If you are a library developer you should use @ayanaware/logger-api inside your package instead of this package. The @ayanaware/logger-api package is a lot smaller and only contains a bit of code that checks whether this package is installed and attempts to make use of it. Otherwise it will just do nothing. This also has the great side-effect that users can decide themselves whether they want logging or not.

Installation

With NPM

npm i @ayanaware/logger

With Yarn

yarn add @ayanaware/logger

Usage

This module works out of the box so you can start using it and worry about configuring it later.

Let's say your module is called my-module, your JavaScript file is located in the folder src/my/package and your main file is src/index.js:

const Logger = require('@ayanaware/logger');

// Pass no argument here to use the files name (excluding the extension) as logger name
const log = Logger.get('Hello');

class Hello {
    constructor() {
        log.info('Hello World!');
        // Example output: 2018-07-16 18:00:00:000 INFO  [my-module:my.package.Hello]: Hello World!
    }
}

// You can also create a logger using a reference to the class. This will simply use the name of the class passed.
const logOfClass = Logger.get(Hello);

[my-module:my.package.Hello] shows the location where the line was logged from. The part before the colon (my-module) is the module name. The part after the colon (my.package) is the folder path separated by dots (called "package" in Java so this term "package path" is used here). The part behind the last dot (Hello) is the loggers name. If the loggers name is an empty string when creating it, only the package path will be shown. If no argument is passed the file name without the extension will be used as logger name.

Package detection

The package detection finds your modules name and main file by it's package.json file. The shown path is relative to the main files directory. This means the name of every folder above your main file and the folder the main file is located in will never be shown in logs. The name of every folder underneath the one of your main file may be shown logs.

If you want to change the root folder of the relative path shown but not change your main entry, you can use the property awLoggerName in your package.json and set it to something else relative to the directory the package.json is located in.

Restricting specific levels and loggers

Restrictions are made on the transport level so each transport can define what it wants to print out. For example you might want to log everything with your logging server but only shown Info messages and upwards in your console. Restrictions can be set when creating a transport or afterwards. In this example we showcase how you can edit the restrictions on the default transport:

// The transports base level. This will be used if there's nothing specific defined in loggers. (Default: 'INFO')
Logger.getDefaultTransport().setLevel(LogLevel.INFO);

// Specifications for individual modules, packages and loggers.
Logger.getDefaultTransport().setLoggers([
    {
        name: 'helloworld:hello.Hello',
        level: 'DEBUG',
        // Whether the name should match exactly or if just the logger name starting with that name is enough (Optional, Default: false)
        exact: false,
    }
]);

Attaching further information

The uniqueMarker argument is meant to be used to denote multiple instances of one class if needed. It is passed to the logger like this:

log.info('Hello World!', 'Unique');
// Example output: 2018-07-16 18:00:00:000 INFO  [helloworld:hello.Hello/Unique]: Hello World!

The extra argument is meant to be used for custom formatters, custom transports and attachment of further metadata. It can be set globally, per logger and per log line. When a log call is done the extra data is merged together. If there are duplicate keys the value from the log line will be used first, the value from the logger second and the global value last.

Setting it globally:

Logger.setGlobalExtra({
	myGlobalField: true,
});

Setting it per logger:

Logger.get('MyLogger', {
	myLoggerField: true,
});

Setting it per log line:

log.info('message', null, { myField: true });

Formatters

This module has a default formatter that can be customized by options. If that isn't enough you can extend the Formatter class and create your own formatter.

Currently, those are the options you can override in the default formatter:

| Field | Description | |-|-| | dateFormat | Moment.js compatible date format. Default: YYYY-MM-DD HH:mm:ss:SSS | | disableDefaultColors | Whether to use the predefined color map or an empty color map. Default: false | | disableErrorColors | Whether to disable attempting to format errors. This should be enabled when errors would not be colored anyway as it improves performance. Default: false | | colorMap | A map containing colors or functions formatting a string. This map will be merged with the current predefined map. Valid keys are in the enum DefaultFormatterColor. Default: Predefined map |

const { DefaultFormatter, Formatter, DefaultTransport } = require('@ayanaware/logger');

// Override default formatter
Logger.setFormatter(new DefaultFormatter({
    disableDefaultColors: true,
    // ... further options go here
}));

// Create custom formatter
class MyFormatter extends Formatter {
    formatError(meta, error) {
        return error.toString();
    }

    formatMessage(meta, message) {
        return `${meta.level}: ${message}`;
    }
}

// Use formatter with a transport
Logger.addTransport(new ConsoleTransport({
    formatter: new MyFormatter(),
}));

// When using another ConsoleTransport it makes sense to disable the default transport
Logger.disableDefaultTransport();

The meta object has the following properties:

| Field | Description | |-|-| | origin | The instance of the logger that initiated the current logging call | | level | The log level of the message | | uniqueMarker | The optional uniqueMarker used to denote multiple instance | | input | The input message. This can either be a string or an Error | | extra | An optional object of key value pairs with extra data (Can be used for a central logging system for example) |

Transports

Currently the only transport available is the ConsoleTransport, which is also the default. You can however implement your own transport and pass it to the library:

const { Logger, Transport } = require('@ayanaware/logger');

class MyTransport extends Transport {
    print(meta, message) { // The meta passed here is the same as detailed above
        // Print it somewhere...
    }
}

Logger.addTransport(new MyTransport());

// If you want to disable the default transport you can do it like this
Logger.disableDefaultTransport();

Links

GitLab repository

NPM package

License

Refer to the LICENSE file.