OCPP WS IOOCPP WS IO

Logging

Comprehensive guide to structured logging in ocpp-ws-io

Logging

ocpp-ws-io includes a structured logging system powered by voltlog-io. It provides real-time traffic inspection, performance monitoring, and integration with external logging services.

Overview

Logging in ocpp-ws-io is designed to be:

  • Zero-Config: Works out of the box with sensible defaults.
  • Structured: All logs are JSON-formatted for easy parsing and ingestion.
  • OCPP-Aware: Special handling for OCPP messages, including direction and metadata.
  • Extensible: Use built-in transports or bring your own logger (Pino, Winston, etc.).

Quick Start

Enable logging when initializing your client or server:

import { OCPPClient } from "ocpp-ws-io";

const client = new OCPPClient({
  identity: "CP-001",
  endpoint: "ws://localhost:3000",
  logging: {
    enabled: true, // Default: true
    prettify: true, // 🌈 Enable colors & icons for development
    exchangeLog: true, // ⚡ Log every OCPP message (Call/Result/Error)
  },
});

Configuration

The logging option accepts a LoggingConfig object:

OptionTypeDefaultDescription
enabledbooleantrueEnable or disable all logging.
logging (root)booleanundefinedCan be set directly to false to completely disable logging with a safe NOOP fallback.
levelstring'info'Minimum log level (trace, debug, info, warn, error, fatal).
prettifybooleanfalseUse prettyTransport for human-readable output (colors, icons).
exchangeLogbooleanfalseLog all OCPP messages with direction (IN/OUT) and metadata.
loggerLoggerLikeundefinedCustom logger instance (e.g., Pino) to replace the default logger.
handlerfunctionundefinedCustom voltlog-io transport function (entry) => void | Promise<void>
showMetadatabooleantrueShow trailing metadata object in logs.
showSourceMetabooleantrueShow source context (component, identity).
prettifySourcebooleanfalseCompact source tag [OCPPServer/CP-1].
prettifyMetadatabooleanfalseFormat metadata as key=value pairs.

Levels

LevelValueUsage
fatal60System is unusable.
error50Error conditions (connection failures, validation errors).
warn40Warning conditions (retries, unexpected messages).
info30Normal operational messages (connect/disconnect, startup).
debug20Detailed internal state (protocol negotiation, raw payloads).
trace10Very detailed step-by-step tracing.

Exchange Logging (Middleware)

The exchangeLog feature is now powered by the internal Logging Middleware. It logs every WebSocket message sent or received.

Output Format

When prettify: true is also enabled, you get styled output distinguishing outbound calls, inbound calls, and asynchronous results:

// Outbound RPC Call (from Station to CSMS)
⚡ CP-101  →  BootNotification  [OUT]

// Inbound RPC Call (from CSMS to Station)
✅ CP-101  ←  GetConfiguration  [IN]

// Asynchronous RPC Result / Error returned
🔥 CP-101  ←  BootNotification  [RES]   { latencyMs: 45 }

When prettify: false (production), logs are structured JSON:

{
  "level": 30,
  "msg": "BootNotification",
  "direction": "OUT",
  "messageId": "12345",
  "payload": { ... }
}

Voltlog Integration

This library uses voltlog-io under the hood. You can import logging utilities directly from ocpp-ws-io/logger:

import { createLogger, consoleTransport } from "ocpp-ws-io/logger";

const logger = createLogger({
  name: "MyCSMS",
  transports: [consoleTransport()],
});

logger.info("System started");

Using a Custom Logger Instance

If you already use Pino, Winston, or another logger, you can pass it to ocpp-ws-io. The logger must satisfy the LoggerLike interface (methods: debug, info, warn, error, child).

Example with Pino:

import pino from "pino";
import { OCPPServer } from "ocpp-ws-io";

const myLogger = pino();

const server = new OCPPServer({
  logging: {
    logger: myLogger, // ocpp-ws-io will use this instance
  },
});

Using a Custom Transport Handler

If you prefer to let ocpp-ws-io handle the logger initialization (and middleware enrichment) but want to siphon the formatted log items to an external observability platform (like Datadog, Sentry, an external file, or a custom UI), you can provide a custom handler callback.

This handler will receive the fully resolved LogEntry directly from the internal voltlog-io pipeline!

const server = new OCPPServer({
  logging: {
    enabled: true,
    handler: async (entry) => {
      // example: Send log to a remote ingest API
      await fetch("https://logs.example.com/ingest", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(entry),
      });
    },
  },
});

Browser Client

The BrowserOCPPClient also supports logging, configured the same way.

import { BrowserOCPPClient } from "ocpp-ws-io/browser";

const client = new BrowserOCPPClient({
  endpoint: "wss://csms.example.com",
  identity: "Simulator-1",
  logging: {
    level: "debug",
    exchangeLog: true,
  },
});

Note: In the browser, prettify uses browser console styling (CSS) instead of terminal colors.

On this page