# Technical Documentation: winstonjs/winston

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/winstonjs/winston)

### Overview (`README.md`)

# winston

A logger for just about everything.

[](https://www.npmjs.com/package/winston)
[](https://npmcharts.com/compare/winston?minimal=true)
[](https://github.com/winstonjs/winston/actions/workflows/ci.yml)
[](https://coveralls.io/github/winstonjs/winston?branch=master)

[](https://nodei.co/npm/winston/)

## winston@3

See the [Upgrade Guide](UPGRADE-3.0.md) 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`:

``` js
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

* [Motivation](#motivation)
* [Quick Start](#quick-start)
* [Usage](#usage)
* [Table of Contents](#table-of-contents)
* [Logging](#logging)
  * [Creating your logger](#creating-your-own-logger)
  * [Streams, `objectMode`, and `info` objects](#streams-objectmode-and-info-objects)
* [Formats]
  * [Combining formats](#combining-formats)
  * [String interpolation](#string-interpolation)
  * [Filtering `info` Objects](#filtering-info-objects)
  * [Creating custom formats](#creating-custom-formats)
* [Logging levels]
  * [Using logging levels](#using-logging-levels)
  * [Using custom logging levels](#using-custom-logging-levels)
* [Transports]
  * [Multiple transports of the same type](#multiple-transports-of-the-same-type)
  * [Adding Custom Transports](#adding-custom-transports)
  * [Common Transport options](#common-transport-options)
* [Exceptions](#exceptions)
  * [Handling Uncaught Exceptions with winston](#handling-uncaught-exceptions-with-winston)
  * [To Exit or Not to Exit](#to-exit-or-not-to-exit)
* [Rejections](#rejections)
  * [Handling Uncaught Promise Rejections with winston](#handling-uncaught-promise-rejections-with-winston)
* [Profiling](#profiling)
* [Streaming Logs](#streaming-logs)
* [Querying Logs](#querying-logs)
* [Further Reading](#further-reading)
  * [Using the default logger](#using-the-default-logger)
  * [Awaiting logs to be written in `winston`](#awaiting-logs-to-be-written-in-winston)
  * [Working with multiple Loggers in `winston`](#working-with-multiple-loggers-in-winston)
  * [Routing Console transport messages to the console instead of stdout and stderr](#routing-console-transport-messages-to-the-console-instead-of-stdout-and-stderr)
* [Installation](#installation)
* [Run Tests](#run-tests)

## 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._

``` js
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`:

``` js
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`](#streams-objectmode-and-info-objects) 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.

``` js
//
// 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`:

``` js
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:

``` js
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:

``` js
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`](https://nodejs.org/api/stream.html#stream_object_mode)
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:

``` js
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.:

``` js
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.:

``` js
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`](https://github.com/winstonjs/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:

``` js
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.

``` js
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`.

``` js
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 transports.Console()]
});

// Outputs: {"level":"error","message":"Public error to share"}
logger.log({
  level: 'error',
  message: 'Public error to share'
});

// Messages with { private: true } will not be written when logged.
logger.log({
  private: true,
  level: 'error',
  message: 'This is super secret - hide it.'
});
```

Use of `format.combine` will respect any falsey values return and stop
evaluation of later formats in the series. For example:

``` js
const { format } = require('winston');
const { combine, timestamp, label } = format;

const willNeverThrow = format.combine(
  format(info => { return false })(), // Ignores everything
  format(info => { throw new Error('Never reached') })()
);
```

### Creating custom formats

Formats are prototypal objects (i.e. class instances) that define a single
method: `transform(info, opts)` and return the mutated `info`:

- `info`: an object representing the log message.
- `opts`: setting specific to the current instance of the format.

They are expected to return one of two things:

- **An `info` Object** representing the modified `info` argument. Object
references need not be preserved if immutability is preferred. All current
built-in formats consider `info` mutable, but [immutablejs] is being
considered for future releases.
- **A falsey value** indicating that the `info` argument should be ignored by the
caller. (See: [Filtering `info` Objects](#filtering-info-objects)) below.

`winston.format` is designed to be as simple as possible. To define a new
format, simply pass it a `transform(info, opts)` function to get a new
`Format`.

The named `Format` returned can be used to create as many copies of the given
`Format` as desired:

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

const volume = format((info, opts) => {
  if (opts.yell) {
    info.message = info.message.toUpperCase();
  } else if (opts.whisper) {
    info.message = info.message.toLowerCase();
  }

  return info;
});

// `volume` is now a function that returns instances of the format.
const scream = volume({ yell: true });
console.dir(scream.transform({
  level: 'info',
  message: `sorry for making you YELL in your head!`
}, scream.options));
// {
//   level: 'info'
//   message: 'SORRY FOR MAKING YOU YELL IN YOUR HEAD!'
// }

// `volume` can be used multiple times to create different formats.
const whisper = volume({ whisper: true });
console.dir(whisper.transform({
  level: 'info',
  message: `WHY ARE THEY MAKING US YELL SO MUCH!`
}, whisper.options));
// {
//   level: 'info'
//   message: 'why are they making us yell so much!'
// }
```

## Logging Levels

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._

Each `level` is given a specific integer priority. The higher the priority the
more important the message is considered to be, and the lower the
corresponding integer priority.  For example, as specified exactly in RFC5424
the `syslog` levels are prioritized from 0 to 7 (highest to lowest).

```js
{
  emerg: 0,
  alert: 1,
  crit: 2,
  error: 3,
  warning: 4,
  notice: 5,
  info: 6,
  debug: 7
}
```

Similarly, `npm` logging levels are prioritized from 0 to 6 (highest to
lowest):

``` js
{
  error: 0,
  warn: 1,
  info: 2,
  http: 3,
  verbose: 4,
  debug: 5,
  silly: 6
}
```

If you do not explicitly define the levels that `winston` should use, the
`npm` levels above will be used.

### Using Logging Levels

Setting the level for your logging message can be accomplished in one of two
ways. You can pass a string representing the logging level to the log() method
or use the level specified methods defined on every winston Logger.

``` js
//
// Any logger instance
//
logger.log('silly', "127.0.0.1 - there's no place like home");
logger.log('debug', "127.0.0.1 - there's no place like home");
logger.log('verbose', "127.0.0.1 - there's no place like home");
logger.log('info', "127.0.0.1 - there's no place like home");
logger.log('warn', "127.0.0.1 - there's no place like home");
logger.log('error', "127.0.0.1 - there's no place like home");
logger.info("127.0.0.1 - there's no place like home");
logger.warn("127.0.0.1 - there's no place like home");
logger.error("127.0.0.1 - there's no place like home");

//
// Default logger
//
winston.log('info', "127.0.0.1 - there's no place like home");
winston.info("127.0.0.1 - there's no place like home");
```

`winston` allows you to define a `level` property on each transport which
specifies the **maximum** level of messages that a transport should log. For
example, using the `syslog` levels you could log only `error` messages to the
console and everything `info` and below to a file (which includes `error`
messages):

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

You may also dynamically change the log level of a transport:

``` js
const transports = {
  console: new winston.transports.Console({ level: 'warn' }),
  file: new winston.transports.File({ filename: 'combined.log', level: 'error' })
};

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

logger.info('Will not be logged in either transport!');
transports.console.level = 'info';
transports.file.level = 'info';
logger.info('Will be logged in both transports!');
```

`winston` supports customizable logging levels, defaulting to npm style
logging levels. Levels must be specified at the time of creating your logger.

### Using Custom Logging Levels

In addition to the predefined `npm`, `syslog`, and `cli` levels available in
`winston`, you can also choose to define your own:

``` js
const myCustomLevels = {
  levels: {
    foo: 0,
    bar: 1,
    baz: 2,
    foobar: 3
  },
  colors: {
    foo: 'blue',
    bar: 'green',
    baz: 'yellow',
    foobar: 'red'
  }
};

const customLevelLogger = winston.createLogger({
  levels: myCustomLevels.levels
});

customLevelLogger.foobar('some foobar level-ed message');
```

Although there is slight repetition in this data structure, it enables simple
encapsulation if you do not want to have colors. If you do wish to have
colors, in addition to passing the levels to the Logger itself, you must make
winston aware of them:

``` js
winston.addColors(myCustomLevels.colors);
```

This enables loggers using the `colorize` formatter to appropriately color and style
the output of custom levels.

Additionally, you can also change background color and font style.
For example,
``` js
baz: 'italic yellow',
foobar: 'bold red cyanBG'
```

Possible options are below.

* Font styles: `bold`, `dim`, `italic`, `underline`, `inverse`, `hidden`,
  `strikethrough`.

* Font foreground colors: `black`, `red`, `green`, `yellow`, `blue`, `magenta`,
  `cyan`, `white`, `gray`, `grey`.

* Background colors: `blackBG`, `redBG`, `greenBG`, `yellowBG`, `blueBG`
  `magentaBG`, `cyanBG`, `whiteBG`

### Colorizing Standard logging levels

To colorize the standard logging level add
```js
winston.format.combine(
  winston.format.colorize(),
  winston.format.simple()
);
```
where `winston.format.simple()` is whatever other formatter you want to use.  The `colorize` formatter must come before any formatters adding text you wish to color.

### Colorizing full log line when json formatting logs

To colorize the full log line with the json formatter you can apply the following

```js
winston.format.combine(
  winston.format.json(),
  winston.format.colorize({ all: true })
);
```

## Transports

There are several [core transports] included in  `winston`, which leverage the
built-in networking and file I/O offered by Node.js core. In addition, there
are [additional transports] written by members of the community.

## Multiple transports of the same type

It is possible to use multiple transports of the same type e.g.
`winston.transports.File` when you construct the transport.

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

If you later want to remove one of these transports you can do so by using the
transport itself. e.g.:

``` js
const combinedLogs = logger.transports.find(transport => {
  return transport.filename === 'combined.log'
});

logger.remove(combinedLogs);
```

## Adding Custom Transports

Adding a custom transport is easy. All you need to do is accept any options
you need, implement a log() method, and consume it with `winston`.

``` js
const Transport = require('winston-transport');
const util = require('util');

//
// Inherit from `winston-transport` so you can take advantage
// of the base functionality and `.exceptions.handle()`.
//
module.exports = class YourCustomTransport extends Transport {
  constructor(opts) {
    super(opts);
    //
    // Consume any custom options here. e.g.:
    // - Connection information for databases
    // - Authentication information for APIs (e.g. loggly, papertrail,
    //   logentries, etc.).
    //
  }

  log(info, callback) {
    setImmediate(() => {
      this.emit('logged', info);
    });

    // Perform the writing to the remote service
    callback();
  }
};
```

## Common Transport options

As every transport inherits from [winston-transport], it's possible to set
a custom format and a custom log level on each transport separately:

``` js
const logger = winston.createLogger({
  transports: [
    new winston.transports.File({
      filename: 'error.log',
      level: 'error',
      format: winston.format.json()
    }),
    new winston.transports.Http({
      level: 'warn',
      format: winston.format.json()
    }),
    new winston.transports.Console({
      level: 'info',
      format: winston.format.combine(
        winston.format.colorize(),
        winston.format.simple()
      )
    })
  ]
});
```

## Exceptions

### Handling Uncaught Exceptions with winston

With `winston`, it is possible to catch and log `uncaughtException` events
from your process. With your own logger instance you can enable this behavior
when it's created or later on in your applications lifecycle:

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

// Enable exception handling when you create your logger.
const logger = createLogger({
  transports: [
    new transports.File({ filename: 'combined.log' })
  ],
  exceptionHandlers: [
    new transports.File({ filename: 'exceptions.log' })
  ]
});

// Or enable it later on by adding a transport or using `.exceptions.handle`
const logger = createLogger({
  transports: [
    new transports.File({ filename: 'combined.log' })
  ]
});

// Call exceptions.handle with a transport to handle exceptions
logger.exceptions.handle(
  new transports.File({ filename: 'exceptions.log' })
);
```

If you want to use this feature with the default logger, simply call
`.exceptions.handle()` with a transport instance.

``` js
//
// You can add a separate exception logger by passing it to `.exceptions.handle`
//
winston.exceptions.handle(
  new winston.transports.File({ filename: 'path/to/exceptions.log' })
);

//
// Alternatively you can set `handleExceptions` to true when adding transports
// to winston.
//
winston.add(new winston.transports.File({
  filename: 'path/to/combined.log',
  handleExceptions: true
}));
```

### To Exit or Not to Exit

By default, winston will exit after logging an uncaughtException. If this is
not the behavior you want, set `exitOnError = false`

``` js
const logger = winston.createLogger({ exitOnError: false });

//
// or, like this:
//
logger.exitOnError = false;
```

When working with custom logger instances, you can pass in separate transports
to the `exceptionHandlers` property or set `handleExceptions` on any
transport.

##### Example 1

``` js
const logger = winston.createLogger({
  transports: [
    new winston.transports.File({ filename: 'path/to/combined.log' })
  ],
  exceptionHandlers: [
    new winston.transports.File({ filename: 'path/to/exceptions.log' })
  ]
});
```

##### Example 2

``` js
const logger = winston.createLogger({
  transports: [
    new winston.transports.Console({
      handleExceptions: true
    })
  ],
  exitOnError: false
});
```

The `exitOnError` option can also be a function to prevent exit on only
certain types of errors:

``` js
function ignoreEpipe(err) {
  return err.code !== 'EPIPE';
}

const logger = winston.createLogger({ exitOnError: ignoreEpipe });

//
// or, like this:
//
logger.exitOnError = ignoreEpipe;
```

## Rejections

### Handling Uncaught Promise Rejections with winston

With `winston`, it is possible to catch and log `unhandledRejection` events
from your process. With your own logger instance you can enable this behavior
when it's created or later on in your applications lifecycle:

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

// Enable rejection handling when you create your logger.
const logger = createLogger({
  transports: [
    new transports.File({ filename: 'combined.log' })
  ],
  rejectionHandlers: [
    new transports.File({ filename: 'rejections.log' })
  ]
});

// Or enable it later on by adding a transport or using `.rejections.handle`
const logger = createLogger({
  transports: [
    new transports.File({ filename: 'combined.log' })
  ]
});

// Call rejections.handle with a transport to handle rejections
logger.rejections.handle(
  new transports.File({ filename: 'rejections.log' })
);
```

If you want to use this feature with the default logger, simply call
`.rejections.handle()` with a transport instance.

``` js
//
// You can add a separate rejection logger by passing it to `.rejections.handle`
//
winston.rejections.handle(
  new winston.transports.File({ filename: 'path/to/rejections.log' })
);

//
// Alternatively you can set `handleRejections` to true when adding transports
// to winston.
//
winston.add(new winston.transports.File({
  filename: 'path/to/combined.log',
  handleRejections: true
}));
```

## Profiling

In addition to logging messages and metadata, `winston` also has a simple
profiling mechanism implemented for any logger:

``` js
//
// Start profile of 'test'
//
logger.profile('test');

setTimeout(function () {
  //
  // Stop profile of 'test'. Logging will now take place:
  //   '17 Jan 21:00:00 - info: test duration=1000ms'
  //
  logger.profile('test');
}, 1000);
```

Also you can start a timer and keep a reference that you can call `.done()`
on:

``` js
 // Returns an object corresponding to a specific timing. When done
 // is called the timer will finish and log the duration. e.g.:
 //
 const profiler = logger.startTimer();
 setTimeout(function () {
   profiler.done({ message: 'Logging message' });
 }, 1000);
```

All profile messages are set to 'info' level by default, and both message and
metadata are optional.  For individual profile messages, you can override the default log level by supplying a metadata object with a `level` property:

```js
logger.profile('test', { level: 'debug' });
```

## Querying Logs

`winston` supports querying of logs with Loggly-like options. [See Loggly
Search API](https://www.loggly.com/docs/api-retrieving-data/). Specifically:
`File`, `Couchdb`, `Redis`, `Loggly`, `Nssocket`, and `Http`.

``` js
const options = {
  from: new Date() - (24 * 60 * 60 * 1000),
  until: new Date(),
  limit: 10,
  start: 0,
  order: 'desc',
  fields: ['message']
};

//
// Find items logged between today and yesterday.
//
logger.query(options, function (err, results) {
  if (err) {
    /* TODO: handle me */
    throw err;
  }

  console.log(results);
});
```

## Streaming Logs
Streaming allows you to stream your logs back from your chosen transport.

``` js
//
// Start at the end.
//
winston.stream({ start: -1 }).on('log', function(log) {
  console.log(log);
});
```

## Further Reading

### Using the Default Logger

The default logger is accessible through the `winston` module directly. Any
method that you could call on an instance of a logger is available on the
default logger:

``` js
const winston = require('winston');

winston.log('info', 'Hello distributed log files!');
winston.info('Hello again distributed logs');

winston.level = 'debug';
winston.log('debug', 'Now my debug messages are written to console!');
```

By default, no transports are set on the default logger. You must
add or remove transports via the `add()` and `remove()` methods:

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

winston.add(console);
winston.add(files);
winston.remove(console);
```

Or do it with one call to configure():

``` js
winston.configure({
  transports: [
    new winston.transports.File({ filename: 'somefile.log' })
  ]
});
```

For more documentation about working with each individual transport supported
by `winston` see the [`winston` Transports](docs/transports.md) document.

### Awaiting logs to be written in `winston`

Often it is useful to wait for your logs to be written before exiting the
process. Each instance of `winston.Logger` is also a [Node.js stream](https://nodejs.org/api/stream.html). A
`finish` event will be raised when all logs have flushed to all transports
after the stream has been ended.

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

logger.on('finish', function (info) {
  // All `info` log messages has now been logged
});

logger.info('CHILL WINSTON!', { seriously: true });
logger.end();
```

It is also worth mentioning that the logger also emits an 'error' event
if an error occurs within the logger itself which
you should handle or suppress if you don't want unhandled exceptions:

``` js
//
// Handle errors originating in the logger itself
//
logger.on('error', function (err) { /* Do Something */ });
```

### Working with multiple Loggers in winston

Often in larger, more complex, applications it is necessary to have multiple
logger instances with different settings. Each logger is responsible for a
different feature area (or category). This is exposed in `winston` in two
ways: through `winston.loggers` and instances of `winston.Container`. In fact,
`winston.loggers` is just a predefined instance of `winston.Container`:

``` js
const winston = require('winston');
const { format } = winston;
const { combine, label, json } = format;

//
// Configure the logger for `category1`
//
winston.loggers.add('category1', {
  format: combine(
    label({ label: 'category one' }),
    json()
  ),
  transports: [
    new winston.transports.Console({ level: 'silly' }),
    new winston.transports.File({ filename: 'somefile.log' })
  ]
});

//
// Configure the logger for `category2`
//
winston.loggers.add('category2', {
  format: combine(
    label({ label: 'category two' }),
    json()
  ),
  transports: [
    new winston.transports.Http({ host: 'localhost', port:8080 })
  ]
});
```

Now that your loggers are setup, you can require winston _in any file in your
application_ and access these pre-configured loggers:

``` js
const winston = require('winston');

//
// Grab your preconfigured loggers
//
const category1 = winston.loggers.get('category1');
const category2 = winston.loggers.get('category2');

category1.info('logging to file and console transports');
category2.info('logging to http transport');
```

If you prefer to manage the `Container` yourself, you can simply instantiate one:

``` js
const winston = require('winston');
const { format } = winston;
const { combine, label, json } = format;

const container = new winston.Container();

container.add('category1', {
  format: combine(
    label({ label: 'category one' }),
    json()
  ),
  transports: [
    new winston.transports.Console({ level: 'silly' }),
    new winston.transports.File({ filename: 'somefile.log' })
  ]
});

const category1 = container.get('category1');
category1.info('logging to file and console transports');
```

### Routing Console transport messages to the console instead of stdout and stderr

By default the `winston.transports.Console` transport sends messages to `stdout` and `stderr`. This
is fine in most situations; however, there are some cases where this isn't desirable, including:

- Debugging using VSCode and attaching to, rather than launching, a Node.js process
- Writing JSON format messages in AWS Lambda
- Logging during Jest tests with the `--silent` option

To make the transport log use `console.log()`, `console.warn()` and `console.error()`
instead, set the `forceConsole` option to `true`:

```js
const logger = winston.createLogger({
  level: 'info',
  transports: [new winston.transports.Console({ forceConsole: true })]
});
```

## Installation

``` bash
npm install winston
```

``` bash
yarn add winston
```

## Run Tests

``` bash
npm test # Runs all tests
npm run test:unit # Runs all Unit tests with coverage
npm run test:integration # Runs all integration tests
npm run test:typescript # Runs tests verifying Typescript types
```

All of the winston tests are written with [jest]. Assertions use a mix of [assume] and the built-in jest assertion library.

#### Author: [Charlie Robbins]
#### Contributors: [Jarrett Cruger], [David Hyde], [Chris Alderson], [Jonathon Terry]

[Transports]: #transports
[Logging levels]: #logging-levels
[Formats]: #formats
[Using custom logging levels]: #using-custom-logging-levels
[Adding Custom Transports]: #adding-custom-transports
[core transports]: docs/transports.md#winston-core
[additional transports]: docs/transports.md#additional-transports

[RFC5424]: https://tools.ietf.org/html/rfc5424
[util.format]: https://nodejs.org/dist/latest/docs/api/util.html#util_util_format_format_args
[assume]: https://github.com/bigpipe/assume
[logform]: https://github.com/winstonjs/logform#readme
[winston-transport]: https://github.com/winstonjs/winston-transport
[jest]: https://jestjs.io/

[Read the `winston@2.x` documentation]: https://github.com/winstonjs/winston/tree/2.x

[quick-example]: https://github.com/winstonjs/winston/blob/master/examples/quick-start.js
[examples]: https://github.com/winstonjs/winston/tree/master/examples

[Charlie Robbins]: http://github.com/indexzero
[Jarrett Cruger]: https://github.com/jcrugzz
[David Hyde]: https://github.com/dabh
[Chris Alderson]: https://github.com/chrisalderson
[Jonathon Terry]: https://github.com/maverick1872

---

### Publishing (`docs/publishing.md`)

The release process here mostly follows along with the [vbump script](https://github.com/indexzero/vbump) that @indexzero wrote several years ago, but the main steps for a release are as follows:

1. Complete merging in any PRs that should be part of the release.
1. On the [Releases tab](https://github.com/winstonjs/winston/releases) in the GitHub UI, click 'Draft a new release' in the upper right corner.
1. Under the 'Choose a tag' dropdown, type the name of the new version starting with a v (e.g. `v3.7.0`) and don't forget to click the 'Create new tag on publish' option below (this step is annoyingly easy to miss):

1. Paste the same version number, with or without the v (with is probably better) in the release title box.
1. Click 'Generate release notes' and cut & paste the draft contents into the changelog.
1. Paste the contents of the changelog for this release in the 'Describe this release' box.
1. Check to make sure you've caught everything (including direct commits) using GitHub's compare tool ([example here](https://github.com/winstonjs/winston/compare/v3.6.0...master)).
1. Update the changelog. It's nice to thank the contributors here.  It's nice to organize this by which changes would merit which level of semver bump, and especially call out any breaking changes (major-version-number) concisely at the start.
1. **Update the version number in package.json and package-lock.json**, bumping as appropriate for [semver](https://semver.org/) based on the most significant position change trigger from the changelog you just wrote/reviewed.  Do not miss this step! Also note there are two places in package-lock where this gets updated: at the top level and under the empty-string entry of packages.
1. Update the tag and version number on the Draft a New Release page, with the same number (which might've changed while drafting changelog notes).
1. Make sure your local master branch is up to date.
1. Make sure all the lint checks and tests pass, beyond what the CI might've told you.
1. Paste the contents of the changelog for this release in the 'Describe this release' box on the Draft a Release page.
1. Click "Publish release."
1. Back on the command line, `npm publish` and complete npm 2FA as needed.
1. Update the distribution tags, for example: `npm dist-tag add winston@3.7.0 3.x-latest`.
1. Verify the distribution tags look correct under the 'Versions' tab at https://www.npmjs.com/package/winston or with `npm dist-tag ls`.
1. Keep a closer-than-usual eye on issues in the hours and days that follow, prepared to quickly revert/address anything that might be associated with that release.

A more professional version of this would probably use a release branch off master to make sure no other maintainers merge a PR into master between the loading of a compare view for changelog preparation and completion of the process, but we're such a small team that the extra steps are probably not needed. After release, you can also verify with the compare view between the new and prior release tags to see when the latest change was and verify it was before you started the process.

---

### Releases (`docs/releases.md`)

# Past Release Roadmaps

Below is the list of items that made up the roadmap for past releases. 

- [Version 3.0.0](#version-300)

## Legend

- [ ] Unstarted work.
- [x] Finished work.
- [-] Partially finished or in-progress work. 

## Version `3.0.0`

### Show stoppers
- [x] `silent` support.
- [x] Finish `3.0.0` upgrade guide: https://github.com/winstonjs/winston/blob/master/UPGRADE-3.0.md
- [x] Triage all open issues since October 2017

### High priority issues (non-blocking)
- [x] [#1144]: this is _the_ purpose of `winston`. If we cannot log at high-volume we cannot ship out of RC. There was [test coverage for this][stress-test] that should be failing, but isnt. _(Fixed by #1291)._
- [x] Error handling within formats [#1261]
- [x] Update `docs/transports.md`.
- [Type definitions for TypeScript](https://github.com/winstonjs/winston/issues/1096)
  - [x] Supporting libraries: `winston-transport`, `logform`
  - [x] `winston` itself 

### Core logging
- [x] Make `Logger.prototype.level` and `Transport.level` play nice(r) together.
- [x] Remove `new winston.Logger` in favor of `winston.createLogger`.
- [x] Finish implementation for `TransportStream` and `LegacyTransportStream`. 
- [x] Move `TransportStream` and `LegacyTransportStream` into `winston-transport`.
- [x] Move `winston/config.js` to `winston/config/index.js`
- [x] **DEPRECATE** `winston.clone`
- [x] Add convenience methods from `winston-transport`
- [-] Replace all `vows`-based tests.
  - [x] `test/*-test.js`
  - [x] `test/formats/*-test.js` 
  - [-] `test/transports/*-test.js` 
- [x] Move `winston.config` into `triple-beam` around a base `Levels` class.
  _(Fixed in `triple-beam@1.2.0`)_
- [x] Update to the latest `npm` levels (e.g. including `http`).
- [ ] Code coverage tests above 80% for `winston` _(currently `~72%`)_.
- [x] Code coverage tests above 90% for `winston-transport`.
- [x] Code coverage tests above 90% for `logform`
- [-] Core scenarios covered in `abstract-winston-transport`.
- [x] Code coverage tests above 60% for `winston-compat`.

### Transports
- [x] Implement `stream.Writable.writev` in `TransportStream`.
- [x] Refactor all built-in transports to be TransportStream instances.
  - [x] Console
  - [x] File
  - [x] Http
  - [x] Steam

### Formats
- [x] `winston.format.colorize()` format.
- [x] `winston.format.prettyPrint()` format.
- [x] `winston.format.uncolorize()` format.
- [x] `winston.format.logstash()` format.
- [x] `winston.format.cli()`
- [x] String interpolation _(i.e. splat)_ via format
- [x] Use of different formats across multiple Transports. e.g.:
   - Colors on `Console`
   - Not on `File`
- [x] Mutable levels on `info` objects 
   – Use `triple-beam` and `Symbol.for('level')`.
   - Needed for `winston.formats.colorize()`. 
- [x] Quieter finalized output using `Symbol.for('message')` 
- [x] Filtering messages completely in a format.
- [x] `winston.format.padLevels()` format.
- [x] `humanReadableUnhandledException` should be the default

### Communications / Compatibility
- [x] Add friendly(ish) deprecation notices for common changes.
- [x] Create `winston-compat` to help with backwards compatibility for transport authors.  
- [x] Update the `README.md` in `winston`.
- [x] `README.md` for `winston-transport`.
- [x] `README.md` for `logform`.
- [x] Migrate all `examples/*.js` to the new API.

### Querying, Streaming, Uncaught Exceptions
- [x] Uncaught Exceptions

### Other Miscellaneous API changes
- [x] Move `LogStream` back to `Logger`.
- [x] Add LogStream.prototype.configure from `winston@2.0.0`
- [x] `winston.Container` instances no longer add any transports by default.
- [x] Strip wrapping `(` `)` from all occurances of `new winston.transports.*)`

### Benchmarking
- [x] Benchmark against `winston@1.0.0` in `logmark`.
- [x] Benchmark against `winston@2.0.0` in `logmark`.
- [x] Benchmark JSON format against `bunyan` in `logmark`.
- [x] Benchmark against `pino` in `logmark`.
- [x] Submit PR for all `pino` benchmarks.

---

### Transports (`docs/transports.md`)

# Winston Transports

In `winston` a transport is essentially a storage device for your logs. Each
instance of a winston logger can have multiple transports configured at
different 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.

There are several [core transports](#built-in-to-winston) included in `winston`
that leverage the built-in networking and file I/O offered by Node.js core. In
addition, there are transports which are [actively supported by winston
contributors](#maintained-by-winston-contributors). And last (but not least)
there are additional transports written by
[members of the community](#community-transports).

> Additionally there are transports previously maintained by winston
> contributors that are [looking for maintainers](#looking-for-maintainers).

* **[Built-in to winston](#built-in-to-winston)**
  * [Console](#console-transport)
  * [File](#file-transport)
  * [Http](#http-transport)
  * [Stream](#stream-transport)

* **[Maintained by winston contributors](#maintained-by-winston-contributors)**
  * [DailyRotateFile](#dailyrotatefile-transport)
  * [MongoDB](#mongodb-transport)
  * [Syslog](#syslog-transport)

* **[Community Transports](#community-transports)**
  * [Airbrake](#airbrake-transport)
  * [Amazon CloudWatch](#amazon-cloudwatch-transport)
  * [Amazon DynamoDB](#amazon-dynamodb-transport)
  * [Amazon Kinesis Firehose](#amazon-kinesis-firehose-transport)
  * [Amazon SNS](#amazon-sns-simple-notification-system-transport)
  * [Azure Table](#azure-table)
  * [Cassandra](#cassandra-transport)
  * [Cisco Spark](#cisco-spark-transport)
  * [Cloudant](#cloudant)
  * [Datadog](#datadog-transport)
  * [Elasticsearch](#elasticsearch-transport)
  * [FastFileRotate](#fastfilerotate-transport)
  * [Google BigQuery](#google-bigquery)
  * [Google Stackdriver Logging](#google-stackdriver-transport)
  * [Graylog2](#graylog2-transport)
  * [Humio](#humio-transport)
  * [LogDNA](#logdna-transport)
  * [Logsene](#logsene-transport) (including Log-Alerts and Anomaly Detection)
  * [Logz.io](#logzio-transport)
  * [Mail](#mail-transport)
  * [MySQL](#mysql-transport)
  * [New Relic](#new-relic-agent-transport)
  * [Papertrail](#papertrail-transport)
  * [Parseable](#parseable)
  * [PostgresQL](#postgresql-transport)
  * [Pusher](#pusher-transport)
  * [Sentry](#sentry-transport)
  * [Seq](#seq-transport)
  * [SimpleDB](#simpledb-transport)
  * [Slack](#slack-transport)
  * [SQLite3](#sqlite3-transport)
  * [SSE with KOA 2](#sse-transport-with-koa-2)
  * [Sumo Logic](#sumo-logic-transport)
  * [VS Code extension](#vs-code-extension)
  * [Worker Thread based async Console transport](#worker-thread-based-async-console-transport)
  * [Winlog2 Transport](#winlog2-transport)

* **[Looking for maintainers](#looking-for-maintainers)**
  * [CouchDB](#couchdb-transport)
  * [Loggly](#loggly-transport)
  * [Redis](#redis-transport)
  * [Riak](#riak-transport)

## Built-in to winston

There are several core transports included in `winston`, which leverage the built-in networking and file I/O offered by Node.js core.

* [Console](#console-transport)
* [File](#file-transport)
* [Http](#http-transport)
* [Stream](#stream-transport)

### Console Transport

``` js
logger.add(new winston.transports.Console(options));
```

The Console transport takes a few simple options:

* __level:__ Level of messages that this transport should log (default: level set on parent logger).
* __silent:__ Boolean flag indicating whether to suppress output (default false).
* __eol:__ string indicating the end-of-line characters to use (default `os.EOL`)
* __stderrLevels__ Array of strings containing the levels to log to stderr instead of stdout, for example `['error', 'debug', 'info']`. (default `[]`)
* __consoleWarnLevels__ Array of strings containing the levels to log using console.warn or to stderr (in Node.js) instead of stdout, for example `['warn', 'debug']`. (default `[]`)

### File Transport
``` js
logger.add(new winston.transports.File(options));
```

The File transport supports a variety of file writing options. If you are
looking for daily log rotation see [DailyRotateFile](#dailyrotatefile-transport)

* __level:__ Level of messages that this transport should log (default: level set on parent logger).
* __silent:__ Boolean flag indicating whether to suppress output (default false).
* __eol:__ Line-ending character to use. (default: `os.EOL`).
* __lazy:__ If true, log files will be created on demand, not at the initialization time.
* __filename:__ The filename of the logfile to write output to.
* __maxsize:__ Max size in bytes of the logfile, if the size is exceeded then a new file is created, a counter will become a suffix of the log file.
* __maxFiles:__ Limit the number of files created when the size of the logfile is exceeded.
* __tailable:__ If true, log files will be rolled based on maxsize and maxfiles, but in ascending order. The __filename__ will always have the most recent log lines. The larger the appended number, the older the log file.  This option requires __maxFiles__ to be set, or it will be ignored.
* __maxRetries:__ The number of stream creation retry attempts before entering a failed state. In a failed state the transport stays active but performs a NOOP on it's log function. (default 2)
* __zippedArchive:__ If true, all log files but the current one will be zipped.
* __options:__ options passed to `fs.createWriteStream` (default `{flags: 'a'}`).
* __stream:__ **DEPRECATED** The WriteableStream to write output to.

### Http Transport

``` js
logger.add(new winston.transports.Http(options));
```

The `Http` transport is a generic way to log, query, and stream logs from an arbitrary Http endpoint, preferably [winstond][1]. It takes options that are passed to the node.js `http` or `https` request:

* __host:__ (Default: **localhost**) Remote host of the HTTP logging endpoint
* __port:__ (Default: **80 or 443**) Remote port of the HTTP logging endpoint
* __path:__ (Default: **/**) Remote URI of the HTTP logging endpoint
* __auth:__ (Default: **None**) An object representing the `username` and `password` for HTTP Basic Auth
* __ssl:__ (Default: **false**) Value indicating if we should use HTTPS
* __batch:__ (Default: **false**) Value indicating if batch mode should be used. A batch of logs to send through the HTTP request when one of the batch options is reached: number of elements, or timeout
* __batchInterval:__ (Default: **5000 ms**) Value indicating the number of milliseconds to wait before sending the HTTP request
* __batchCount:__ (Default: **10**) Value indicating the number of logs to cumulate before sending the HTTP request

### Stream Transport

``` js
logger.add(new winston.transports.Stream({
  stream: fs.createWriteStream('/dev/null')
  /* other options */
}));
```

The Stream transport takes a few simple options:

* __stream:__ any Node.js stream. If an `objectMode` stream is provided then
  the entire `info` object will be written. Otherwise `info[MESSAGE]` will be
  written.
* __level:__ Level of messages that this transport should log (default: level set on parent logger).
* __silent:__ Boolean flag indicating whether to suppress output (default false).
* __eol:__ Line-ending character to use. (default: `os.EOL`).

## Maintained by winston contributors

Starting with `winston@0.3.0` an effort was made to remove any transport which added additional dependencies to `winston`. At the time there were several transports already in `winston` which will have slowly waned in usage. The
following transports are **actively maintained by members of the winston Github
organization.**

* [MongoDB](#mongodb-transport)
* [DailyRotateFile](#dailyrotatefile-transport)
* [Syslog](#syslog-transport)

### MongoDB Transport

As of `winston@0.3.0` the MongoDB transport has been broken out into a new module: [winston-mongodb][14]. Using it is just as easy:

``` js
const winston = require('winston');

/**
 * Requiring `winston-mongodb` will expose
 * `winston.transports.MongoDB`
 */
require('winston-mongodb');

logger.add(new winston.transports.MongoDB(options));
```

The MongoDB transport takes the following options. 'db' is required:

* __level:__ Level of messages that this transport should log, defaults to
'info'.
* __silent:__ Boolean flag indicating whether to suppress output, defaults to
false.
* __db:__ MongoDB connection uri, pre-connected db object or promise object
which will be resolved with pre-connected db object.
* __options:__ MongoDB connection parameters (optional, defaults to
`{poolSize: 2, autoReconnect: true}`).
* __collection__: The name of the collection you want to store log messages in,
defaults to 'log'.
* __storeHost:__ Boolean indicating if you want to store machine hostname in
logs entry, if set to true it populates MongoDB entry with 'hostname' field,
which stores os.hostname() value.
* __username:__ The username to use when logging into MongoDB.
* __password:__ The password to use when logging into MongoDB. If you don't
supply a username and password it will not use MongoDB authentication.
* __label:__ Label stored with entry object if defined.
* __name:__ Transport instance identifier. Useful if you need to create multiple
MongoDB transports.
* __capped:__ In case this property is true, winston-mongodb will try to create
new log collection as capped, defaults to false.
* __cappedSize:__ Size of logs capped collection in bytes, defaults to 10000000.
* __cappedMax:__ Size of logs capped collection in number of documents.
* __tryReconnect:__ Will try to reconnect to the database in case of fail during
initialization. Works only if __db__ is a string. Defaults to false.
* __expireAfterSeconds:__ Seconds before the entry is removed. Works only if __capped__ is not set.

*Metadata:* Logged as a native JSON object in 'meta' property.

*Logging unhandled exceptions:* For logging unhandled exceptions specify
winston-mongodb as `handleExceptions` logger according to winston documentation.

### DailyRotateFile Transport

See [winston-dailyrotatefile](https://github.com/winstonjs/winston-daily-rotate-file).

### Syslog Transport

See [winston-syslog](https://github.com/winstonjs/winston-syslog).

## Community Transports

The community has truly embraced `winston`; there are over **23** winston transports and over half of them are maintained by authors external to the winston core team. If you want to check them all out, just search `npm`:

``` bash
  $ npm search winston
```

**If you have an issue using one of these modules you should contact the module author directly**

### Airbrake Transport

[winston-airbrake2][22] is a transport for winston that sends your logs to Airbrake.io.

``` js
const winston = require('winston');
const { Airbrake } = require('winston-airbrake2');
logger.add(new Airbrake(options));
```

The Airbrake transport utilises the node-airbrake module to send logs to the Airbrake.io API. You can set the following options:

* __apiKey__: The project API Key. (required, default: null)
* __name__: Transport name. (optional, default: 'airbrake')
* __level__: The level of message that will be sent to Airbrake (optional, default: 'error')
* __host__: The information that is displayed within the URL of the Airbrake interface. (optional, default: 'http://' + os.hostname())
* __env__: The environment will dictate what happens with your message. If your environment is currently one of the 'developmentEnvironments', the error will not be sent to Airbrake. (optional, default: process.env.NODE_ENV)
* __timeout__: The maximum time allowed to send to Airbrake in milliseconds. (optional, default: 30000)
* __developmentEnvironments__: The environments that will **not** send errors to Airbrake. (optional, default: ['development', 'test'])
* __projectRoot__: Extra string sent to Airbrake. (optional, default: null)
* __appVersion__: Extra string or number sent to Airbrake. (optional, default: null)
* __consoleLogError__: Toggle the logging of errors to console when the current environment is in the developmentEnvironments array. (optional, default: false)

### Amazon CloudWatch Transport

The [winston-aws-cloudwatch][25] transport relays your log messages to Amazon CloudWatch.

```js
const winston = require('winston');
const AwsCloudWatch = require('winston-aws-cloudwatch');

logger.add(new AwsCloudWatch(options));
```

Options:

* __logGroupName:__ The name of the CloudWatch log group to which to log. *[required]*
* __logStreamName:__ The name of the CloudWatch log stream to which to log. *[required]*
* __awsConfig:__ An object containing your `accessKeyId`, `secretAccessKey`, `region`, etc.

~~Alternatively, you may be interested in [winston-cloudwatch][26].~~
`lazywithclass/winston-cloudwatch` is no longer maintained. Use
[@initd-sg/winston-cloudwatch](https://github.com/initdsg/winston-cloudwatch)

### Amazon DynamoDB Transport
The [winston-dynamodb][36] transport uses Amazon's DynamoDB as a sink for log messages. You can take advantage of the various authentication methods supports by Amazon's aws-sdk module. See [Configuring the SDK in Node.js](http://docs.aws.amazon.com/AWSJavaScriptSDK/guide/node-configuring.html).

``` js
const winston = require('winston');
const { DynamoDB } = require('winston-dynamodb');

logger.add(new DynamoDB(options));
```

Options:
* __accessKeyId:__ your AWS access key id
* __secretAccessKey:__ your AWS secret access key
* __region:__ the region where the domain is hosted
* __useEnvironment:__ use process.env values for AWS access, secret, & region.
* __tableName:__ DynamoDB table name

To Configure using environment authentication:
``` js
logger.add(new winston.transports.DynamoDB({
  useEnvironment: true,
  tableName: 'log'
}));
```

Also supports callbacks for completion when the DynamoDB putItem has been completed.

### Amazon Kinesis Firehose Transport

The [winston-firehose][28] transport relays your log messages to Amazon Kinesis Firehose.

```js
const winston = require('winston');
const WFirehose = require('winston-firehose');

logger.add(new WFirehose(options));
```

Options:

* __streamName:__ The name of the Amazon Kinesis Firehose stream to which to log. *[required]*
* __firehoseOptions:__ The AWS Kinesis firehose options to pass direction to the firehose client, [as documented by AWS](http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Firehose.html#constructor-property). *[required]*

### Amazon SNS (Simple Notification System) Transport

The [winston-sns][18] transport uses amazon SNS to send emails, texts, or a bunch of other notifications. Since this transport uses the Amazon AWS SDK for JavaScript, you can take advantage of the various methods of authentication found in Amazon's [Configuring the SDK in Node.js](http://docs.aws.amazon.com/AWSJavaScriptSDK/guide/node-configuring.html) document.

``` js
const winston = require('winston');
const SnsTransport = require('winston-sns');

logger.add(new SnsTransport(options));
```

Options:

* __subscriber:__ Subscriber number - found in your SNS AWS Console, after clicking on a topic. Same as AWS Account ID. *[required]*
* __topic_arn:__ Also found in SNS AWS Console - listed under a topic as Topic ARN. *[required]*
* __aws_key:__ Your Amazon Web Services Key.
* __aws_secret:__ Your Amazon Web Services Secret.
* __region:__ AWS Region to use. Can be one of: `us-east-1`,`us-west-1`,`eu-west-1`,`ap-southeast-1`,`ap-northeast-1`,`us-gov-west-1`,`sa-east-1`. (default: `us-east-1`)
* __subject:__ Subject for notifications. Uses placeholders for level (%l), error message (%e), and metadata (%m). (default: "Winston Error Report")
* __message:__ Message of notifications. Uses placeholders for level (%l), error message (%e), and metadata (%m). (default: "Level '%l' Error:\n%e\n\nMetadata:\n%m")
* __level:__ lowest level this transport will log. (default: `info`)
* __json:__ use json instead of a prettier (human friendly) string for meta information in the notification. (default: `false`)
* __handleExceptions:__ set to true to have this transport handle exceptions. (default: `false`)

### Azure Table

[winston-azuretable][21] is a Azure Table transport:

``` js
const { AzureLogger } = require('winston-azuretable');
logger.add(new AzureLogger(options));
```

The Azure Table transport connects to an Azure Storage Account using the following options:

* __useDevStorage__: Boolean flag denoting whether to use the Azure Storage Emulator (default: `false`)
* __account__: Azure Storage Account Name. In lieu of this setting, you can set the environment variable: `AZURE_STORAGE_ACCOUNT`
* __key__: Azure Storage Account Key. In lieu of this setting, you can set the environment variable: `AZURE_STORAGE_ACCESS_KEY`
* __level__: lowest logging level transport to be logged (default: `info`)
* __tableName__: name of the table to log messages (default: `log`)
* __partitionKey__: table partition key to use (default: `process.env.NODE_ENV`)
* __silent__: Boolean flag indicating whether to suppress output (default: `false`)

### Cassandra Transport

[winston-cassandra][20] is a Cassandra transport:

``` js
const Cassandra = require('winston-cassandra').Cassandra;
logger.add(new Cassandra(options));
```

The Cassandra transport connects to a cluster using the native protocol with the following options:

* __level:__ Level of messages that this transport should log (default: `'info'`).
* __table:__ The name of the Cassandra column family you want to store log messages in (default: `'logs'`).
* __partitionBy:__ How you want the logs to be partitioned. Possible values `'hour'` and `'day'`(Default).
* __consistency:__ The consistency of the insert query (default: `quorum`).

In addition to the options accepted by the [Node.js Cassandra driver](https://github.com/jorgebay/node-cassandra-cql) Client.

* __hosts:__ Cluster nodes that will handle the write requests:
Array of strings containing the hosts, for example `['host1', 'host2']` (required).
* __keyspace:__ The name of the keyspace that will contain the logs table (required). The keyspace should be already created in the cluster.

### Cisco Spark Transport

[winston-spark][31] is a transport for [Cisco Spark](https://www.ciscospark.com/)

``` js
const winston = require('winston');
require('winston-spark');

const options = {
  accessToken: '***Your Spark Access Token***',
  roomId: '***Spark Room Id***'
};

logger.add(new winston.transports.SparkLogger(options));
```

Valid Options are as the following:
* __accessToken__ Your Spark Access Token. *[required]*
* __roomId__ Spark Room Id. *[required]*
* __level__ Log Level (default: info)
* __hideMeta__ Hide MetaData (default: false)

### Cloudant
[winston-clodant][34] is a transport for Cloudant NoSQL Db.

```js
const winston = require('winston');
const WinstonCloudant = require('winston-cloudant');
logger.add(new WinstonCloudant(options));
```

The Cloudant transport takes the following options:

    url         : Access url including user and password [required]
    username    : Username for the Cloudant DB instance
    password    : Password for the Cloudant DB instance
    host        : Host for the Cloudant DB instance
    db          : Name of the databasename to put logs in
    logstash    : Write logs in logstash format

### Datadog Transport
[datadog-logger-integrations][38] is a transport to ship your logs to DataDog.

```javascript
var winston = require('winston')
var { DataDogTransport } = require('datadog-logger-integrations/winston')

var logger = winston.createLogger({
  // Whatever options you need
  // Refer https://github.com/winstonjs/winston#creating-your-own-logger
})

logger.add(
  new DataDogTransport({
    ddClientConfig: {
      authMethods: {
        apiKeyAuth: apiKey,
      },
    },
    service: 'super_service',
    ddSource: 'nodejs',
    ddTags: 'foo:bar,boo:baz'
  })
)
```

Options:
* __ddClientConfig__: DataDog client config *[required]*
* __service__: The name of the application or service generating the logs
* __ddsource__: The technology from which the logs originated
* __ddtags__: Metadata associated with the logs

### Google BigQuery
[winston-bigquery][42] is a transport for Google BigQuery.

```js
import {WinstonBigQuery} from 'winston-bigquery';
import winston, {format} from 'winston';

const logger = winston.createLogger({
	transports: [
		new WinstonBigQuery({
			tableId: 'winston_logs',
			datasetId: 'logs'
		})
	]
});
```

The Google BigQuery takes the following options:

* __datasetId__   	      	    : Your dataset name [required]
* __tableId__     	  	    : Table name in the datase [required]
* __applicationCredentials__    : a path to local service worker (useful in dev env) [Optional]

**Pay Attention**, since BQ, unlike some other products, is not a "schema-less" you will need to build the schema in advance.
read more on the topic on [github][42] or [npmjs.com][43]

### Google Stackdriver Transport

[@google-cloud/logging-winston][29] provides a transport to relay your log messages to [Stackdriver Logging][30].

```js
const winston = require('winston');
const Stackdriver = require('@google-cloud/logging-winston');
logger.add(new Stackdriver({
  projectId: 'your-project-id',
  keyFilename: '/path/to/keyfile.json'
}));
```

### Graylog2 Transport

[winston-graylog2][19] is a Graylog2 transport:

``` js
const winston = require('winston');
const Graylog2 = require('winston-graylog2');
logger.add(new Graylog2(options));
```

The Graylog2 transport connects to a Graylog2 server over UDP using the following options:

* __name__:  Transport name
* __level__: Level of messages this transport should log. (default: info)
* __silent__: Boolean flag indicating whether to suppress output. (default: false)
* __handleExceptions__: Boolean flag, whenever to handle uncaught exceptions. (default: false)
* __graylog__:
  - __servers__; list of graylog2 servers
    * __host__: your server address (default: localhost)
    * __port__: your server port (default: 12201)
  - __hostname__: the name of this host (default: os.hostname())
  - __facility__: the facility for these log messages (default: "Node.js")
  - __bufferSize__: max UDP packet size, should never exceed the MTU of your system (default: 1400)

### Elasticsearch Transport

Log to Elasticsearch in a logstash-like format and
leverage Kibana to browse your logs.

See: https://github.com/vanthome/winston-elasticsearch.

### FastFileRotate Transport

[fast-file-rotate][35] is a performant file transport providing daily log rotation.

```js
const FileRotateTransport = require('fast-file-rotate');
const winston = require('winston');

const logger = winston.createLogger({
  transports: [
    new FileRotateTransport({
      fileName: __dirname + '/console%DATE%.log'
    })
  ]
})
```

### Humio Transport

[humio-winston][44] is a transport for sending logs to Humio:

``` js
const winston = require('winston');
const HumioTransport = require('humio-winston');

const logger = winston.createLogger({
  transports: [
    new HumioTransport({
      ingestToken: '<YOUR HUMIO INGEST TOKEN>',
    }),
  ],
});
```

### LogDNA Transport

[LogDNA Winston][37] is a transport for being able to forward the logs to [LogDNA](https://logdna.com/):

``` js
const logdnaWinston = require('logdna-winston');
const winston = require('winston');
const logger = winston.createLogger({});
const options = {
    key: apikey, // the only field required
    hostname: myHostname,
    ip: ipAddress,
    mac: macAddress,
    app: appName,
    env: envName,
    index_meta: true // Defaults to false, when true ensures meta object will be searchable
};

// Only add this line in order to track exceptions
options.handleExceptions = true;

logger.add(new logdnaWinston(options));

let meta = {
    data:'Some information'
};
logger.log('info', 'Log from LogDNA Winston', meta);
```

### Logzio Transport

You can download the logzio transport here : [https://github.com/logzio/winston-logzio](https://github.com/logzio/winston-logzio)

*Basic Usage*
```js
const winston = require('winston');
const Logzio = require('winston-logzio');

logger.add(new Logzio({
  token: '__YOUR_API_TOKEN__'
}));
```

For more information about how to configure the logzio transport, view the README.md in the [winston-logzio repo](https://github.com/logzio/winston-logzio).

### Logsene Transport

[winston-logsene][24] transport for Elasticsearch bulk indexing via HTTPS to Logsene:

``` js
const winston = require('winston');
const Logsene = require('winston-logsene');

logger.add(new Logsene({
  token: process.env.LOGSENE_TOKEN
  /* other options */
}));
```
Options:
* __token__: Logsene Application Token
* __source__: Source of the logs (defaults to main module)

[Logsene](http://www.sematext.com/logsene/) features:
- Fulltext search
- Anomaly detection and alerts
- Kibana4 integration
- Integration with [SPM Performance Monitoring for Node.js](http://www.sematext.com/spm/integrations/nodejs-monitoring.html)

### Mail Transport

The [winston-mail][16] is an email transport:

``` js
const { Mail } = require('winston-mail');
logger.add(new Mail(options));
```

The Mail transport uses [node-mail][17] behind the scenes.  Options are the following, `to` and `host` are required:

* __to:__ The address(es) you want to send to. *[required]*
* __from:__ The address you want to send from. (default: `winston@[server-host-name]`)
* __host:__ SMTP server hostname
* __port:__ SMTP port (default: 587 or 25)
* __secure:__ Use secure
* __username__ User for server auth
* __password__ Password for server auth
* __level:__ Level of messages that this transport should log.
* __silent:__ Boolean flag indicating whether to suppress output.

*Metadata:* Stringified as JSON in email.

### MySQL Transport

[winston-mysql](https://github.com/charles-zh/winston-mysql) is a MySQL transport for Winston.

Create a table in your database first:

```sql
 CREATE TABLE `sys_logs_default` (
 `id` INT NOT NULL AUTO_INCREMENT,
 `level` VARCHAR(16) NOT NULL,
 `message` VARCHAR(2048) NOT NULL,
 `meta` VARCHAR(2048) NOT NULL,
 `timestamp` DATETIME NOT NULL,
 PRIMARY KEY (`id`));
```

> You can also specify `meta` to be a `JSON` field on MySQL 5.7+, i.e., ``meta` JSON NOT NULL`, which is helfpul for searching and parsing.

Configure Winston with the transport:

```javascript
import MySQLTransport from 'winston-mysql';

const options = {
    host: '${MYSQL_HOST}',
    user: '${MYSQL_USER}',
    password: '${MYSQL_PASSWORD}',
    database: '${MYSQL_DATABASE}',
    table: 'sys_logs_default'
};

const logger = winston.createLogger({
    level: 'debug',
    format: winston.format.json(),
    defaultMeta: { service: 'user-service' },
    transports: [
        new winston.transports.Console({
            format: winston.format.simple(),
        }),
        new MySQLTransport(options),
    ],
});

/// ...
let msg = 'My Log';
logger.info(msg, {message: msg, type: 'demo'});
```


### New Relic Agent Transport

[winston-newrelic-agent-transport][47] is a New Relic transport that leverages the New Relic agent:

``` js
import winston from 'winston'
import NewrelicTransport from 'winston-newrelic-agent-transport'

const logger = winston.createLogger()

const options = {}
logger.add(new NewrelicTransport(options))
```

The New Relic agent typically automatically forwards Winston logs to New Relic when using CommonJS. With CommonJS no additional transport should be needed. However, when using ECMAScript modules, the automatic forwarding of logs can with certain coding patterns not work. If the New Relic agent is not automatically forwarding your logs, this transport provides a solution.

Options:

* __level__ (optional): The Winston logging level to use as the maximum level of messages that the transport will log.
* __rejectCriteria__ (optional): The rejectCriteria option allows you to specify an array of regexes that will be matched against either the Winston info object or log message to determine whether or not a log message should be rejected and not logged to New Relic.

### Papertrail Transport

[winston-papertrail][27] is a Papertrail transport:

``` js
const { Papertrail } = require('winston-papertrail');
logger.add(new Papertrail(options));
```

The Papertrail transport connects to a [PapertrailApp log destination](https://papertrailapp.com) over TCP (TLS) using the following options:

* __level:__ Level of messages this transport should log. (default: info)
* __host:__ FQDN or IP address of the Papertrail endpoint.
* __port:__ Port for the Papertrail log destination.
* __hostname:__ The hostname associated with messages. (default: require('os').hostname())
* __program:__ The facility to send log messages.. (default: default)
* __logFormat:__ a log formatting function with the signature `function(level, message)`, which allows custom formatting of the level or message prior to delivery

*Metadata:* Logged as a native JSON object to the 'meta' attribute of the item.

### Parseable Transport

[Parseable](https://parseable.com/) is an open source, general purpose log analytics system. [Parseable-Winston](https://github.com/jybleau/parseable-node-loggers/tree/main/packages/winston#parseable-winston) is a Parseable transport for Winston.

```js
// Using cjs
const { ParseableTransport } = require('parseable-winston')
const winston = require('winston')

const parseable = new ParseableTransport({
  url: process.env.PARSEABLE_LOGS_URL, // Ex: 'https://parsable.myserver.local/api/v1/logstream'
  username: process.env.PARSEABLE_LOGS_USERNAME,
  password: process.env.PARSEABLE_LOGS_PASSWORD,
  logstream: process.env.PARSEABLE_LOGS_LOGSTREAM, // The logstream name
  tags: { tag1: 'tagValue' } // optional tags to be added with each ingestion
})

const logger = winston.createLogger({
  levels: winston.config.syslog.levels,
  transports: [parseable],
  defaultMeta: { instance: 'app', hostname: 'app1' }
})

logger.info('User took the goggles', { userid: 1, user: { name: 'Rainier Wolfcastle' } })
logger.warning('The goggles do nothing', { userid: 1 })
```

### PostgresQL Transport

[@pauleliet/winston-pg-native](https://github.com/petpano/winston-pg-native) is a PostgresQL transport supporting Winston 3.X.

### Pusher Transport
[winston-pusher](https://github.com/meletisf/winston-pusher) is a Pusher transport.

```js
const { PusherLogger } = require('winston-pusher');
logger.add(new PusherLogger(options));
```

This transport sends the logs to a Pusher app for real time processing and it uses the following options:

* __pusher__ [Object]
  * __appId__ The application id obtained from the dashboard
  * __key__ The application key obtained from the dashboard
  * __secret__ The application secret obtained from the dashboard
  * __cluster__ The cluster
  * __encrypted__ Whether the data will be send through SSL
* __channel__ The channel of the event (default: default)
* __event__ The event name (default: default)

### Sentry Transport
[winston-transport-sentry-node][41] is a transport for [Sentry](https://sentry.io/) uses [@sentry/node](https://www.npmjs.com/package/@sentry/node).

```js
const Sentry = require('winston-transport-sentry-node').default;
logger.add(new Sentry({
  sentry: {
    dsn: 'https://******@sentry.io/12345',
  },
  level: 'info'
}));
```

This transport takes the following options:

* __sentry:__ [Object]
  * __dsn:__ Sentry DSN or Data Source Name (default: `process.env.SENTRY_DSN`) **REQUIRED**
  * __environment:__ The application environment (default: `process.env.SENTRY_ENVIRONMENT || process.env.NODE_ENV || 'production'`)
  * __serverName:__  The application name
  * __debug:__ Turns debug mode on or off (default: `process.env.SENTRY_DEBUG || false`)
  * __sampleRate:__ Sample rate as a percentage of events to be sent in the range of 0.0 to 1.0 (default: `1.0`)
  * __maxBreadcrumbs:__ Total amount of breadcrumbs that should be captured (default: `100`)
* __level:__ Level of messages that this transport should log
* __silent:__  Boolean flag indicating whether to suppress output, defaults to false

### Seq Transport

[winston-seq][45] is a transport that sends structured log events to [Seq](https://datalust.co/seq).

```js
const { SeqTransport } = require('@datalust/winston-seq');
logger.add(new SeqTransport({
  serverUrl: "https://your-seq-server:5341",
  apiKey: "your-api-key",
  onError: (e => { console.error(e) }),
}));
```

`SeqTransport` is configured with the following options:

* __serverUrl__ - the URL for your Seq server's ingestion
* __apiKey__ - (optional) The Seq API Key to use
* __onError__ - Callback to execute when an error occurs within the transport

### SimpleDB Transport

The [winston-simpledb][15] transport is just as easy:

``` js
const SimpleDB = require('winston-simpledb').SimpleDB;
logger.add(new SimpleDB(options));
```

The SimpleDB transport takes the following options. All items marked with an asterisk are required:

* __awsAccessKey__:* your AWS Access Key
* __secretAccessKey__:* your AWS Secret Access Key
* __awsAccountId__:* your AWS Account Id
* __domainName__:* a string or function that returns the domain name to log to
* __region__:* the region your domain resides in
* __itemName__: a string ('uuid', 'epoch', 'timestamp') or function that returns the item name to log

*Metadata:* Logged as a native JSON object to the 'meta' attribute of the item.

### Slack Transport
[winston-slack-webhook-transport][39] is a transport that sends all log messages to the Slack chat service.

```js
const winston = require('winston');
const SlackHook = require('winston-slack-webhook-transport');

const logger = winston.createLogger({
	level: 'info',
	transports: [
		new SlackHook({
			webhookUrl: 'https://hooks.slack.com/services/xxx/xxx/xxx'
		})
	]
});

logger.info('This should now appear on Slack');
```

This transport takes the following options:

* __webhookUrl__ - Slack incoming webhook URL. This can be from a basic integration or a bot. **REQUIRED**
* __channel__ - Slack channel to post message to.
* __username__ - Username to post message with.
* __iconEmoji__ - Status icon to post message with. (interchangeable with __iconUrl__)
* __iconUrl__ - Status icon to post message with. (interchangeable with __iconEmoji__)
* __formatter__ - Custom function to format messages with. This function accepts the __info__ object ([see Winston documentation](https://github.com/winstonjs/winston/blob/master/README.md#streams-objectmode-and-info-objects)) and must return an object with at least one of the following three keys: __text__ (string), __attachments__ (array of [attachment objects](https://api.slack.com/docs/message-attachments)), __blocks__ (array of [layout block objects](https://api.slack.com/messaging/composing/layouts)). These will be used to structure the format of the logged Slack message. By default, messages will use the format of `[level]: [message]` with no attachments or layout blocks.
* __level__ - Level to log. Global settings will apply if this is blank.
* __unfurlLinks__ - Enables or disables [link unfurling.](https://api.slack.com/docs/message-attachments#unfurling) (Default: false)
* __unfurlMedia__ - Enables or disables [media unfurling.](https://api.slack.com/docs/message-link-unfurling) (Default: false)
* __mrkdwn__ - Enables or disables [`mrkdwn` formatting](https://api.slack.com/messaging/composing/formatting#basics) within attachments or layout blocks (Default: false)

### SQLite3 Transport

The [winston-better-sqlite3][40] transport uses [better-sqlite3](https://github.com/JoshuaWise/better-sqlite3).

```js
const wbs = require('winston-better-sqlite3');
logger.add(new wbs({

    // path to the sqlite3 database file on the disk
    db: '<name of sqlite3 database file>',

    // A list of params to log
    params: ['level', 'message']
}));
```

### Sumo Logic Transport
[winston-sumologic-transport][32] is a transport for Sumo Logic

``` js
const winston = require('winston');
const { SumoLogic } = require('winston-sumologic-transport');

logger.add(new SumoLogic(options));
```

Options:
* __url__: The Sumo Logic HTTP collector URL

### SSE transport with KOA 2
[winston-koa-sse](https://github.com/alexvictoor/winston-koa-sse) is a transport that leverages on Server Sent Event. With this transport you can use your browser console to view your server logs.

### VS Code extension

[winston-transport-vscode][48] is a transport for VS Code extension development.

```js
const vscode = require('vscode');
const winston = require('winston');
const { OutputChannelTransport } = require('winston-transport-vscode');

const outputChannel = vscode.window.createOutputChannel('My extension');

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

The extension includes dedicated log levels and format for using with VS Code's
LogOutputChannel.

```js
const { LogOutputChannelTransport } = require('winston-transport-vscode');

const outputChannel = vscode.window.createOutputChannel('My extension', {
  log: true,
});

const logger = winston.createLogger({
  levels: LogOutputChannelTransport.config.levels,
  format: LogOutputChannelTransport.format(),
  transports: [new LogOutputChannelTransport({ outputChannel })],
});
```


### Worker Thread based async Console transport

[winston-console-transport-in-worker][46]

```typescript
import * as winston from 'winston';
import { ConsoleTransportInWorker } from '@greeneyesai/winston-console-transport-in-worker';

...

export const logger: winston.Logger = winston.createLogger({
    format: combine(timestamp(), myFormat),
    level: Level.INFO,
    transports: [new ConsoleTransportInWorker()],
});
```

The `ConsoleTransportInWorker` is a subclass of `winston.transports.Console` therefore accepting the same options as the `Console` transport.

TypeScript supported.

### Winlog2 Transport

[winston-winlog2][33] is a Windows Event log transport:

``` js
const winston = require('winston');
const Winlog2 = require('winston-winlog2');
logger.add(new Winlog2(options));
```

The winlog2 transport uses the following options:

* __name__:  Transport name
* __eventLog__: Log type (default: 'APPLICATION')
* __source__: Name of application which will appear in event log (default: 'node')

## Looking for maintainers

These transports are part of the `winston` Github organization but are
actively seeking new maintainers. Interested in getting involved? Open an
issue on `winston` to get the conversation started!

* [CouchDB](#couchdb-transport)
* [Loggly](#loggly-transport)
* [Redis](#redis-transport)
* [Riak](#riak-transport)

### CouchDB Transport

_As of `winston@0.6.0` the CouchDB transport has been broken out into a new module: [winston-couchdb][2]._

``` js
const WinstonCouchDb = require('winston-couchdb');
logger.add(new WinstonCouchdb(options));
```

The `Couchdb` will place your logs in a remote CouchDB database. It will also create a [Design Document][3], `_design/Logs` for later querying and streaming your logs from CouchDB. The transport takes the following options:

* __host:__ (Default: **localhost**) Remote host of the HTTP logging endpoint
* __port:__ (Default: **5984**) Remote port of the HTTP logging endpoint
* __db:__ (Default: **winston**) Remote URI of the HTTP logging endpoint
* __auth:__ (Default: **None**) An object representing the `username` and `password` for HTTP Basic Auth
* __ssl:__ (Default: **false**) Value indicating if we should us HTTPS

### Loggly Transport

_As of `winston@0.6.0` the Loggly transport has been broken out into a new module: [winston-loggly][5]._

``` js
const WinstonLoggly = require('winston-loggly');
logger.add(new winston.transports.Loggly(options));
```

The Loggly transport is based on [Nodejitsu's][6] [node-loggly][7] implementation of the [Loggly][8] API. If you haven't heard of Loggly before, you should probably read their [value proposition][9]. The Loggly transport takes the following options. Either 'inputToken' or 'inputName' is required:

* __level:__ Level of messages that this transport should log.
* __subdomain:__ The subdomain of your Loggly account. *[required]*
* __auth__: The authentication information for your Loggly account. *[required with inputName]*
* __inputName:__ The name of the input this instance should log to.
* __inputToken:__ The input token of the input this instance should log to.
* __json:__ If true, messages will be sent to Loggly as JSON.

### Redis Transport

``` js
const WinstonRedis = require('winston-redis');
logger.add(new WinstonRedis(options));
```

This transport accepts the options accepted by the [node-redis][4] client:

* __host:__ (Default **localhost**) Remote host of the Redis server
* __port:__ (Default **6379**) Port the Redis server is running on.
* __auth:__ (Default **None**) Password set on the Redis server

In addition to these, the Redis transport also accepts the following options.

* __length:__ (Default **200**) Number of log messages to store.
* __container:__ (Default **winston**) Name of the Redis container you wish your logs to be in.
* __channel:__ (Default **None**) Name of the Redis channel to stream logs from.

### Riak Transport

_As of `winston@0.3.0` the Riak transport has been broken out into a new module: [winston-riak][11]._ Using it is just as easy:

``` js
const { Riak } = require('winston-riak');
logger.add(new Riak(options));
```

In addition to the options accepted by the [riak-js][12] [client][13], the Riak transport also accepts the following options. It is worth noting that the riak-js debug option is set to *false* by default:

* __level:__ Level of messages that this transport should log.
* __bucket:__ The name of the Riak bucket you wish your logs to be in or a function to generate bucket names dynamically.

``` js
  // Use a single bucket for all your logs
  const singleBucketTransport = new Riak({ bucket: 'some-logs-go-here' });

  // Generate a dynamic bucket based on the date and level
  const dynamicBucketTransport = new Riak({
    bucket: function (level, msg, meta, now) {
      var d = new Date(now);
      return level + [d.getDate(), d.getMonth(), d.getFullYear()].join('-');
    }
  });
```


## Find more Transports

There are more than 1000 packages on `npm` when [you search for] `winston`.
That's why we say it's a logger for just about everything

[you search for]: https://www.npmjs.com/search?q=winston
[0]: https://nodejs.org/api/stream.html#stream_class_stream_writable
[1]: https://github.com/flatiron/winstond
[2]: https://github.com/indexzero/winston-couchdb
[3]: http://guide.couchdb.org/draft/design.html
[4]: https://github.com/mranney/node_redis
[5]: https://github.com/indexzero/winston-loggly
[6]: http://nodejitsu.com
[7]: https://github.com/nodejitsu/node-loggly
[8]: http://loggly.com
[9]: http://www.loggly.com/product/
[10]: http://wiki.loggly.com/loggingfromcode
[11]: https://github.com/indexzero/winston-riak
[12]: http://riakjs.org
[13]: https://github.com/frank06/riak-js/blob/master/src/http_client.coffee#L10
[14]: http://github.com/indexzero/winston-mongodb
[15]: http://github.com/appsattic/winston-simpledb
[16]: http://github.com/wavded/winston-mail
[17]: https://github.com/weaver/node-mail
[18]: https://github.com/jesseditson/winston-sns
[19]: https://github.com/namshi/winston-graylog2
[20]: https://github.com/jorgebay/winston-cassandra
[21]: https://github.com/jpoon/winston-azuretable
[22]: https://github.com/rickcraig/winston-airbrake2
[24]: https://github.com/sematext/winston-logsene
[25]: https://github.com/timdp/winston-aws-cloudwatch
[26]: https://github.com/lazywithclass/winston-cloudwatch
[27]: https://github.com/kenperkins/winston-papertrail
[28]: https://github.com/pkallos/winston-firehose
[29]: https://www.npmjs.com/package/@google-cloud/logging-winston
[30]: https://cloud.google.com/logging/
[31]: https://github.com/joelee/winston-spark
[32]: https://github.com/avens19/winston-sumologic-transport
[33]: https://github.com/peteward44/winston-winlog2
[34]: https://github.com/hakanostrom/winston-cloudant
[35]: https://github.com/SerayaEryn/fast-file-rotate
[36]: https://github.com/inspiredjw/winston-dynamodb
[37]: https://github.com/logdna/logdna-winston
[38]: https://github.com/marklai1998/datadog-logger-integrations
[39]: https://github.com/TheAppleFreak/winston-slack-webhook-transport
[40]: https://github.com/punkish/winston-better-sqlite3
[41]: https://github.com/aandrewww/winston-transport-sentry-node
[42]: https://github.com/kaminskypavel/winston-bigquery
[43]: https://www.npmjs.com/package/winston-bigquery
[44]: https://github.com/Quintinity/humio-winston
[45]: https://github.com/datalust/winston-seq
[46]: https://github.com/arpad1337/winston-console-transport-in-worker
[47]: https://github.com/kimnetics/winston-newrelic-agent-transport
[48]: https://github.com/loderunner/winston-transport-vscode

---

--- METRICS ---
- Files Extracted: 4
- Estimated Token Budget: ~22138 tokens
- Canonical Reference: https://codewiki.google/github.com/winstonjs/winston
