Skip to main content

@agentlib/logger

Structured logging middleware for AgentLIB — plug-and-play observability for agent runs.

Installation

npm install @agentlib/logger

Overview

The @agentlib/logger package provides a middleware that logs agent lifecycle events with:
  • Structured log output
  • Configurable log levels
  • Timing measurements
  • Scope filtering
  • Custom transports
  • Zero-config defaults

Quick Start

import { createAgent } from '@agentlib/core'
import { createLogger } from '@agentlib/logger'

const agent = createAgent({
  name: 'assistant',
  middleware: [createLogger()]
})

await agent.run('Hello, world!')
Output:
[agentlib] [2026-03-03T10:15:30.123Z] [INFO] scope=run:before
[agentlib] [2026-03-03T10:15:31.456Z] [INFO] scope=run:after duration=1333ms

Configuration

interface LoggerMiddlewareConfig {
  /** Minimum log level to emit (default: 'info') */
  level?: 'debug' | 'info' | 'warn' | 'error' | 'silent'
  
  /** Which middleware scopes to log */
  scopes?: MiddlewareScope[]
  
  /** Custom transport function */
  transport?: (entry: LogEntry) => void
  
  /** Measure and log duration (default: true) */
  timing?: boolean
  
  /** Log prefix (default: '[agentlib]') */
  prefix?: string
}

Usage Examples

Default Configuration

import { createLogger } from '@agentlib/logger'

agent.use(createLogger())
Logs:
  • run:before and run:after at INFO level
  • step:* and tool:* at DEBUG level
  • Includes timing measurements

Debug Mode

agent.use(createLogger({
  level: 'debug'
}))
Shows all lifecycle events including:
  • Step start/end
  • Tool invocations
  • Detailed timing

Scope Filtering

agent.use(createLogger({
  scopes: ['run:before', 'run:after', 'tool:before', 'tool:after']
}))
Only logs specific scopes.

Disable Timing

agent.use(createLogger({
  timing: false
}))

Custom Prefix

agent.use(createLogger({
  prefix: '[my-agent]'
}))
Output:
[my-agent] [2026-03-03T10:15:30.123Z] [INFO] scope=run:before

Log Levels

Level Hierarchy

const levels = {
  debug: 0,   // Most verbose
  info: 1,    // Default
  warn: 2,
  error: 3,
  silent: 99  // No output
}
Setting level: 'info' will show INFO, WARN, and ERROR logs.

Auto-Level Mapping

Scopes are automatically mapped to log levels:
  • run:before, run:after → INFO
  • step:before, step:after → DEBUG
  • tool:before, tool:after → DEBUG

Custom Transports

JSON Transport

import { createLogger } from '@agentlib/logger'

agent.use(createLogger({
  transport: (entry) => {
    console.log(JSON.stringify(entry))
  }
}))
Output:
{"level":"info","scope":"run:before","timestamp":"2026-03-03T10:15:30.123Z","agentInput":"Hello"}

File Transport

import fs from 'fs'
import { createLogger } from '@agentlib/logger'

const logStream = fs.createWriteStream('agent.log', { flags: 'a' })

agent.use(createLogger({
  transport: (entry) => {
    logStream.write(JSON.stringify(entry) + '\n')
  }
}))

Winston Integration

import winston from 'winston'
import { createLogger } from '@agentlib/logger'

const logger = winston.createLogger({
  transports: [new winston.transports.File({ filename: 'agent.log' })]
})

agent.use(createLogger({
  transport: (entry) => {
    logger.log(entry.level, entry)
  }
}))

Pino Integration

import pino from 'pino'
import { createLogger } from '@agentlib/logger'

const logger = pino()

agent.use(createLogger({
  transport: (entry) => {
    logger[entry.level](entry)
  }
}))

Log Entry Structure

interface LogEntry {
  /** Log level */
  level: 'debug' | 'info' | 'warn' | 'error' | 'silent'
  
  /** Middleware scope */
  scope: MiddlewareScope
  
  /** ISO timestamp */
  timestamp: string
  
  /** Agent input (for run scopes) */
  agentInput?: string
  
  /** Tool name (for tool scopes) */
  tool?: string
  
  /** Duration in milliseconds */
  durationMs?: number
  
  /** Additional metadata */
  meta?: Record<string, unknown>
}

Middleware Scopes

Available scopes:
  • run:before - Before agent run starts
  • run:after - After agent run completes
  • step:before - Before reasoning step
  • step:after - After reasoning step
  • tool:before - Before tool execution
  • tool:after - After tool execution

Timing Measurements

When timing: true (default), the logger measures duration between :before and :after scopes:
[agentlib] [2026-03-03T10:15:30.123Z] [DEBUG] scope=tool:before tool=get_weather
[agentlib] [2026-03-03T10:15:30.850Z] [DEBUG] scope=tool:after tool=get_weather duration=727ms

Advanced Usage

Conditional Logging

const isDev = process.env.NODE_ENV === 'development'

agent.use(createLogger({
  level: isDev ? 'debug' : 'info'
}))

Multi-Transport

const consoleLogger = createLogger({ level: 'info' })
const fileLogger = createLogger({
  level: 'debug',
  transport: (entry) => {
    fs.appendFileSync('agent.log', JSON.stringify(entry) + '\n')
  }
})

agent.use(consoleLogger)
agent.use(fileLogger)

Metric Collection

const metrics = {
  runs: 0,
  totalDuration: 0,
  toolCalls: 0
}

agent.use(createLogger({
  transport: (entry) => {
    if (entry.scope === 'run:after' && entry.durationMs) {
      metrics.runs++
      metrics.totalDuration += entry.durationMs
    }
    if (entry.scope === 'tool:after') {
      metrics.toolCalls++
    }
  }
}))

Selective Scope Logging

// Only log tool executions
agent.use(createLogger({
  scopes: ['tool:before', 'tool:after'],
  level: 'debug'
}))

Best Practices

  1. Use INFO for production:
    agent.use(createLogger({ level: 'info' }))
    
  2. Use DEBUG for development:
    agent.use(createLogger({ level: 'debug' }))
    
  3. Filter noisy scopes:
    agent.use(createLogger({
      scopes: ['run:before', 'run:after', 'tool:after']
    }))
    
  4. Structured logging to files:
    agent.use(createLogger({
      transport: (entry) => {
        fs.appendFileSync('agent.log', JSON.stringify(entry) + '\n')
      }
    }))
    
  5. Combine with monitoring tools:
    agent.use(createLogger({
      transport: (entry) => {
        // Send to DataDog, Prometheus, etc.
        monitoring.track(entry)
      }
    }))
    

Requirements

  • Node.js: >= 18.0.0
  • Dependencies: @agentlib/core (workspace)

Exports

Functions

  • createLogger(config?) - Create logging middleware

Types

  • LoggerMiddlewareConfig - Configuration interface
  • LogLevel - Log level type
  • LogEntry - Log entry structure
  • LogTransport - Transport function type

Build docs developers (and LLMs) love