Skip to content

Latest commit

 

History

History
160 lines (114 loc) · 4.73 KB

README.md

File metadata and controls

160 lines (114 loc) · 4.73 KB

Pinetto

An isomorphic, opinionated logging library that focuses on:

  • Simplicity: zero runtime dependencies, ~500 LoCs
  • Readability: produces plain-text, human-readable output
  • Performance: uses asynchronous logging techniques when possible
  • Child loggers: supports chained child loggers using prefix concatenation
  • Isomorphism: supports browsers and server-side runtimes
  • ESM: ships with separate ESM and CommonJS builds
  • Flexibility: log level can be changed at runtime

Etymology

In many areas this library stands opposite to pino, hence the name.

-etto

forms nouns from nouns, denoting a diminutive

Wikipedia

Usage

Within ES modules

import pinetto from 'pinetto';

Within CommonJS modules

const { default: pinetto } = require('pinetto');

Basic usage

const root = pinetto({ level: 'debug' });
root.info('Hello, %s!', 'World');
// => 2024-09-09T19:05:28.884Z INF Hello, World!

const child = logger.child('[foo]');
child.debug('Hello, %s!', () => 'World');
// => 2024-09-09T19:06:02.643Z INF [foo] Hello, World!

const grandchild = child.child('[bar]');
grandchild.debug('Hello, %s!', 'World');
// => 2024-09-09T19:06:02.643Z INF [foo][bar] Hello, World!

// The log level can be changed at runtime and the change
// propagates to child loggers.
logger.level = 'warn';        
child.info('Hello, world!'); 
// => <prints nothing>

Supported options

Option Description Default value
level Starting log level, one of "trace", "debug", "info", "warn", "error" "info"
writer Log writer function (see below) Depends on the environment
datetime A function that returns a date/time string (see below) datetimeISO

String formatting

printf-style syntax is supported:

const logger = pinetto({ level: 'debug' });

logger.info('Hello, %s!', 'World');

Date/time

The datetime option may be used to customize whether and how each log line will be prefixed with a date/time string:

const logger = pinetto({ 
  level: 'debug',
  datetime: () => `${new Date().getFullYear()} `,
});

logger.info('Hello, %s!', 'World');
// => 2024 INF Hello, World!

Pinetto ships with two datetime functions: datetimeVoid, which returns an empty string, and datetimeISO, which returns an ISO 8601 string (well, technically it's the RFC 3339 string returned by Date#toISOString).

Note that datetime functions must return a string that ends with a space character.

Functions as arguments

If a log argument is provided in the form of a function it will invoked only when the log triggers and its return value will be passed to the formatter.

This helps with reducing the number of expensive serialization operations, such as JSON.stringify(), taking place even when the log level is such that the result of the serialization will never be used:

logger.level = 'warn';
logger.info('Foo %s', () => JSON.serialize({ bar: 42 }));
// JSON.serialize() will never be invoked

Log writers

Pinetto ships with three different writers:

  • ConsoleWriter, which falls back onto console.log() and works pretty much everywhere;

  • ProcessWriter, which falls back onto process.stdout.write() and can only be used in Node.js-like environments;

  • BufferedWriter, which buffers entries and periodically flushes its buffer out using process.stdout.write() (when in Node.js-like environments) or console.log() (everywhere else).

By default, pinetto will use ProcessWriter in Node.js-like environments and ConsoleWriter everywhere else. A custom writer can be set via the respective constructor option:

import pinetto, { BufferedWriter } from 'pinetto';

const logger = pinetto({ level: 'debug', writer: new BufferedWriter() });

License

Pinetto is released under the MIT license.

The following packages have been vendored into pinetto, although slowly diverging from the respective sources: