npm package: @lightbase/logger
Description: Simple logger in NDJSON format
Author: Dirk de Visser
Latest version: 2.1.0
Deprecated: Discontinued, see @lbu/insight

# Logger

A simple logging utility library

```bash
yarn add @lightbase/logger
# npm install @lightbase/logger
```

## Features

- Log to any writable stream
- Only stringify to a maximum property depth
- Pretty print for development & NDJSON (New line delimited JSON) for production

## Example

```js
const { log, Logger } = require("./lib");

log.info("Hello");
log.info("Hello object", { my: "object" });
log.info("Hello array", ["my", "array"]);
log.info({ object: "only" });
log.info(["array", "only"]);

const myExtendedLogger = Logger.new({ context: { custom: "info" } });
myExtendedLogger.info(context);
```

Production output:

```text
{"level":"info","timestamp":"2019-05-26T14:28:46.989Z","message":"Hello"}
{"level":"info","timestamp":"2019-05-26T14:28:46.990Z","message":"Hello object","my":"object"}
{"level":"info","timestamp":"2019-05-26T14:28:46.990Z","message":"Hello array","values":["my","array"]}
{"level":"info","timestamp":"2019-05-26T14:28:46.990Z","object":"only"}
{"level":"info","timestamp":"2019-05-26T14:28:46.991Z","values":["array","only"]}
{"level":"info","timestamp":"2019-05-26T14:28:46.992Z","message":"Same result as before, except the data from extraObj is added to the output.","custom":"info"}
```

Development output: ![Development output console](./output.png "Console output")

Check the examples folder for simple integrations with Koa and Express

# API

- [Types](#types)
- [Exports](#exports)

## Types

**LogFunction**: Function

Function signature used in `Logger`.

`(message: string | any, arg?: any | undefined | null): void`

**LogData**: Object

Object to pass around log information

| Key         | Type     | Info                                                             |
| ----------- | -------- | ---------------------------------------------------------------- |
| level       | LogLevel | The level of this log information                                |
| timestamp   | Date     | The date of when the log function was called                     |
| message     | string?  | Standard message property                                        |
| [s: string] | any      | Any other piece of information that is passed to the LogFunction |

**LogLevel**: Enum

The level of the data is is logged

| Key   | Value |
| ----- | ----- |
| Info  | info  |
| Error | error |

**NewLoggerOpts**: Object

Options to construct a new Logger

| Key          | Type         | Default                 | Info                                                       |
| ------------ | ------------ | ----------------------- | ---------------------------------------------------------- |
| logDepth     | number?      | 5                       | The maximum depth of object properties that are serialized |
| context      | any?         | {}                      | The context of the logger, this is appended to all logs    |
| stream       | WriteStream? | process.stdout          | The stream to write the logs to                            |
| isProduction | boolean?     | NODE_ENV === production | Write NDJSON or pretty print                               |

**NewMiddlewareOpts**: Object extends `NewLoggerOpts`

The object to be passed to `expressMiddleware` and `koaMiddleware` functions

**Formatter**: Class

**Formatter::RESERVED_KEYS**: string[]

Keys that are reserved by the Formatter. If an object comes by with those keys, an underscore (`_`) is added
in front of the key.

**Formatter#constructor**: Function

Create a new formatter instance

| Key      | Type     | Default |
| -------- | -------- | ------- |
| logLevel | LogLevel |         |
| context  | any      |         |
| maxDepth | number   | 5       |

**Formatter#format**: Function

Combines level, time, context, message and arg into LogData and returns the result

| Key     | Type   | Default   |
| ------- | ------ | --------- |
| message | string | any       |
| arg     | any?   | undefined |

The format function returns the following for the specified inputs.

Base result: `{level: LogLevel, timestamp: Date, ...context }`

| message Input | arg input | output                             |
| ------------- | --------- | ---------------------------------- |
| string        | undefined | { message: string }                |
| string        | array     | { message: string, values: array } |
| string        | any       | { message: string, ...any }        |
| array         | undefined | { values: array }                  |
| any           | undefined | { ...any }                         |

**Logger**: Class

**Logger::defaults**: Object

The default `NewLoggerOpts` as specified

**Logger::new**: Logger

Combines the defaults with the provided argument and returns a new Logger instance

`(opts: NewLoggerOpts): Logger`

**Logger#constructor**: Function

Constructs a new logger instance

| Key    | Type      | Info                                  |
| ------ | --------- | ------------------------------------- |
| info   | Formatter | The formatter used for info messages  |
| error  | Formatter | The formatter used for error messages |
| writer | Writer    | The writer that is used               |

**Logger#replaceWriter**: `(writer: Writer): void`

Replace the curren writer with the provided one. For example useful when using a staging environment and
setting `NODE_ENV=staging` which means by default the DevWriter will be used. Or when testing, to easily use a
mock.

**Logger#info**: LogFunction

Use the info formatter and write to writer

**Logger#error**: LogFunction

Use the error formatter and write to writer

**Logger#createChild**: `(context: any): Logger`

Create a new logger combining the current context and the provided context

**Writer**: Class

**Writer#constructor**: Function

Creates a writer for the provided stream.

| Key               | Type        | Default        |
| ----------------- | ----------- | -------------- |
| stream            | WriteStream | process.stdout |
| shouldCloseOnExit | boolean     | false          |

**Writer#write**: Function

Writes the provided data to the stream.

`(data: LogData): void`

**DevWriter**: Class extends Writer

Pretty print writer useful in development.

**DevWriter::formatTime**: Function

Format a date in the following format: `HH:MM:SS.mmm`

`(time: Date): string`

**DevWriter#write**: Function

Pretty prints the provided log data

## Exports

All types are exported

**log**: Logger

A log instance with all the defaults

**expressMiddleware**: Function

`(opts: NewMiddlewareOpts): ExpressMiddleware`

An express middleware that logs request and response info.

Also creates a new logger and adds it to `req.log` & `res.log` with a unique `requestId` in the context. To
easily follow log messages for a specific request

**koaMiddleware**: Function

`(opts: NewMiddlewareOpts): KoaMiddleware`

A Koa middleware that logs request and response info. Also add `ctx.log` with a unique `requestId` as context
to easily follow log messages for a specific request.