Skip to content

Logger

The logger helper wraps Winston in a scoped, cached Logger class with console, daily-rotating file, and UDP transports built in.

In one example

The smallest real use: get a scoped logger and log with it.

typescript
import { LoggerFactory } from '@venizia/ignis-helpers';

const logger = LoggerFactory.getLogger(['UserService']);
logger.info('User created');
// Output: [UserService] User created

LoggerFactory is how BaseHelper creates its internal logger, so every helper in the framework gets a scoped logger the same way, for free.

How it works

  • Typed against ILogger. Every consumer, including BaseHelper.logger, receives the ILogger interface, not a concrete class - Winston is the built-in provider behind it today, selected in factory.ts.
  • Provider-based. LoggerFactory.use({ provider }) selects the app's logger engine once at the entrypoint - Winston by default, pino for throughput. Every factory-issued logger (including ones captured at import time) follows the registration.
  • Scoped and cached. LoggerFactory.getLogger(scopes) joins the scopes with - and caches per scope - the same scope returns the same instance. BaseHelper calls this in its constructor, so every helper gets this.logger scoped automatically. (Custom-backed winston loggers - Logger.get(scope, customWinstonLogger) from the /winston sub-path - are NOT cached: each call is a fresh wrapper over the given instance.)
  • Method scoping. .for(methodName) returns a child logger scoped to <scope>-<methodName> (also cached), so each line shows where it came from.
  • Level floor. APP_ENV_LOGGER_LEVEL (default debug) sets the logger-level floor; transports without their own level inherit it.
  • debug() is gated. It emits only when DEBUG=true and NODE_ENV is unset or in Environment.COMMON_ENVS (extend via APP_ENV_EXTRA_LOG_ENVS). The check runs once at module load - runtime env changes need a restart.

Log levels

Five levels, each with a direct method: debug, info, warn, error, emerg. The generic .log(level, ...) remains for picking the level dynamically. What each level MEANS and when to use it is in the level guide.

Transports

TransportTurns on when
ConsoleAlways
Daily-rotating fileAPP_ENV_LOGGER_FOLDER_PATH is set
UDP (DgramTransport)All four UDP APP_ENV_LOGGER_DGRAM_* variables are set

Output shape (plain text or JSON) follows APP_ENV_LOGGER_FORMAT. Color codes appear only on the console - file and UDP output never carries ANSI escapes. For extreme hot paths, HfLogger is a separate ring-buffer logger outside this pipeline - it has its own usage guide. The Full reference covers everything else, including the ApplicationLogger facade.

Common tasks

Get a scoped logger

Use LoggerFactory.getLogger with an array of scope segments, or ApplicationLogger.get with a single string. Both cache by scope and follow the registered provider.

typescript
import { ApplicationLogger, LoggerFactory } from '@venizia/ignis-helpers';

const scoped = LoggerFactory.getLogger(['Payment', 'Stripe']); // [Payment-Stripe]
const direct = ApplicationLogger.get('MyService');             // [MyService]

Scope logs to a method

.for() appends a method name to the current scope so every line in that method self-identifies.

typescript
class UserService {
  private logger = LoggerFactory.getLogger(['UserService']);

  async createUser(data: CreateUserDto) {
    this.logger.for('createUser').info('Creating user: %j', data);
    // Output: [UserService-createUser] Creating user: {...}
  }
}

Log an Error with %s, never %j

message and stack are non-enumerable on a native Error. %j formats via JSON.stringify, which only visits enumerable own properties, so it silently drops both. Always pair an Error argument with %s.

typescript
logger.error('Failed to create user: %s', error); // prints message + stack

Switch the output format

APP_ENV_LOGGER_FORMAT controls plain text (default) vs. JSON output.

bash
APP_ENV_LOGGER_FORMAT=text   # 2024-01-11T10:30:00.000Z [APP] info: [UserService] User created
APP_ENV_LOGGER_FORMAT=json   # {"level":"info","message":"[UserService] User created", ...}

The [APP] label comes from APP_ENV_APPLICATION_NAME (defaults to 'APP').

Enable daily file rotation

Point APP_ENV_LOGGER_FOLDER_PATH at a directory; rotation frequency, size cap, and retention are also env-driven. Without this variable no log files are written - console (and UDP, if configured) remain the only outputs.

bash
APP_ENV_LOGGER_FOLDER_PATH=./app_data/logs
APP_ENV_LOGGER_FILE_MAX_FILES=30d

Defaults: 1h rotation frequency, 100m max size per file, 5d retention. Programmatic configuration (per-transport prefixes, custom retention) is in the Full reference.

Forward logs over UDP

Set all four APP_ENV_LOGGER_DGRAM_* variables - the transport is silently skipped if any one is missing.

bash
APP_ENV_LOGGER_DGRAM_HOST=127.0.0.1
APP_ENV_LOGGER_DGRAM_PORT=5000
APP_ENV_LOGGER_DGRAM_LABEL=my-app
APP_ENV_LOGGER_DGRAM_LEVELS=error,warn,info

See also

Files: