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

nomatic-logging

v1.1.0

Published

Seriously awesome logging library built for Node.js

Downloads

19

Readme

nomatic-logging

Greenkeeper badge Semantic Release GitHub release npm Build Status Coverage Status Known Vulnerabilities dependencies Status devDependencies Status License

Overview

Get serious about logging. This library takes the best concepts of winston and bunyan to create a flexible yet elegant logging solution for any Node.js library or application. You decide what to do with generated logs by using the included transports or creating your own, very easily. You can even decide how to manage logs from your project's dependencies (if they are using this library, of course). A log doesn't have to be just a message, either. You can data to the log message or have a message generated for you from the data via templates.

Goals

  • Reliable: It should fail predictably, and with valid cause. Log data is sensitive and important to determining the status of the dependent application. This is done with extensive unit and integration testing along with proper semantic versioning.
  • Flexible: Each dependent package will use this in a different way. Design it in a way that will fit most use cases.
  • Elegant: It should be easy to get started, yet support complex use cases when needed.
  • Fast: Logging is boring, but essential. Do what we need to do, quickly, and get out of the way.

Installation

You can install from npm by doing:

npm install --save nomatic-logging

Basic Usage

To get the default Logger:

const logger = require('nomatic-logging');

...which is equivalent to (if the namespace is not already taken):

const logging = require('nomatic-logging');
const Logger = logging.Logger;
const ConsoleTransport = logging.ConsoleTransport;
const logger = new Logger('root', {
    transports: [
        new ConsoleTransport({
            level: 'info'
        })
    ]
});

Now, logger has a name of root and a way to send logs of level info and above to the console.

Then, to use it:

logger.info('test');
// with data:
logger.info('test', {
    isTest: true
});

You read that right. You can send data with your message. As a matter of fact, you can just send data with your log and have the Logger parse it into a message for you:

logger.template = '{method} {url} {status} {length} {ms}';
logger.info({
    method: 'GET',
    url: '/path/to/resource',
    status: 200,
    length: '1214',
    ms: 22
});

To listen for all entries generated on logger:

logger.on('entry', (entry) => {
    /* `entry` is an object with `namespace`, `message`, `level`,
    * `hostname`, `createdAt`, and optional `data` fields.
    */
    console.log(`[${entry.level}]\t${entry.message}`);
});

To listen for the 'info' log level entries:

logger.on('info', (entry) => {
    console.log(`[INFO]\t${entry.message}`);
});

Because we are using EventEmitter from nomatic-events, you can also use a regex:

logger.on(/(info|debug)/, (entry) => {
    console.log(`[${entry.level}]\t${entry.message}`);
})

You can create your own transport very easily:

const Transport = require('nomatic-logging').Transport;
class DatabaseTransport extends Transport {
    public execute(entry) {
        /// do something here
    }
}

const myTransport = new DatabaseTransport({
    level: 'debug'
});

You can send log entries to a database, a file, a remote server, whatever you want. This is where nomatic-logging becomes very powerful, and not just a complicated replacement for console.log().

You can then subscribe myTransport to a logger:

logger.use(myTransport);

A log entry object looks like this:

interface Entry {
  namespace?: string;
  level: string;
  message: string;
  createdAt: Date;
  hostname: string;
  data?: Object;
}

As you can see, the only two properties that are optional are namespace and data. namespace is optional because it is optional in the Logger class. You can use the Logger class directly, and potentially export it as part of your library or module:

const Logger = logging.Logger;
module.exports.logger = new Logger();

The Logger class uses no transport(s) by default. You can specify one (or more) when instantiating or do:

module.exports.logger.configure({
    transports: [
        logging.transport.console,
        myTransport,
    ] 
});

This will override properties at a top-level basis (i.e. if you specify transports, any other transports specified will no longer be used by the logger).

Anything you can configure via configure, you can pass on instantiation:

const myLogger = new Logger({
    transports: [
        logging.transport.console,
        myTransport,
    ]
});

A logger can also have child loggers:

logger.create('app');

...which have all the same levels and transports of the parent. If you try to create another logger with the same name on this parent, it will throw an exception. When you configure the parent, the parent will push the same configuration all child loggers.

Loggers also have a get method, which will either return a logger or create one if it does not exist:

logger.get('app'); // returns the previously created Logger instance of the same name
logger.get('app2'); // creates then returns a Logger instance with `name` of 'app2'

TypeScript

This library is developed with TypeScript, and as such, includes definitions. However, you do not even need to know what TypeScript is to use this package. The compiled project is included in the npm package.

Testing

You can run tests by doing:

npm test

A summary of code coverage shows up at the end of the output, but if you want the HTML site, do:

npm run coverage

I do strive for 100% code coverage since this is a very small library. I would ask for the same when submitting a PR. If you need help with writing tests, ping me and I will either write them for you (if it's small enough) or give you guidance on how to do so.

Future Plans

  • Make usable in both Node.js and the browser (currently only supported in Node.js)
  • Add more transports (either included in the main project or as plugins), including:
    • HTTP (sending log entries via JSON or text to a remote server)
    • File (with log-rotate capabilities)
    • Node.js streams
  • Improve test cases, remove clutter, etc. to build even more confidence in the project

Contributing / Support

Please note that this software is in the early stages of development, but is in production use in several of my personal projects and university/work endeavors.

Pull requests are absolutely welcome, and issues can be raised for questions or bugs. I do understand the documentation is a little sparse at the moment, and I'm certainly working to expand that very, very soon. If you need help using the library, submit an issue for it and I'll be sure to document it (first in the issue itself, then in the actual documentation).

Please remember that this is something I maintain and build upon in my spare time. If you need paid support for a particular solution, feature, or bug, please feel free to send me a message. Generally speaking, I'm very responsive during the work week.