### Configure Pino Transport Targets with `targets()` Source: https://context7.com/adonisjs/logger/llms.txt Use the `targets()` builder to create an array of Pino transport target options. Supports conditional pushing of targets based on environment variables. This setup configures logging for development and production environments. ```typescript import { targets, defineConfig, LoggerManager } from '@adonisjs/logger' const isDev = process.env.NODE_ENV === 'development' const isProd = process.env.NODE_ENV === 'production' const transportTargets = targets() // Always write to stdout (pino/file with no destination = stdout) .push(targets.file()) // Pretty-print only in development .pushIf(isDev, targets.pretty({ colorize: true, singleLine: false })) // Write to a file only in production (lazy factory, only evaluated when condition is true) .pushUnless(isDev, () => targets.file({ destination: '/var/log/myapp.log', mkdir: true, append: true }, 'warn')) .toArray() console.log(transportTargets) // In dev: [{ target: 'pino/file', ... }, { target: 'pino-pretty', ... }] // In prod: [{ target: 'pino/file', ... }, { target: 'pino/file', destination: '/var/log/myapp.log', level: 'warn', ... }] const config = defineConfig({ default: 'main', loggers: { main: { enabled: true, level: 'debug', transport: { targets: transportTargets } }, }, }) const manager = new LoggerManager(config) manager.info('transport configured') ``` -------------------------------- ### Retrieve Named or Default Logger Instance Source: https://context7.com/adonisjs/logger/llms.txt Use `manager.use(name?)` to get a typed `Logger` instance. If no name is provided, it returns the default logger. Instances are cached and reused across calls. ```typescript import { LoggerManager, defineConfig } from '@adonisjs/logger' const manager = new LoggerManager(defineConfig({ default: 'web', loggers: { web: { enabled: true, level: 'info' }, queue: { enabled: true, level: 'debug' }, }, })) const webLogger = manager.use('web') // Logger<{ enabled: true, level: 'info' }> const queueLogger = manager.use('queue') // Logger<{ enabled: true, level: 'debug' }> const defaultLog = manager.use() // Logger (default = 'web') webLogger.info('HTTP server listening on :3333') queueLogger.debug({ jobId: 'job-42' }, 'processing job') ``` -------------------------------- ### manager.create(config, pino?) Source: https://context7.com/adonisjs/logger/llms.txt Creates an unmanaged logger instance from the provided configuration without adding it to the manager's internal cache. This is useful for constructing loggers that are short-lived or intended for one-off use. It can also optionally wrap an existing Pino instance. ```APIDOC ## manager.create(config, pino?) Creates a brand-new `Logger` instance from the given config without registering it in the manager's internal cache. Useful for constructing short-lived or one-off loggers. ```ts import { LoggerManager, defineConfig, destination } from '@adonisjs/logger' const manager = new LoggerManager(defineConfig({ default: 'main', loggers: { main: { enabled: true, level: 'info' } }, })) // Ephemeral logger writing to stderr const errLogger = manager.create({ enabled: true, level: 'error', destination: destination(2), // fd 2 = stderr }) er rLogger.error('critical failure reported to stderr') // Pass an existing pino instance import pino from 'pino' const pinoInst = pino({ level: 'warn' }) const wrapped = manager.create({ enabled: true, level: 'warn' }, pinoInst) wrapped.warn('wrapping existing pino instance') ``` ``` -------------------------------- ### new Logger(config) Source: https://context7.com/adonisjs/logger/llms.txt Instantiates a Pino-backed logger. You can pass `enabled: false` to create a no-op logger, which is useful for test environments. The `destination` option allows you to specify a Pino-compatible `DestinationStream`. ```APIDOC ## new Logger(config) ### Description Instantiates a Pino-backed logger. Pass `enabled: false` to get a no-op abstract logger that accepts every API call but produces no output — ideal for test environments. The `destination` option accepts any Pino-compatible `DestinationStream` and replaces Pino's second constructor argument. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **config** (object) - Required - Configuration object for the logger. - **enabled** (boolean) - Optional - Whether the logger is enabled. Defaults to `true`. - **level** (string) - Optional - The logging level. Defaults to `'info'`. - **name** (string) - Optional - The name of the logger. - **destination** (DestinationStream) - Optional - A Pino-compatible `DestinationStream`. ### Request Example ```ts import { Logger, destinations } from '@adonisjs/logger' // Basic JSON logger to stdout const logger = new Logger({ enabled: true, level: 'info', name: 'myapp' }) logger.info('server started') // Logger with merging object logger.info({ requestId: 'abc-123', method: 'GET' }, 'incoming request') // sprintf-style interpolation logger.info('user %s logged in from %s', 'alice', '192.168.1.1') // Pretty-print destination (requires pino-pretty peer dep) const prettyLogger = new Logger({ enabled: true, level: 'debug', destination: await destinations.pretty({ colorize: true, translateTime: 'SYS:standard' }), }) prettyLogger.debug('pretty output active') // Disabled (no-op) logger for tests const silent = new Logger({ enabled: false }) console.log(silent.isEnabled) // false console.log(silent.level) // 'info' ``` ### Response #### Success Response (200) Returns an instance of the Logger class. #### Response Example ```json { "instance": "Logger" } ``` ``` -------------------------------- ### Create Basic JSON Logger Instance Source: https://context7.com/adonisjs/logger/llms.txt Instantiate a basic JSON logger to stdout. Pass `enabled: false` for a no-op logger in test environments. The `destination` option can be used to specify a Pino-compatible stream. ```typescript import { Logger, destinations } from '@adonisjs/logger' // Basic JSON logger to stdout const logger = new Logger({ enabled: true, level: 'info', name: 'myapp' }) logger.info('server started') // → {"level":30,"time":1700000000000,"pid":1,"hostname":"host","name":"myapp","msg":"server started"} ``` ```typescript // Logger with merging object logger.info({ requestId: 'abc-123', method: 'GET' }, 'incoming request') // → {"level":30,...,"requestId":"abc-123","method":"GET","msg":"incoming request"} ``` ```typescript // sprintf-style interpolation logger.info('user %s logged in from %s', 'alice', '192.168.1.1') // → {"level":30,...,"msg":"user alice logged in from 192.168.1.1"} ``` ```typescript // Pretty-print destination (requires pino-pretty peer dep) const prettyLogger = new Logger({ enabled: true, level: 'debug', destination: await destinations.pretty({ colorize: true, translateTime: 'SYS:standard' }), }) prettyLogger.debug('pretty output active') // → [12:00:00.000] DEBUG: pretty output active ``` ```typescript // Disabled (no-op) logger for tests const silent = new Logger({ enabled: false }) silent.fatal('this is suppressed') // no output, no error console.log(silent.isEnabled) // false console.log(silent.level) // 'info' ``` -------------------------------- ### Create File Transport Target with `targets.file()` Source: https://context7.com/adonisjs/logger/llms.txt Constructs a `TransportTargetOptions` object for Pino's built-in `pino/file` transport. Use `destination` to specify a file path or file descriptor. Omitting `destination` defaults to stdout. ```typescript import { targets } from '@adonisjs/logger' // stdout const stdoutTarget = targets.file() // { target: 'pino/file', level: undefined, options: {} } // Specific file path with directory creation const fileTarget = targets.file({ destination: '/tmp/app.log', mkdir: true, append: true }, 'info') // { target: 'pino/file', level: 'info', options: { destination: '/tmp/app.log', mkdir: true, append: true } } // stderr (fd 2) const stderrTarget = targets.file({ destination: 2 }, 'error') // { target: 'pino/file', level: 'error', options: { destination: 2 } } ``` -------------------------------- ### targets.file(options?, level?) — File transport target descriptor Source: https://context7.com/adonisjs/logger/llms.txt Creates a Pino file transport target configuration. Allows specifying a file path for logs or defaulting to stdout. Supports options for directory creation and log appending. ```APIDOC ## `targets.file(options?, level?)` — File transport target descriptor Constructs a `TransportTargetOptions` object pointing to Pino's built-in `pino/file` transport. Use `destination` to specify a file path or file descriptor. Omitting `destination` defaults to stdout (fd 1). ### Parameters - **options** (`object`, optional): Configuration options for the file transport. - **destination** (`string | number`, optional): The file path or file descriptor (e.g., `1` for stdout, `2` for stderr). Defaults to stdout. - **mkdir** (`boolean`, optional): If `true`, creates the destination directory if it doesn't exist. - **append** (`boolean`, optional): If `true`, appends logs to the file instead of overwriting. - **level** (`string`, optional): The minimum log level for this target. ### Examples ```ts import { targets } from '@adonisjs/logger' // stdout const stdoutTarget = targets.file() // { target: 'pino/file', level: undefined, options: {} } // Specific file path with directory creation const fileTarget = targets.file({ destination: '/tmp/app.log', mkdir: true, append: true }, 'info') // { target: 'pino/file', level: 'info', options: { destination: '/tmp/app.log', mkdir: true, append: true } } // stderr (fd 2) const stderrTarget = targets.file({ destination: 2 }, 'error') // { target: 'pino/file', level: 'error', options: { destination: 2 } } ``` ``` -------------------------------- ### Create Unmanaged Logger Instance Source: https://context7.com/adonisjs/logger/llms.txt Employ `manager.create(config, pino?)` to generate a new `Logger` instance without caching. This is suitable for ephemeral or one-off logging tasks. You can optionally pass an existing Pino instance. ```typescript import { LoggerManager, defineConfig, destination } from '@adonisjs/logger' const manager = new LoggerManager(defineConfig({ default: 'main', loggers: { main: { enabled: true, level: 'info' } }, })) // Ephemeral logger writing to stderr const errLogger = manager.create({ enabled: true, level: 'error', destination: destination(2), // fd 2 = stderr }) erLogger.error('critical failure reported to stderr') // Pass an existing pino instance import pino from 'pino' const pinoInst = pino({ level: 'warn' }) const wrapped = manager.create({ enabled: true, level: 'warn' }, pinoInst) wrapped.warn('wrapping existing pino instance') ``` -------------------------------- ### Create Synchronous Pretty-Print Destination Stream Source: https://context7.com/adonisjs/logger/llms.txt Asynchronously imports and instantiates a `pino-pretty` destination stream for in-process pretty-printing. This is an alternative to using transport targets and runs pretty-printing on the main thread. ```typescript import { Logger, destinations } from '@adonisjs/logger' const logger = new Logger({ enabled: true, level: 'debug', destination: await destinations.pretty({ colorize: true, translateTime: 'SYS:standard', ignore: 'pid,hostname', }), }) logger.info('in-process pretty printing') // [2024-01-15 12:00:00.000 +0000] INFO: in-process pretty printing logger.error({ err: new Error('oops') }, 'something failed') // [2024-01-15 12:00:00.001 +0000] ERROR: something failed // err: { // "type": "Error", // "message": "oops", // ... // } ``` -------------------------------- ### Use LoggerFactory for Testing Source: https://context7.com/adonisjs/logger/llms.txt Create logger instances in tests using `LoggerFactory`. Use `pushLogsTo(array)` to capture log output for assertions. ```typescript import { LoggerFactory } from '@adonisjs/logger/factories' // Disabled logger (default) – useful as a no-op in unit tests const noop = new LoggerFactory().create() console.log(noop.isEnabled) // false // Enabled logger with custom config const logger = new LoggerFactory().merge({ enabled: true, level: 'debug' }).create() logger.debug('works') // writes to stdout // Capture logs into an array for assertions const logs: string[] = [] const testLogger = new LoggerFactory() .pushLogsTo(logs) .merge({ enabled: true, level: 'trace' }) .create() testLogger.info({ userId: 1 }, 'user created') testLogger.error({ err: new Error('fail') }, 'operation failed') console.log(JSON.parse(logs[0])) // { level: 30, userId: 1, msg: 'user created', ... } console.log(JSON.parse(logs[1]).msg) // 'operation failed' ``` -------------------------------- ### targets() — Chainable transport target builder Source: https://context7.com/adonisjs/logger/llms.txt Builds an array of Pino transport targets. Supports conditional and unconditional additions, accepting values or lazy factory functions for flexible log routing. ```APIDOC ## `targets()` — Chainable transport target builder Returns a `Targets` builder that composes a `TransportTargetOptions[]` array for Pino's `transport.targets`. Supports unconditional (`push`), conditional (`pushIf`), and inverse-conditional (`pushUnless`) additions, each accepting a value or a lazy factory function. ### Example Usage ```ts import { targets, defineConfig, LoggerManager } from '@adonisjs/logger' const isDev = process.env.NODE_ENV === 'development' const isProd = process.env.NODE_ENV === 'production' const transportTargets = targets() // Always write to stdout (pino/file with no destination = stdout) .push(targets.file()) // Pretty-print only in development .pushIf(isDev, targets.pretty({ colorize: true, singleLine: false })) // Write to a file only in production (lazy factory, only evaluated when condition is true) .pushUnless(isDev, () => targets.file({ destination: '/var/log/myapp.log', mkdir: true, append: true }, 'warn')) .toArray() console.log(transportTargets) // In dev: [{ target: 'pino/file', ... }, { target: 'pino-pretty', ... }] // In prod: [{ target: 'pino/file', ... }, { target: 'pino/file', destination: '/var/log/myapp.log', level: 'warn', ... }] const config = defineConfig({ default: 'main', loggers: { main: { enabled: true, level: 'debug', transport: { targets: transportTargets } }, }, }) const manager = new LoggerManager(config) manager.info('transport configured') ``` ``` -------------------------------- ### Create Pretty-Print Transport Target with `targets.pretty()` Source: https://context7.com/adonisjs/logger/llms.txt Constructs a `TransportTargetOptions` object for the `pino-pretty` transport. Accepts `PrettyTargetOptions` for customization like colorization and timestamp formatting. This is suitable for development environments. ```typescript import { targets } from '@adonisjs/logger' // Minimal pretty target const basic = targets.pretty() // { target: 'pino-pretty', level: undefined, options: {} } // Colorized, human-readable timestamps, single-line output const devTarget = targets.pretty( { colorize: true, translateTime: 'SYS:HH:MM:ss', singleLine: false, ignore: 'pid,hostname', messageFormat: '{levelLabel} [{name}] {msg}', }, 'trace' ) // { // target: 'pino-pretty', // level: 'trace', // options: { colorize: true, translateTime: 'SYS:HH:MM:ss', ... } // } ``` -------------------------------- ### targets.pretty(options?, level?) — Pretty-print transport target descriptor Source: https://context7.com/adonisjs/logger/llms.txt Generates a transport target configuration for `pino-pretty`. Enables human-readable log output with options for colorization, timestamp formatting, and message customization. ```APIDOC ## `targets.pretty(options?, level?)` — Pretty-print transport target descriptor Constructs a `TransportTargetOptions` object for the `pino-pretty` transport (optional peer dependency). Accepts the full `PrettyTargetOptions` surface including colorization, time translation, message formatting, and key filtering. ### Parameters - **options** (`object`, optional): Configuration options for `pino-pretty`. - **colorize** (`boolean`): Enables colorized output. - **translateTime** (`string | boolean`): Formats timestamps. Accepts formats like 'SYS:HH:MM:ss' or 'standard'. - **singleLine** (`boolean`): Outputs logs on a single line. - **ignore** (`string`): Comma-separated list of keys to ignore. - **messageFormat** (`string`): A format string for the log message. - (Other `pino-pretty` options are also supported) - **level** (`string`, optional): The minimum log level for this target. ### Examples ```ts import { targets } from '@adonisjs/logger' // Minimal pretty target const basic = targets.pretty() // { target: 'pino-pretty', level: undefined, options: {} } // Colorized, human-readable timestamps, single-line output const devTarget = targets.pretty( { colorize: true, translateTime: 'SYS:HH:MM:ss', singleLine: false, ignore: 'pid,hostname', messageFormat: '{levelLabel} [{name}] {msg}', }, 'trace' ) // { // target: 'pino-pretty', // level: 'trace', // options: { colorize: true, translateTime: 'SYS:HH:MM:ss', ... } // } ``` ``` -------------------------------- ### destinations.pretty(options?) — Synchronous pino-pretty destination stream Source: https://context7.com/adonisjs/logger/llms.txt Provides an in-process pretty-print destination stream for the logger. This is an alternative to using `pino-pretty` as a transport target, running the formatting directly in the main thread. ```APIDOC ## `destinations.pretty(options?)` — Synchronous pino-pretty destination stream Asynchronously imports and instantiates a `pino-pretty` destination as a `DestinationStream`, suitable for passing directly to the `destination` option of `new Logger(...)`. This approach (vs. transport targets) runs pretty-printing in the main thread. ### Parameters - **options** (`object`): Configuration options for `pino-pretty`. - **colorize** (`boolean`): Enables colorized output. - **translateTime** (`string`): Formats timestamps. Accepts formats like 'standard'. - **ignore** (`string`): Comma-separated list of keys to ignore. - (Other `pino-pretty` options are also supported) ### Example Usage ```ts import { Logger, destinations } from '@adonisjs/logger' const logger = new Logger({ enabled: true, level: 'debug', destination: await destinations.pretty({ colorize: true, translateTime: 'SYS:standard', ignore: 'pid,hostname', }), }) logger.info('in-process pretty printing') // [2024-01-15 12:00:00.000 +0000] INFO: in-process pretty printing logger.error({ err: new Error('oops') }, 'something failed') // [2024-01-15 12:00:00.001 +0000] ERROR: something failed // err: { // "type": "Error", // "message": "oops", // ... // } ``` ``` -------------------------------- ### Timestamp Configuration Source: https://context7.com/adonisjs/logger/llms.txt Configure the timestamp format for log entries. Options include 'iso', 'unix', 'epoch', disabling timestamps with `false`, or providing a custom function. ```APIDOC ## Timestamp configuration — `iso`, `unix`, `epoch`, boolean, or custom function The `timestamp` config key accepts a keyword (`'iso'` | `'unix'` | `'epoch'`), `false` to disable timestamps entirely, or an arbitrary function returning a raw JSON fragment string. ```ts import { Logger } from '@adonisjs/logger' // ISO 8601 timestamp string const isoLogger = new Logger({ enabled: true, timestamp: 'iso' }) isoLogger.info('test') // → {"level":30,"time":"2024-01-15T12:00:00.000Z","msg":"test"} // Unix seconds (integer) const unixLogger = new Logger({ enabled: true, timestamp: 'unix' }) unixLogger.info('test') // → {"level":30,"time":1705320000,"msg":"test"} // Epoch milliseconds (default pino behavior, keyword form) const epochLogger = new Logger({ enabled: true, timestamp: 'epoch' }) // Disable timestamp field entirely const noTimeLogger = new Logger({ enabled: true, timestamp: false }) noTimeLogger.info('test') // → {"level":30,"msg":"test"} // Custom key name const customLogger = new Logger({ enabled: true, timestamp: () => `,"eventTime":${Date.now()}`, }) customLogger.info('test') // → {"level":30,"eventTime":1705320000000,"msg":"test"} ``` ``` -------------------------------- ### logger.trace / debug / info / warn / error / fatal / silent Source: https://context7.com/adonisjs/logger/llms.txt These methods allow you to log messages at specific levels. Each method accepts either a message string with optional interpolation values or a merging object followed by a message and optional values. The levels correspond to Pino's standard numeric values. ```APIDOC ## logger.trace / debug / info / warn / error / fatal / silent ### Description Each method accepts either `(message, ...values)` or `(mergingObject, message, ...values)`. Levels map to Pino's standard numeric values: trace=10, debug=20, info=30, warn=40, error=50, fatal=60. The `silent` method exists for API completeness but produces no output. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **message** (string) - The log message. - **values** (...any) - Optional - Values for interpolation in the message. - **mergingObject** (object) - Optional - An object to merge with the log record. ### Request Example ```ts import { Logger } from '@adonisjs/logger' import { Writable } from 'node:stream' const messages: string[] = [] const dest = new Writable() dest.write = (chunk) => { messages.push(chunk.toString().trim()); return true } const logger = new Logger({ enabled: true, level: 'trace', destination: dest }) logger.trace('entering function') logger.debug({ userId: 42 }, 'fetching user') logger.info('request processed in %d ms', 120) logger.warn({ retries: 3 }, 'upstream slow') logger.error({ err: new Error('timeout') }, 'request failed') logger.fatal('unrecoverable error, shutting down') console.log(JSON.parse(messages[0])) // { level: 10, msg: 'entering function', ... } console.log(JSON.parse(messages[1])) // { level: 20, userId: 42, msg: 'fetching user', ... } console.log(JSON.parse(messages[2])) // { level: 30, msg: 'request processed in 120 ms', ... } ``` ### Response #### Success Response (200) Logs the message to the configured destination. #### Response Example None (output is streamed to destination) ``` -------------------------------- ### logger.child(bindings, options?) Source: https://context7.com/adonisjs/logger/llms.txt Creates a new Logger instance that inherits the parent's stream and configuration but includes the provided bindings on every log entry. It can optionally override the log level or apply redaction rules independently. ```APIDOC ## `logger.child(bindings, options?)` — Create a child logger Returns a new `Logger` wrapping a Pino child logger that inherits the parent's stream and config but includes the provided `bindings` on every log entry. Optionally override `level` or apply `redact` rules on the child independently. ```ts import { Logger } from '@adonisjs/logger' const logger = new Logger({ enabled: true, level: 'info', name: 'api' }) // Attach request-scoped context to every log line const reqLogger = logger.child({ requestId: 'req-001', route: '/users' }) reqLogger.info('handler invoked') // → {"level":30,"name":"api","requestId":"req-001","route":"/users","msg":"handler invoked",...} // Child with elevated level and redaction const safeLogger = logger.child({ service: 'auth' }, { level: 'debug', redact: ['password', 'token'] }) safeLogger.debug({ password: 'hunter2', token: 'xyz' }, 'login attempt') // → {"level":20,"service":"auth","password":"[Redacted]","token":"[Redacted]","msg":"login attempt",...} // Disabled logger returns itself unchanged const noop = new Logger({ enabled: false }) console.log(noop.child({ x: 1 }) === noop) // true ``` ``` -------------------------------- ### Configure Logger Timestamps Source: https://context7.com/adonisjs/logger/llms.txt Set the timestamp format for log entries. Accepts keywords like 'iso', 'unix', 'epoch', boolean `false` to disable, or a custom function. ```typescript import { Logger } from '@adonisjs/logger' // ISO 8601 timestamp string const isoLogger = new Logger({ enabled: true, timestamp: 'iso' }) isoLogger.info('test') // → {"level":30,"time":"2024-01-15T12:00:00.000Z","msg":"test"} ``` ```typescript // Unix seconds (integer) const unixLogger = new Logger({ enabled: true, timestamp: 'unix' }) unixLogger.info('test') // → {"level":30,"time":1705320000,"msg":"test"} ``` ```typescript // Epoch milliseconds (default pino behavior, keyword form) const epochLogger = new Logger({ enabled: true, timestamp: 'epoch' }) ``` ```typescript // Disable timestamp field entirely const noTimeLogger = new Logger({ enabled: true, timestamp: false }) noTimeLogger.info('test') // → {"level":30,"msg":"test"} ``` ```typescript // Custom key name const customLogger = new Logger({ enabled: true, timestamp: () => `,"eventTime":${Date.now()}`, }) customLogger.info('test') // → {"level":30,"eventTime":1705320000000,"msg":"test"} ``` -------------------------------- ### Pino Re-exports Source: https://context7.com/adonisjs/logger/llms.txt Direct re-exports of Pino primitives like `transport`, `destination`, `multistream`, `stdSerializers`, and `stdTimeFunctions` for common logging operations. ```APIDOC ## Pino re-exports — `transport`, `destination`, `multistream`, `stdSerializers`, `stdTimeFunctions` Direct re-exports of Pino primitives so consumers do not need to install or import Pino separately for common operations like creating file destinations, multi-streams, or using standard serializers. ```ts import { transport, destination, multistream, stdSerializers, stdTimeFunctions, Logger, } from '@adonisjs/logger' // Write to a file using pino destination const fileDest = destination({ dest: '/var/log/app.log', sync: false }) const fileLogger = new Logger({ enabled: true, level: 'info', destination: fileDest }) // Fan-out to multiple streams with different levels const streams = multistream([ { stream: destination(1), level: 'info' }, // stdout: info+ { stream: destination(2), level: 'error' }, // stderr: error+ ]) const multiLogger = new Logger({ enabled: true, level: 'info', destination: streams }) // Use standard serializers for req/res/err objects const httpLogger = new Logger({ enabled: true, level: 'info', serializers: { req: stdSerializers.req, res: stdSerializers.res, err: stdSerializers.err, }, }) httpLogger.info({ req: incomingMessage }, 'HTTP request') // ISO timestamps via stdTimeFunctions const isoLogger = new Logger({ enabled: true, timestamp: stdTimeFunctions.isoTime, }) ``` ``` -------------------------------- ### Create a child logger with bindings Source: https://context7.com/adonisjs/logger/llms.txt Use logger.child to create a new logger instance that inherits parent streams and config but adds custom bindings to every log entry. Optionally, override the level or apply redaction rules independently for the child logger. ```typescript import { Logger } from '@adonisjs/logger' const logger = new Logger({ enabled: true, level: 'info', name: 'api' }) // Attach request-scoped context to every log line const reqLogger = logger.child({ requestId: 'req-001', route: '/users' }) reqLogger.info('handler invoked') // → {"level":30,"name":"api","requestId":"req-001","route":"/users","msg":"handler invoked",...} // Child with elevated level and redaction const safeLogger = logger.child({ service: 'auth' }, { level: 'debug', redact: ['password', 'token'] }) safeLogger.debug({ password: 'hunter2', token: 'xyz' }, 'login attempt') // → {"level":20,"service":"auth","password":"[Redacted]","token":"[Redacted]","msg":"login attempt",...} // Disabled logger returns itself unchanged const noop = new Logger({ enabled: false }) console.log(noop.child({ x: 1 }) === noop) // true ``` -------------------------------- ### manager.use(name?) Source: https://context7.com/adonisjs/logger/llms.txt Retrieves a named or the default logger instance. Returns a typed `Logger` instance for a registered logger name, or the default logger when called without arguments. Instances are cached, so repeated calls return the same object. ```APIDOC ## manager.use(name?) Returns a typed `Logger` instance for a registered logger name, or the default logger when called with no arguments. Instances are cached; repeated calls return the same object. ```ts import { LoggerManager, defineConfig } from '@adonisjs/logger' const manager = new LoggerManager(defineConfig({ default: 'web', loggers: { web: { enabled: true, level: 'info' }, queue: { enabled: true, level: 'debug' }, }, })) const webLogger = manager.use('web') // Logger<{ enabled: true, level: 'info' }> const queueLogger = manager.use('queue') // Logger<{ enabled: true, level: 'debug' }> const defaultLog = manager.use() // Logger (default = 'web') webLogger.info('HTTP server listening on :3333') queueLogger.debug({ jobId: 'job-42' }, 'processing job') ``` ``` -------------------------------- ### Use Level-Specific Log Methods Source: https://context7.com/adonisjs/logger/llms.txt Each log method accepts either `(message, ...values)` or `(mergingObject, message, ...values)`. Levels map to Pino's standard numeric values. The `silent` method exists for API completeness but produces no output. ```typescript import { Logger } from '@adonisjs/logger' import { Writable } from 'node:stream' const messages: string[] = [] const dest = new Writable() dest.write = (chunk) => { messages.push(chunk.toString().trim()); return true } const logger = new Logger({ enabled: true, level: 'trace', destination: dest }) logger.trace('entering function') logger.debug({ userId: 42 }, 'fetching user') logger.info('request processed in %d ms', 120) logger.warn({ retries: 3 }, 'upstream slow') logger.error({ err: new Error('timeout') }, 'request failed') logger.fatal('unrecoverable error, shutting down') console.log(JSON.parse(messages[0])) // { level: 10, msg: 'entering function', ... } console.log(JSON.parse(messages[1])) // { level: 20, userId: 42, msg: 'fetching user', ... } console.log(JSON.parse(messages[2])) // { level: 30, msg: 'request processed in 120 ms', ... } ``` -------------------------------- ### logger.log(level, ...) Source: https://context7.com/adonisjs/logger/llms.txt This method allows for dynamic logging at any named level, including custom levels. It's useful when the logging level is determined at runtime or when using user-defined level names. ```APIDOC ## logger.log(level, ...) ### Description Emits a log entry at any named level, including custom levels defined via `customLevels`. Useful when the level is determined at runtime or when logging with user-defined level names. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **level** (string) - Required - The name of the logging level (e.g., 'info', 'warn', 'audit'). - **message** (string) - The log message. - **values** (...any) - Optional - Values for interpolation in the message. - **mergingObject** (object) - Optional - An object to merge with the log record. ### Request Example ```ts import { Logger } from '@adonisjs/logger' const logger = new Logger({ enabled: true, level: 'trace', customLevels: { audit: 35, verbose: 15 }, }) // Built-in level by name logger.log('warn', 'low disk space') // Custom level logger.log('audit', { userId: 7, action: 'DELETE' }, 'resource removed') // → {"level":35,"userId":7,"action":"DELETE","msg":"resource removed",...} logger.log('verbose', 'detailed diagnostic info') // → {"level":15,"msg":"detailed diagnostic info",...} ``` ### Response #### Success Response (200) Logs the message to the configured destination at the specified level. #### Response Example None (output is streamed to destination) ``` -------------------------------- ### Manage Multiple Named Loggers with LoggerManager Source: https://context7.com/adonisjs/logger/llms.txt Instantiate `LoggerManager` with a configuration object. Log directly via the manager (proxies to the default logger) or retrieve named logger instances, which are lazily created and cached. ```typescript import { LoggerManager, defineConfig } from '@adonisjs/logger' const config = defineConfig({ default: 'main', loggers: { main: { enabled: true, level: 'info', name: 'main' }, audit: { enabled: true, level: 'info', name: 'audit' }, debug: { enabled: true, level: 'trace', name: 'debug' }, }, }) const manager = new LoggerManager(config) // Log directly via the manager (uses default logger) manager.info('application booted') // Retrieve a named logger (cached on subsequent calls) const auditLogger = manager.use('audit') auditLogger.info({ userId: 99, action: 'login' }, 'audit event') // Type-safe: TypeScript knows the config shape of each logger const debugLogger = manager.use('debug') debugLogger.trace('verbose tracing enabled') // Verify caching console.log(manager.use('audit') === manager.use('audit')) // true // Create an unmanaged (uncached) logger on demand const tempLogger = manager.create({ enabled: true, level: 'warn' }) tempLogger.warn('temporary logger, not cached') ``` -------------------------------- ### LoggerFactory for Testing Source: https://context7.com/adonisjs/logger/llms.txt Utilize `LoggerFactory` from `@adonisjs/logger/factories` to create logger instances in tests, with options to capture logs for assertions. ```APIDOC ## `LoggerFactory` — Test utility for creating logger instances Exported from `@adonisjs/logger/factories`, `LoggerFactory` provides a fluent builder for constructing `Logger` instances in tests. Use `pushLogsTo(array)` to capture all log output as raw JSON strings for assertion. ```ts import { LoggerFactory} from '@adonisjs/logger/factories' // Disabled logger (default) – useful as a no-op in unit tests const noop = new LoggerFactory().create() console.log(noop.isEnabled) // false // Enabled logger with custom config const logger = new LoggerFactory().merge({ enabled: true, level: 'debug' }).create() logger.debug('works') // writes to stdout // Capture logs into an array for assertions const logs: string[] = [] const testLogger = new LoggerFactory() .pushLogsTo(logs) .merge({ enabled: true, level: 'trace' }) .create() testLogger.info({ userId: 1 }, 'user created') testLogger.error({ err: new Error('fail') }, 'operation failed') console.log(JSON.parse(logs[0])) // { level: 30, userId: 1, msg: 'user created', ... } console.log(JSON.parse(logs[1]).msg) // 'operation failed' ``` ``` -------------------------------- ### Perform Dynamic Level Logging Source: https://context7.com/adonisjs/logger/llms.txt Emits a log entry at any named level, including custom levels. Useful when the level is determined at runtime or when logging with user-defined level names. ```typescript import { Logger } from '@adonisjs/logger' const logger = new Logger({ enabled: true, level: 'trace', customLevels: { audit: 35, verbose: 15 }, }) // Built-in level by name logger.log('warn', 'low disk space') // Custom level logger.log('audit', { userId: 7, action: 'DELETE' }, 'resource removed') // → {"level":35,"userId":7,"action":"DELETE","msg":"resource removed",...} logger.log('verbose', 'detailed diagnostic info') // → {"level":15,"msg":"detailed diagnostic info",...} ``` -------------------------------- ### Configure Custom Log Formatters Source: https://context7.com/adonisjs/logger/llms.txt Reshape the level field and log object using `formatters.level` and `formatters.log`. Useful for adapting output to third-party log ingestion formats. ```typescript import { Logger } from '@adonisjs/logger' // Rename the level field and use a string label instead of a number const logger = new Logger({ enabled: true, level: 'trace', formatters: { level(label, number) { return { severity: label.toUpperCase(), levelCode: number } }, log(log) { // Add a custom field to every log entry return { ...log, service: 'payments-api', env: process.env.NODE_ENV } }, }, }) logger.info({ orderId: 'ord-001' }, 'order created') // → {"severity":"INFO","levelCode":30,"time":...,"orderId":"ord-001","service":"payments-api","env":"production","msg":"order created"} ``` -------------------------------- ### logger.bindings() Source: https://context7.com/adonisjs/logger/llms.txt Retrieves the default bindings object associated with the logger, such as its name or custom child bindings. Returns an empty object for disabled loggers. ```APIDOC ## `logger.bindings()` — Retrieve current logger bindings Returns the default bindings object attached to the logger (e.g., `name`, or custom child bindings). Returns an empty object for disabled loggers. ```ts import { Logger } from '@adonisjs/logger' const logger = new Logger({ enabled: true, name: 'payments', level: 'info' }) console.log(logger.bindings()) // { name: 'payments' } const child = logger.child({ region: 'us-east-1' }) console.log(child.bindings()) // { name: 'payments', region: 'us-east-1' } const noop = new Logger({ enabled: false }) console.log(noop.bindings()) // {} ``` ``` -------------------------------- ### LoggerManager Source: https://context7.com/adonisjs/logger/llms.txt Manages multiple named loggers, extending the base Logger class. All logging methods are available directly on the manager, proxied to the default logger. Named logger instances are created lazily on first access and cached indefinitely. `use()` without arguments returns the default logger. ```APIDOC ## new LoggerManager(config) `LoggerManager` extends `Logger`, so all logging methods are available directly on the manager (proxied to the default logger). Named logger instances are created lazily on first access and cached forever. `use()` without arguments returns the default logger. ```ts import { LoggerManager, defineConfig } from '@adonisjs/logger' const config = defineConfig({ default: 'main', loggers: { main: { enabled: true, level: 'info', name: 'main' }, audit: { enabled: true, level: 'info', name: 'audit' }, debug: { enabled: true, level: 'trace', name: 'debug' }, }, }) const manager = new LoggerManager(config) // Log directly via the manager (uses default logger) manager.info('application booted') // Retrieve a named logger (cached on subsequent calls) const auditLogger = manager.use('audit') auditLogger.info({ userId: 99, action: 'login' }, 'audit event') // Type-safe: TypeScript knows the config shape of each logger const debugLogger = manager.use('debug') debugLogger.trace('verbose tracing enabled') // Verify caching console.log(manager.use('audit') === manager.use('audit')) // true // Create an unmanaged (uncached) logger on demand const tempLogger = manager.create({ enabled: true, level: 'warn' }) tempLogger.warn('temporary logger, not cached') ``` ``` -------------------------------- ### Pino Re-exports for Logging Operations Source: https://context7.com/adonisjs/logger/llms.txt Utilize re-exported Pino primitives like `transport`, `destination`, `multistream`, `stdSerializers`, and `stdTimeFunctions` for common logging tasks without direct Pino dependency. ```typescript import { transport, destination, multistream, stdSerializers, stdTimeFunctions, Logger, } from '@adonisjs/logger' // Write to a file using pino destination const fileDest = destination({ dest: '/var/log/app.log', sync: false }) const fileLogger = new Logger({ enabled: true, level: 'info', destination: fileDest }) // Fan-out to multiple streams with different levels const streams = multistream([ { stream: destination(1), level: 'info' }, // stdout: info+ { stream: destination(2), level: 'error' }, // stderr: error+ ]) const multiLogger = new Logger({ enabled: true, level: 'info', destination: streams }) // Use standard serializers for req/res/err objects const httpLogger = new Logger({ enabled: true, level: 'info', serializers: { req: stdSerializers.req, res: stdSerializers.res, err: stdSerializers.err, }, }) httpLogger.info({ req: incomingMessage }, 'HTTP request') // ISO timestamps via stdTimeFunctions const isoLogger = new Logger({ enabled: true, timestamp: stdTimeFunctions.isoTime, }) ``` -------------------------------- ### Custom Formatters Source: https://context7.com/adonisjs/logger/llms.txt Use the `formatters` config object to reshape the level field and log object before serialization, adapting output for third-party log ingestion. ```APIDOC ## Custom formatters — `formatters.level` and `formatters.log` The `formatters` config object (inherited from Pino) allows reshaping the level field and any log object before serialization. This is useful for adapting output to third-party log ingestion formats. ```ts import { Logger } from '@adonisjs/logger' // Rename the level field and use a string label instead of a number const logger = new Logger({ enabled: true, level: 'trace', formatters: { level(label, number) { return { severity: label.toUpperCase(), levelCode: number } }, log(log) { // Add a custom field to every log entry return { ...log, service: 'payments-api', env: process.env.NODE_ENV } }, }, }) logger.info({ orderId: 'ord-001' }, 'order created') // → {"severity":"INFO","levelCode":30,"time":...,"orderId":"ord-001","service":"payments-api","env":"production","msg":"order created"} ``` ``` -------------------------------- ### Define Type-Safe Logger Configuration Source: https://context7.com/adonisjs/logger/llms.txt Use `defineConfig` to validate and create a `LoggerManagerConfig` object. It automatically inherits the top-level level for transport targets without an explicit level. Throws `RuntimeException` for missing or inconsistent configuration. ```typescript import { defineConfig, targets } from '@adonisjs/logger' const config = defineConfig({ default: 'main', loggers: { main: { enabled: true, level: 'info', transport: { targets: targets() .pushIf(process.env.NODE_ENV === 'development', targets.pretty({ colorize: true })) .pushUnless(process.env.NODE_ENV === 'development', targets.file({ destination: '/var/log/app.log', mkdir: true })) .toArray(), }, }, audit: { enabled: true, level: 'info', transport: { targets: targets().push(targets.file({ destination: '/var/log/audit.log' })).toArray(), }, }, }, }) ```