Skip to content

Logging Module

forge.log — Structured JSON logging with automatic trace context propagation.

Overview

The Log module provides production-ready structured logging that works out of the box. In production, it outputs JSON for log aggregators. In development, it uses colorized human-readable output. Trace IDs propagate automatically across async boundaries via contextvars.

Installation

pip install forge-kaif

Quick Start

from forge.log import get

logger = get("my_app")
logger.info("Server starting", port=8080)
# {"timestamp": "...", "level": "INFO", "module": "my_app", "message": "Server starting", "port": 8080}

Key Features

Log Context Binding

from forge.log import context

with context(request_id="abc-123", user_id=42):
    logger.info("Processing request")
    # All log entries within this context include request_id and user_id

Module-Aware Loggers

logger = get("my_app.database")
logger.error("Connection failed", db_host="prod-db-1")

JSON Output (Production)

{
  "timestamp": "2025-01-15T10:30:00.123Z",
  "level": "INFO",
  "module": "my_app",
  "message": "Request completed",
  "trace_id": "abc-123-def-456",
  "duration_ms": 245
}

Development Output

[10:30:00] INFO     my_app        Request completed              duration_ms=245 trace_id=abc-123

API Reference

Structured logging module — JSON and human-readable log output with context propagation.

Provides a module-aware logger factory, automatic trace ID propagation via contextvars, and configurable output formats for development and production environments.

Classes

DevFormatter

Colorized human-readable log output for development.

Format::

[2026-06-28 12:00:00] module.name  INFO   message here

JSONFormatter

Outputs structured JSON log lines for production use.

Every record produces: timestamp, level, module, message, and optionally trace_id (if one is active). Extra fields bound via LogContext are included at the top level. Circular references are replaced with "<circular>" and strings longer than 10 000 characters are truncated.

LogContext

Async-safe context manager that binds extra fields to log entries.

Usage::

with LogContext(request_id="abc-123", user="alice"):
    logger.info("processing request")
    # → log entry includes request_id="abc-123", user="alice"

Methods:

get_current staticmethod
get_current() -> dict[str, Any]

Return a copy of the currently bound extra fields.

LogContextFilter

Logging filter that injects LogContext fields into every record.

Attach this filter to the root logger or handler to automatically propagate contextvars-based extra fields to all log entries::

root_logger.addFilter(LogContextFilter())

LogModule

Methods:

context
context(**kwargs: Any) -> Generator[None, None, None]

Context manager for binding key-value pairs to all log entries within the context.

get
get(name: str) -> LoggerProxy

Return a logger wrapped in LoggerProxy for name.

get_logger
get_logger(name: str) -> logging.Logger

Return a logger for name configured by this module.

LoggerProxy

Wraps a standard logging.Logger to support direct keyword arguments.

Example::

logger = log.get("module")
logger.info("user logged in", user_id=123, ip="127.0.0.1")
# → keyword arguments are merged into the structured extra fields.

Functions:

get

get(name: str) -> LoggerProxy

Get a module logger wrapped in LoggerProxy.

Delegates to the active runtime's LogModule if initialized, otherwise returns a default LoggerProxy.