Skip to main content

Logging

The framework uses the Winston logger as the main subsystem for logging.

You can adjust different transports (console and Sentry are available by default) and add your own transport with your own parameters.

The framework provides a basic initialization of Winston so you can easily use it out of the box, but you still have the ability to adjust it as you want.

Logging Levels

RFC5424 defines logger levels. Higher levels will include messages from lower levels. In other words, if you set the ‘warn’ level, the logger will report ‘error’ as well, but will not report the ‘debug’ level.

You can read more about levels in the Winston levels documentation.

But in short, these are the default levels:

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

API

Each class has access to the logger instance via:

this.logger;
this.logger.error("error message");
this.logger.warn("warn message");
this.logger.info("info message");
this.logger.http("http message");
this.logger.verbose("verbose message");
this.logger.debug("debug message");
this.logger.silly("silly message");
tip

Please note that this.logger is an instance of winston.logger, and you can use any methods from it.

Default Transports

By default, the framework provides two transports: console and Sentry (via winston-transport-sentry-node).

Configuration

We try to keep the configuration simple and powerful - you are able to enable/disable loggers and add your own with all available options passed to the transport.

Configuration files are located in ‘config/log.js’.

export default {
transports: [
{
transport: "winston-transport-sentry-node", // transport name (npm package name)
transportOptions: {
// options that will be passed to the transport instance
sentry: {
dsn: process.env.LOGGER_SENTRY_DSN,
},
level: process.env.LOGGER_SENTRY_LEVEL || "info",
},
enable: process.env.LOGGER_SENTRY_ENABLE || false, // whether the transport is enabled or not
},
{
// ....
},
/// more transports
],
};

The config contains a “transports” array. Each transport can be included in the logger.

The transport name is an npm package name that the framework will require. You can use any transport from NPM.

The transportOptions field contains the transport options - you can pass any options here for the transport. Please refer to the transport documentation.

And finally, the enable field will enable/disable modules for the logger. You can check “NODE_ENV” in the config documentation to learn more about how you can use it depending on your environment.

Add Your Own Transport

Adding your own transport is a simple process.

npm i ${WINSTON_TRANSPORT_PACKAGE}

Then add it to the ‘config/log.ts’ config file.

export default {
transports: [
{
// .....
// some already existing transports
},
{
// ....
},
{
transport: "WINSTON_TRANSPORT_PACKAGE",
transportOptions: {
// options that will be passed to the transport instance
// .... your transport options
},
enable: true,
},
],
};
tip

Feel free to use environment variables in your transport config as well. That simplifies working with multiple environments.

Console Output for Logger

Console loggers act in a customized way to provide more verbose info. The default console output is constructed as:

(${process.pid}) ${info.label} ${info.timestamp} ${info.level} : ${info.message}

Where: “process.pid” - the PID of the Node process. Useful in a cluster environment. “info.label” - the label of the place. More info below. “info.timestamp” - the date of the event. “info.level” - the log level (“error”, ”warn”, etc.). “info.message” - the message that was passed to the logger (e.g., this.logger.info(“this is a message”)).

info.label

Inside the base class, we have a method “loggerGroup” that is used as the first part of the info message generation. This is useful for grouping messages like “controllers”, ”models”, etc.

The framework uses the following groups: “command”, “connector”, “controller”, “model”, and “CLI_”.

tip

Feel free to introduce your own groups.

The second part is generated by the base class function “getConstructorName”, which by default grabs the constructor name and adds it to the info string. You can overwrite this method for your classes.

Example:

(15950)  [modelCoin]  2021-10-18T11:17:54.746Z  verbose : Model have no hooks

Here:

(15950) - process PID
[modelCoin] - info message ("model" - group, "Coin" - model name)
2021-10-18T11:17:54.746Z - time
verbose - level
Model have no hooks - message

Environment Variables

Sentry Transport

LOGGER_SENTRY_DSN - Sentry DSN.

LOGGER_SENTRY_LEVEL - the log level that should go into Sentry. Default: 'info'.

LOGGER_SENTRY_ENABLE - enable or disable the Sentry logger. Default: 'false'.

Console Transport

LOGGER_CONSOLE_LEVEL - the log level. Default: 'silly' (includes all).

LOGGER_CONSOLE_ENABLE - enable or disable the console logger. Default: 'true'.