Skip to content

core.logging

Logging modules: structured JSON log output with rotation and sensitive data redaction.

Structured Logger

core.logging.structured_logger

Structured logging with rotation, redaction, and export.

Provides a unified logging layer on top of loguru that adds: - JSON structured log output - Automatic log rotation (size-based + time-based) - Privacy-aware redaction of sensitive fields - Separate user-visible transcript from debug logs - Export functionality for debugging

LogEntry

A structured log entry.

to_dict() -> dict[str, Any]

Serialize to a JSON-friendly dict.

to_json() -> str

Serialize to a JSON string.

to_text() -> str

Serialize to a human-readable text line.

LogLevel

Log level constants.

RotationConfig

Configuration for log rotation.

StructuredLogHandler

Bases: Handler

A stdlib logging handler that writes to a StructuredLogger.

StructuredLogger

Structured logger with rotation and redaction.

Writes JSON-structured logs to a file with automatic rotation. Supports privacy-aware redaction via a LogRedactor. Provides export and debug bundle functionality.

Usage

logger = StructuredLogger( log_dir=pathlib.Path("data/logs"), rotation=RotationConfig(max_bytes=5_000_000), ) logger.info("User connected", component="api", user_id="123") logger.warn("High memory usage", component="system", memory_mb=900)

clear_logs() -> int

Clear all log files. Returns number of files cleared.

export_logs(*, output_path: pathlib.Path, max_bytes: int | None = None, include_transcript: bool = True, include_audit: bool = False) -> pathlib.Path

Export logs to a zip file.

Parameters:

Name Type Description Default
output_path Path

Where to write the zip file.

required
max_bytes int | None

Maximum size of each log file to include (tail).

None
include_transcript bool

Whether to include the user transcript.

True
include_audit bool

Whether to include audit log data.

False

Returns:

Type Description
Path

The path to the created zip file.

get_recent_entries(*, count: int = 100, level: str | None = None, component: str | None = None) -> list[dict[str, Any]]

Read recent entries from the log file.

Parameters:

Name Type Description Default
count int

Maximum number of entries to return.

100
level str | None

Filter by log level.

None
component str | None

Filter by component.

None

Returns:

Type Description
list[dict[str, Any]]

List of log entry dicts (most recent first).

get_stdlib_handler() -> logging.Handler

Get a stdlib logging handler that writes to this logger.

Use this to bridge stdlib logging into the structured logger

handler = structured_logger.get_stdlib_handler() logging.getLogger().addHandler(handler)

log(level: str, message: str, *, component: str = 'app', correlation_id: str = '', transcript: bool = False, **data: Any) -> None

Write a structured log entry.

rotate() -> int

Manually rotate log files. Returns number of files rotated.

Log Redactor

core.logging.log_redactor

Privacy-aware log redaction.

Provides patterns and utilities to sanitize sensitive data before writing to logs: - Email addresses - Phone numbers - IP addresses - API keys and tokens - Passwords and secrets - Credit card-like patterns - Custom redaction patterns

Two implementations: - DefaultRedactor: regex-based, no dependencies - LogRedactor: protocol for custom implementations

DefaultRedactor

Bases: LogRedactor

Regex-based redactor with configurable patterns.

redact(text: str) -> str

Redact sensitive data from a string.

redact_dict(data: dict[str, Any]) -> dict[str, Any]

Redact sensitive data from a dict (values only).

redact_keys(keys: list[str]) -> list[str]

Redact sensitive dict keys themselves.

LogRedactor

Base class for log redactors.

Subclass to provide custom redaction behavior.

redact(text: str) -> str

Redact sensitive data from a string.

redact_dict(data: dict[str, Any]) -> dict[str, Any]

Redact sensitive data from a dict (values only).

redact_keys(keys: list[str]) -> list[str]

Redact sensitive dict keys themselves.

NoOpRedactor

Bases: LogRedactor

Redactor that passes everything through unchanged.

Useful for testing or when redaction is not needed.

RedactionConfig

Configuration for log redaction.

build_patterns() -> list[tuple[str, re.Pattern]]

Build the list of active patterns based on config.