Skip to Content

Logging

The injectable Logger and how to replace it.

Logger is an abstract class registered by default with a ConsoleLogger. Inject it anywhere.

import { Logger } from '@sukujs/core';

@Service()
export class BillingService {
  constructor(private readonly log: Logger) {}

  charge(order: Order) {
    this.log.info('charging order', { orderId: order.id, amount: order.total });
  }
}

Methods are debug, info, warn and error. Each takes a message and an optional metadata object. error also accepts an Error and records its stack.

Level

const app = await Suku.create({ features: [AppFeature] });
(app.get(Logger) as ConsoleLogger).level = 'debug';

Entries below the level are dropped. The default is info.

Replacing it

Extend Logger, implement log, and register the class. Your registration wins over the default.

import pino from 'pino';

@Service()
export class PinoLogger extends Logger {
  private readonly pino = pino();

  log(level: LogLevel, message: string, meta?: Record<string, unknown>) {
    this.pino[level](meta ?? {}, message);
  }
}

await Suku.create({ features: [AppFeature], services: [singleton(Logger, PinoLogger)] });

SilentLogger discards everything, which is useful in tests.

Unhandled errors

An error that is not an HttpException, and that no error handler turned into a response, is reported through the logger with the method and path, then answered with a 500.

On this page