MCPcopy
hub / github.com/winstonjs/winston

github.com/winstonjs/winston @v3.19.0 sqlite

repository ↗ · DeepWiki ↗ · release v3.19.0 ↗
218 symbols 420 edges 84 files 93 documented · 43%
README

winston

A logger for just about everything.

Version npm npm Downloads build status coverage status

NPM

winston@3

See the Upgrade Guide for more information. Bug reports and PRs welcome!

Looking for winston@2.x documentation?

Please note that the documentation below is for winston@3. [Read the winston@2.x documentation].

Motivation

winston is designed to be a simple and universal logging library with support for multiple transports. A transport is essentially a storage device for your logs. Each winston logger can have multiple transports (see: [Transports]) configured at different levels (see: [Logging levels]). For example, one may want error logs to be stored in a persistent remote location (like a database), but all logs output to the console or a local file.

winston aims to decouple parts of the logging process to make it more flexible and extensible. Attention is given to supporting flexibility in log formatting (see: [Formats]) & levels (see: [Using custom logging levels]), and ensuring those APIs decoupled from the implementation of transport logging (i.e. how the logs are stored / indexed, see: [Adding Custom Transports]) to the API that they exposed to the programmer.

Quick Start

TL;DR? Check out the [quick start example][quick-example] in ./examples/. There are a number of other examples in [./examples/*.js][examples]. Don't see an example you think should be there? Submit a pull request to add it!

Usage

The recommended way to use winston is to create your own logger. The simplest way to do this is using winston.createLogger:

const winston = require('winston');

const logger = winston.createLogger({
  level: 'info',
  format: winston.format.json(),
  defaultMeta: { service: 'user-service' },
  transports: [
    //
    // - Write all logs with importance level of `error` or higher to `error.log`
    //   (i.e., error, fatal, but not other levels)
    //
    new winston.transports.File({ filename: 'error.log', level: 'error' }),
    //
    // - Write all logs with importance level of `info` or higher to `combined.log`
    //   (i.e., fatal, error, warn, and info, but not trace)
    //
    new winston.transports.File({ filename: 'combined.log' }),
  ],
});

//
// If we're not in production then log to the `console` with the format:
// `${info.level}: ${info.message} JSON.stringify({ ...rest }) `
//
if (process.env.NODE_ENV !== 'production') {
  logger.add(new winston.transports.Console({
    format: winston.format.simple(),
  }));
}

You may also log directly via the default logger exposed by require('winston'), but this merely intended to be a convenient shared logger to use throughout your application if you so choose. Note that the default logger doesn't have any transports by default. You need add transports by yourself, and leaving the default logger without any transports may produce a high memory usage issue.

Table of contents

Logging

Logging levels in winston conform to the severity ordering specified by [RFC5424]: severity of all levels is assumed to be numerically ascending from most important to least important.

const levels = {
  error: 0,
  warn: 1,
  info: 2,
  http: 3,
  verbose: 4,
  debug: 5,
  silly: 6
};

Creating your own Logger

You get started by creating a logger using winston.createLogger:

const logger = winston.createLogger({
  transports: [
    new winston.transports.Console(),
    new winston.transports.File({ filename: 'combined.log' })
  ]
});

A logger accepts the following parameters:

Name Default Description
level 'info' Log only if info.level is less than or equal to this level
levels winston.config.npm.levels Levels (and colors) representing log priorities
format winston.format.json Formatting for info messages (see: [Formats])
transports [] (No transports) Set of logging targets for info messages
exitOnError true If false, handled exceptions will not cause process.exit
silent false If true, all logs are suppressed

The levels provided to createLogger will be defined as convenience methods on the logger returned.

//
// Logging
//
logger.log({
  level: 'info',
  message: 'Hello distributed log files!'
});

logger.info('Hello again distributed logs');

You can add or remove transports from the logger once it has been provided to you from winston.createLogger:

const files = new winston.transports.File({ filename: 'combined.log' });
const console = new winston.transports.Console();

logger
  .clear()          // Remove all transports
  .add(console)     // Add console transport
  .add(files)       // Add file transport
  .remove(console); // Remove console transport

You can also wholesale reconfigure a winston.Logger instance using the configure method:

const logger = winston.createLogger({
  level: 'info',
  transports: [
    new winston.transports.Console(),
    new winston.transports.File({ filename: 'combined.log' })
  ]
});

//
// Replaces the previous transports with those in the
// new configuration wholesale.
//
const DailyRotateFile = require('winston-daily-rotate-file');
logger.configure({
  level: 'verbose',
  transports: [
    new DailyRotateFile(opts)
  ]
});

Creating child loggers

You can create child loggers from existing loggers to pass metadata overrides:

const logger = winston.createLogger({
  transports: [
    new winston.transports.Console(),
  ]
});

const childLogger = logger.child({ requestId: '451' });

.child is likely to be bugged if you're also extending the Logger class, due to some implementation details that make this keyword to point to unexpected things. Use with caution.

Streams, objectMode, and info objects

In winston, both Logger and Transport instances are treated as objectMode streams that accept an info object.

The info parameter provided to a given format represents a single log message. The object itself is mutable. Every info must have at least the level and message properties:

const info = {
  level: 'info',                 // Level of the logging message
  message: 'Hey! Log something?' // Descriptive message being logged.
};

Properties besides level and message are considered as "meta". i.e.:

const { level, message, ...meta } = info;

Several of the formats in logform itself add additional properties:

Property Format added by Description
splat splat() String interpolation splat for %d %s-style messages.
timestamp timestamp() timestamp the message was received.
label label() Custom label associated with each message.
ms ms() Number of milliseconds since the previous log message.

As a consumer you may add whatever properties you wish – internal state is maintained by Symbol properties:

  • Symbol.for('level') (READ-ONLY): equal to level property. Is treated as immutable by all code.
  • Symbol.for('message'): complete string message set by "finalizing formats":
  • json
  • logstash
  • printf
  • prettyPrint
  • simple
  • Symbol.for('splat'): additional string interpolation arguments. Used exclusively by splat() format.

These Symbols are stored in another package: triple-beam so that all consumers of logform can have the same Symbol reference. i.e.:

const { LEVEL, MESSAGE, SPLAT } = require('triple-beam');

console.log(LEVEL === Symbol.for('level'));
// true

console.log(MESSAGE === Symbol.for('message'));
// true

console.log(SPLAT === Symbol.for('splat'));
// true

NOTE: any { message } property in a meta object provided will automatically be concatenated to any msg already provided: For example the below will concatenate 'world' onto 'hello':

js logger.log('error', 'hello', { message: 'world' }); logger.info('hello', { message: 'world' });

Formats

Formats in winston can be accessed from winston.format. They are implemented in logform, a separate module from winston. This allows flexibility when writing your own transports in case you wish to include a default format with your transport.

In modern versions of node template strings are very performant and are the recommended way for doing most end-user formatting. If you want to bespoke format your logs, winston.format.printf is for you:

const { createLogger, format, transports } = require('winston');
const { combine, timestamp, label, printf } = format;

const myFormat = printf(({ level, message, label, timestamp }) => {
  return `${timestamp} [${label}] ${level}: ${message}`;
});

const logger = createLogger({
  format: combine(
    label({ label: 'right meow!' }),
    timestamp(),
    myFormat
  ),
  transports: [new transports.Console()]
});

To see what built-in formats are available and learn more about creating your own custom logging formats, see [logform][logform].

Combining formats

Any number of formats may be combined into a single format using format.combine. Since format.combine takes no opts, as a convenience it returns pre-created instance of the combined format.

const { createLogger, format, transports } = require('winston');
const { combine, timestamp, label, prettyPrint } = format;

const logger = createLogger({
  format: combine(
    label({ label: 'right meow!' }),
    timestamp(),
    prettyPrint()
  ),
  transports: [new transports.Console()]
})

logger.log({
  level: 'info',
  message: 'What time is the testing at?'
});
// Outputs:
// { level: 'info',
//   message: 'What time is the testing at?',
//   label: 'right meow!',
//   timestamp: '2017-09-30T03:57:26.875Z' }

String interpolation

The log method provides the string interpolation using [util.format]. It must be enabled using format.splat().

Below is an example that defines a format with string interpolation of messages using format.splat and then serializes the entire info message using format.simple.

const { createLogger, format, transports } = require('winston');
const logger = createLogger({
  format: format.combine(
    format.splat(),
    format.simple()
  ),
  transports: [new transports.Console()]
});

// info: test message my string {}
logger.log('info', 'test message %s', 'my string');

// info: test message 123 {}
logger.log('info', 'test message %d', 123);

// info: test message first second {number: 123}
logger.log('info', 'test message %s, %s', 'first', 'second', { number: 123 });

Filtering info Objects

If you wish to filter out a given info Object completely when logging then simply return a falsey value.

``` js const { createLogger, format, transports } = require('winston');

// Ignore log messages if they have { private: true } const ignorePrivate = format((info, opts) => { if (info.private) { return false; } return info; });

const logger = createLogger({ format: format.combine( ignorePrivate(), format.json() ), transports: [new trans

Extension points exported contracts — how you extend this code

QueryOptions (Interface)
(no doc)
index.d.ts
AbstractConfigSetLevels (Interface)
(no doc)
lib/winston/config/index.d.ts
LogEntry (Interface)
(no doc)
index.d.ts
AbstractConfigSetColors (Interface)
(no doc)
lib/winston/config/index.d.ts
LogMethod (Interface)
(no doc)
index.d.ts
AbstractConfigSet (Interface)
(no doc)
lib/winston/config/index.d.ts
LeveledLogMethod (Interface)
(no doc)
index.d.ts
CliConfigSetLevels (Interface)
(no doc)
lib/winston/config/index.d.ts

Core symbols most depended-on inside this repo

log
called by 43
test/helpers/mocks/legacy-mixed-transport.js
isLevelEnabled
called by 42
lib/winston/logger.js
log
called by 34
examples/custom-transport.js
push
called by 25
lib/winston/transports/file.js
add
called by 18
lib/winston/logger.js
close
called by 16
lib/winston/logger.js
get
called by 14
lib/winston/container.js
handle
called by 13
lib/winston/rejection-handler.js

Shape

Method 109
Function 45
Class 40
Interface 24

Languages

TypeScript100%

Modules by API surface

lib/winston/transports/file.js30 symbols
lib/winston/logger.js29 symbols
index.d.ts15 symbols
lib/winston/rejection-handler.js14 symbols
lib/winston/exception-handler.js14 symbols
lib/winston/config/index.d.ts11 symbols
lib/winston/transports/http.js10 symbols
test/unit/winston/transports/file.test.js9 symbols
lib/winston/transports/index.d.ts9 symbols
lib/winston/container.js9 symbols
lib/winston/transports/console.js5 symbols
test/helpers/mocks/legacy-mixed-transport.js4 symbols

Dependencies from manifests, versioned

@babel/cli7.23.9 · 1×
@babel/core7.24.0 · 1×
@babel/preset-env7.24.0 · 1×
@colors/colors1.6.0 · 1×
@dabh/diagnostics2.0.8 · 1×
@dabh/eslint-config-populist4.4.0 · 1×
@types/node20.11.24 · 1×
abstract-winston-transport0.5.1 · 1×
assume2.2.0 · 1×
async3.2.3 · 1×
cross-spawn-async2.2.5 · 1×
eslint8.57.0 · 1×

Datastores touched

(mysql)Database · 1 repos

For agents

$ claude mcp add winston \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact