Raypx

@raypx/logger

Structured logging with Pino.

@raypx/logger provides structured JSON logging built on top of Pino. It exposes a simple API for creating loggers, attaching context, and serializing errors.

Exports

ExportDescription
createLogger(options?)Create a new logger instance with custom configuration
getLogger()Get or create the global default logger singleton
setLogger(logger)Replace the global default logger (useful in tests)
loggerProxy-based default logger that lazily initializes via getLogger()
createConsoleTransport(level?)Create a pino-pretty console transport (dev only)
createFileTransport(destination, level?)Create a file-based transport
serializeError(error)Serialize an error into a plain object

Quick Start

import { logger } from "@raypx/logger"

logger.info("Server started", { port: 3000 })
logger.error("Database connection failed", { err: serializeError(error) })

Log Levels

The logger supports six levels ordered by severity:

LevelPriorityDefault in Production
trace0No
debug1No
info2Yes
warn3Yes
error4Yes
fatal5Yes

In development, the default level is debug. In production (NODE_ENV=production), it defaults to info. Override with the level option or the LOG_LEVEL environment variable.

Creating a Logger

import { createLogger } from "@raypx/logger"

const log = createLogger({
  level: "debug",
  service: "auth-service",
  version: "1.0.0",
  redact: ["password", "token"],
  context: { feature: "auth" },
})

log.info("User logged in", { userId: "abc" })

Context and Child Loggers

Attach context to individual log entries or create child loggers that inherit a base context:

// Per-call context
logger.info("Processing request", { feature: "rpc", endpoint: "profile" })

// Child logger with persistent context
const authLog = logger.withContext({ feature: "auth" })
authLog.info("Password reset requested", { email: "user@example.com" })
authLog.error("Reset failed", { reason: "token_expired" })

Usage in RPC Interceptors

The RPC layer uses the logger to record API activity:

import { logger } from "@raypx/logger"

logger.info("rpc.call", {
  feature: "rpc",
  procedure: "documents.upload",
  userId: session.user.id,
})

Usage in Auth Callbacks

Better Auth callbacks in @raypx/auth log events with the feature: "auth" context:

import { logger } from "@raypx/logger"

logger.info("auth.password.reset", { feature: "auth", userId: user.id })

Error Serialization

Use serializeError to safely convert Error objects (including nested causes) into plain objects suitable for JSON logging:

import { serializeError } from "@raypx/logger"

try {
  await riskyOperation()
} catch (error) {
  logger.error("Operation failed", { err: serializeError(error) })
}

The serialized output includes name, message, stack, and recursively serialized cause properties.

Transports

Two transport factories are provided for advanced configurations:

import { createConsoleTransport, createFileTransport } from "@raypx/logger"

const log = createLogger({
  transports: [
    createConsoleTransport("debug"),
    createFileTransport("/var/log/raypx.log", "info"),
  ],
})

In development, if pino-pretty is installed and no explicit transports are configured, the logger automatically uses it for colored, single-line console output.

On this page