Skip to content

Cheat Sheet ​

A quick reference for the most commonly used LogLayer APIs.

Setup ​

typescript
import { LogLayer, ConsoleTransport } from 'loglayer'

const log = new LogLayer({
  transport: new ConsoleTransport({
    logger: console
  })
})

See Getting Started for full setup instructions and Transports for all available transports.

Log Messages ​

typescript
log.info('User logged in')
log.warn('Disk space low')
log.error('Connection failed')
log.debug('Cache hit for key abc')
log.trace('Entering function parse()')
log.fatal('System out of memory')

// Multiple parameters
log.info('User', userId, 'performed action', action)

See Basic Logging for more details.

Tagged Template Syntax ​

typescript
const userId = '123'
const duration = 250

// Tagged template syntax — direct interpolation
log.info`User ${userId} logged in`
log.warn`Request took ${duration}ms`

// Combine with fluent chain
log.withMetadata({ env: 'production' }).info`Processing ${count} items`

Note: For structured data, use withMetadata(). Objects in templates become "[object Object]".

Metadata (Per-Log Data) ​

Metadata is attached to a single log entry only.

typescript
log.withMetadata({ userId: '123', duration: 42 }).info('Request handled')
json
{ "msg": "Request handled", "userId": "123", "duration": 42 }

Log metadata without a message:

typescript
log.metadataOnly({ status: 'healthy', uptime: 3600 })

See Metadata for dedicated fields and muting.

Context (Persistent Data) ​

Context persists across all subsequent log entries.

typescript
log.withContext({ requestId: 'abc-123', region: 'us-east' })

log.info('Starting')   // includes requestId + region
log.info('Done')        // still includes requestId + region
json
{ "msg": "Starting", "requestId": "abc-123", "region": "us-east" }

Manage context:

typescript
log.getContext()                    // get current context
log.clearContext()                  // clear all context
log.clearContext('requestId')       // clear one key
log.clearContext(['key1', 'key2'])  // clear specific keys

See Context for dedicated fields and context managers.

Error Handling ​

typescript
// Error with a message
log.withError(new Error('timeout')).error('DB query failed')

// Error-only (default level: error)
log.errorOnly(new Error('timeout'))

// Error-only with custom level
log.errorOnly(new Error('timeout'), { logLevel: LogLevel.warn })

// Combine error + metadata
log
  .withMetadata({ query: 'SELECT ...', attempt: 3 })
  .withError(new Error('timeout'))
  .error('DB query failed')

See Error Handling for serialization and configuration options.

Lazy Evaluation ​

Defer expensive computations until log time. Callbacks are skipped when the log level is disabled.

typescript
import { lazy } from 'loglayer'

// Context: re-evaluated on every log call
log.withContext({
  memoryUsage: lazy(() => process.memoryUsage().heapUsed),
})

// Metadata: evaluated once for that log entry
log.withMetadata({
  data: lazy(() => JSON.stringify(largeObject)),
}).debug('Processing result')

// metadataOnly: same behavior
log.metadataOnly({
  status: lazy(() => getHealthStatus()),
})

// Async lazy (metadata only) — must be awaited
await log.withMetadata({
  result: lazy(async () => await fetchResult()),
}).info('Done')

await log.metadataOnly({
  result: lazy(async () => await fetchResult()),
})

See Lazy Evaluation for error handling, async details, and notes.

Chaining ​

typescript
log
  .withContext({ requestId: 'abc' })    // persists
  .withMetadata({ duration: 150 })      // single entry
  .withError(new Error('fail'))         // single entry
  .error('Request failed')

Child Loggers ​

typescript
const childLog = log.child()

// Child inherits config, context, plugins, and groups from parent
childLog.withContext({ module: 'auth' })
childLog.info('Token verified')  // has parent context + module

See Child Loggers for inheritance behavior and Context Managers for controlling context propagation.

Log Levels ​

typescript
import { LogLevel } from 'loglayer'

// Set minimum level (all levels >= warn are enabled)
log.setLevel(LogLevel.warn)

// Enable/disable individual levels
log.enableIndividualLevel(LogLevel.debug)
log.disableIndividualLevel(LogLevel.trace)

// Check if a level is enabled
log.isLevelEnabled(LogLevel.debug)  // true/false

// Enable/disable all logging
log.disableLogging()
log.enableLogging()

Level hierarchy: trace (10) < debug (20) < info (30) < warn (40) < error (50) < fatal (60)

See Adjusting Log Levels and Log Level Managers for parent-child propagation.

Message Prefixing ​

typescript
// Via config
const log = new LogLayer({
  prefix: '[MyApp]',
  transport: new ConsoleTransport({ logger: console })
})

// Via method (returns a child logger)
const prefixed = log.withPrefix('[Auth]')
prefixed.info('Login successful')
// Output: "[Auth] Login successful"

Multiple Transports ​

typescript
import { PinoTransport } from '@loglayer/transport-pino'
import { DatadogBrowserLogsTransport } from '@loglayer/transport-datadog-browser-logs'

const log = new LogLayer({
  transport: [
    new PinoTransport({ logger: pino(), id: 'pino' }),
    new DatadogBrowserLogsTransport({ logger: datadogLogs, id: 'datadog' })
  ]
})

See Multiple Transports for more details.

Groups ​

Route logs to specific transports by category:

typescript
const log = new LogLayer({
  transport: [
    new ConsoleTransport({ id: 'console', logger: console }),
    new DatadogTransport({ id: 'datadog', logger: datadog }),
  ],
  groups: {
    database: { transports: ['datadog'], level: 'error' },
  },
})

// Per-log tagging
log.withGroup('database').error('Connection lost')

// Persistent tagging (child logger)
const dbLogger = log.withGroup('database')
dbLogger.error('Pool exhausted')

// Runtime management
log.disableGroup('database')
log.setGroupLevel('database', 'debug')
log.setActiveGroups(['database'])

See Groups for ungroupedBehavior, env variable support, and full details.

Transport Management ​

typescript
// Add a transport
log.addTransport(new PinoTransport({ logger: pino(), id: 'pino' }))

// Remove a transport by ID
log.removeTransport('pino')

// Replace all transports
log.withFreshTransports(new ConsoleTransport({ logger: console }))

// Get underlying logger instance
const pinoInstance = log.getLoggerInstance<P.Pino>('pino')

See Transport Management for full details.

Plugin Management ​

typescript
log.addPlugins([myPlugin])
log.enablePlugin('my-plugin-id')
log.disablePlugin('my-plugin-id')
log.removePlugin('my-plugin-id')
log.withFreshPlugins([newPlugin])

See Plugins for available plugins and how to create your own.

Configuration Options ​

typescript
const log = new LogLayer({
  // Required
  transport: new ConsoleTransport({ logger: console }),

  // Message
  prefix: '[MyApp]',

  // Control
  enabled: true,

  // Error handling
  errorFieldName: 'err',                      // default: 'err'
  errorSerializer: (err) => ({ message: err.message, stack: err.stack }),
  copyMsgOnOnlyError: false,                   // copy error.message on errorOnly()
  errorFieldInMetadata: false,                 // nest error inside `metadata` field

  // Field naming (places data in dedicated fields instead of root)
  contextFieldName: 'context',
  metadataFieldName: 'metadata',

  // Muting
  muteContext: false,
  muteMetadata: false,

  // Plugins
  plugins: [myPlugin],

  // Groups
  groups: { database: { transports: ['transport-id'], level: 'error' } },
  activeGroups: null,                            // null = all groups active
  ungroupedBehavior: 'all',                       // 'all' | 'none' | string[]
})

See Configuration for full details on all options.

Muting ​

typescript
// Context
log.muteContext()
log.unMuteContext()

// Metadata
log.muteMetadata()
log.unMuteMetadata()

Testing ​

typescript
import { MockLogLayer } from 'loglayer'

// Drop-in replacement — all methods are no-ops
const log = new MockLogLayer()

See No-op / Mocking for advanced mock patterns with spies.

Raw Logging ​

Full control over all log parameters:

typescript
import { LogLevel } from 'loglayer'

log.raw({
  logLevel: LogLevel.error,
  messages: ['Operation failed'],
  metadata: { table: 'users' },
  rootData: { userId: 123 },         // always flat at root, ignores metadataFieldName
  error: new Error('timeout'),
  context: { requestId: 'req-1' }    // overrides stored context for this entry
})

See Basic Logging for context behavior and more examples.

Quick Reference Table ​

WhatMethodScope
Log a messagelog.info('msg')Single entry
Log with templatelog.info`User ${id} logged in`Single entry
Attach metadatalog.withMetadata({...}).info('msg')Single entry
Attach an errorlog.withError(err).error('msg')Single entry
Set contextlog.withContext({...})Persistent
Create childlog.child()New instance
Set log levellog.setLevel(LogLevel.warn)Persistent
Add prefixlog.withPrefix('[Tag]')New instance
Tag with grouplog.withGroup('db').error('msg')Single entry
Group child loggerlog.withGroup('db')New instance
Lazy valuelazy(() => expensiveCall())Per evaluation
Log error onlylog.errorOnly(err)Single entry
Log metadata onlylog.metadataOnly({...})Single entry
Raw log entrylog.raw({ logLevel, messages, metadata, rootData })Single entry
Flat emissionrootData: { userId: 123 } in raw()Bypasses metadataFieldName nesting
Mock for testsnew MockLogLayer()-
Wide events mixin@loglayer/mixin-wide-eventsAccumulate data across async boundaries and emit as single log entry (canonical log line). Sampling: error/fatal default to 100% (overridable via perLevel/shouldEmit); forceKeep can rescue rate-dropped events.
Create wide event mixincreateWideEventMixin({ asyncContext, sampling: { strategy: 'default', rate: 0.1 } })-
Hot-shots mixin@loglayer/mixin-hot-shotsStatsD/DogStatsD metrics via log.stats.*. contextTagKeys auto-promotes allowlisted scalar context values to tags.
Hot-shots metrics testingnew MemoryStatsClient() + hotshotsMixin(client)Records structured { type, name, value, tags, sampleRate } in client.records; client.clear() to reset.