Logging practices
February 7, 2023This post covers some logging practices for the back-end (Node.js) apps.
Avoid putting unique identifiers (e.g., user id) within the message. A unique id will produce a lot of different messages with the same context. Use it as a message parameter.
Use the appropriate log level for the message. There are multiple log levels
- info - app behavior, don't log every single step
- error - app processing failure, something that needs to be fixed
- debug - additional logs needed for troubleshooting
- warning - something unexpected happened (e.g., third-party API fails)
- fatal - app crash, needs to be fixed as soon as possible
Don't use the debug logs on production. Put log level as an environment variable.
Stream logs to the standard output in JSON format so logging aggregators (Graylog, e.g.) can collect and adequately parse them
Avoid logging any credentials, like passwords, auth tokens, etc.
Put correlation ID as a message parameter for tracing related logs.
Use a configurable logger like pino
const pino = require('pino');const logger = pino({level: process.env.LOG_LEVEL || 'info',redact: {paths: ['token'],remove: true,},});logger.info({ someId: 'id' }, 'Started the app...');const correlationId = request.headers['correlation-id'] || uuid.v4();logger.debug({ data: 'some data useful for debugging', correlationId }, 'Sending the request...');
Boilerplate
Here is the link to the boilerplate I use for the development.