Skip to content

API Reference

Public API

HushLog — Zero-config PII redaction for Python logging.

patch(config=None)

Zero-config entry point. Wraps existing formatters with RedactingFormatter.

Call this once at application startup to automatically redact PII and credentials from all log output. No logger rewrites needed.

Calling patch() multiple times is safe (idempotent) — subsequent calls are no-ops. To change the configuration, call unpatch() first, then patch(new_config).

Note: Only handlers present on the root logger at call time are wrapped. Handlers added later will not be redacted.

unpatch()

Remove HushLog's RedactingFormatter wrappers and restore original formatters.

redact_dict(data, config=None)

Redact PII in a dict/list/string structure.

Convenience wrapper around PatternRegistry.redact_dict().

.. note::

This creates a new ``PatternRegistry`` on every call. For repeated use,
create a registry once via ``PatternRegistry.from_config()`` and call
``registry.redact_dict()`` directly.

structlog_processor(config=None)

Create a structlog processor that redacts PII in event dicts.

Returns a processor function compatible with structlog's processor chain. The processor applies PatternRegistry.redact_dict() to the event dict, redacting all string values while leaving keys and non-string values intact.

Usage::

import structlog
from hushlog import structlog_processor

structlog.configure(
    processors=[
        structlog.stdlib.add_log_level,
        structlog_processor(),
        structlog.dev.ConsoleRenderer(),
    ],
)

Parameters:

Name Type Description Default
config Config | None

Optional HushLog configuration. If None, uses default Config.

None

Returns:

Type Description
Callable[[object, str, dict[str, object]], dict[str, object]]

A structlog processor function.

loguru_sink(sink, config=None)

Wrap a loguru sink with PII redaction.

Returns a sink function that redacts PII in log messages before forwarding them to the wrapped sink.

Usage::

from loguru import logger
from hushlog import loguru_sink

logger.add(loguru_sink(print))
logger.info("User email: john@example.com")
# Output: User email: [EMAIL REDACTED]

For file sinks, wrap a file-writing function::

f = open("app.log", "a")
logger.add(loguru_sink(f.write), format="{message}")

Parameters:

Name Type Description Default
sink Callable[[str], object]

The underlying sink callable (receives a string).

required
config Config | None

Optional HushLog configuration. If None, uses default Config.

None

Returns:

Type Description
Callable[[object], None]

A loguru-compatible sink function.

Config

hushlog._config.Config dataclass

Optional configuration for HushLog redaction behavior.

All fields have sensible defaults — constructing Config() gives zero-config behavior.

RedactingJsonFormatter

hushlog._json_formatter.RedactingJsonFormatter

Bases: Formatter

A JSON log formatter that redacts PII in structured log records.

Builds a dict from the log record, redacts all string values via PatternRegistry.redact_dict(), then serializes to JSON.

Usage::

from hushlog import Config, RedactingJsonFormatter
from hushlog._registry import PatternRegistry

registry = PatternRegistry.from_config(Config())
formatter = RedactingJsonFormatter(registry)
handler.setFormatter(formatter)

from_config(config=None, *, fmt=None, datefmt=None, json_indent=None) classmethod

Create a RedactingJsonFormatter from a Config.

format(record)

Format the log record as redacted JSON.

PatternRegistry

hushlog._registry.PatternRegistry

Central store of pre-compiled regex patterns with heuristic pre-checks.

register(entry)

Register a redaction pattern.

unregister(name)

Remove a pattern by name. Raises KeyError if not found.

redact(text)

Apply all registered patterns to the text, returning the redacted result.

This is the hot path — performance matters. For each pattern: 1. If a heuristic is defined and returns False, skip (early exit). 2. Otherwise, run regex substitution.

redact_dict(data, *, _depth=0)

Recursively redact string values in dicts, lists, and tuples.

Non-string scalars (int, float, bool, None) are returned as-is. Keys in dicts are not redacted — only values. Max recursion depth of 20 prevents stack overflow on pathological input.

from_config(config) classmethod

Build a registry from a Config, applying disable/custom pattern overrides.