Drop-in structured JSON logging for Python using the stdlib logging module
pip install philiprehberger-json-loggerDrop-in structured JSON logging for Python using the stdlib logging module.
pip install philiprehberger-json-logger
from philiprehberger_json_logger import setup
setup(level="DEBUG")
import logging
logging.info("Server started", extra={"port": 8080})
# {"timestamp": "2026-03-13T12:00:00+00:00", "level": "INFO", "message": "Server started", "logger": "root", "module": "app", "line": 5, "port": 8080}
import logging
from philiprehberger_json_logger import setup
logger = logging.getLogger("myapp")
setup(level="INFO", logger=logger)
logger.warning("Disk usage high", extra={"usage_pct": 91.3})
from philiprehberger_json_logger import setup
setup(level="INFO", extra_fields={"service": "api", "env": "production"})
Every log entry will include "service": "api" and "env": "production".
from philiprehberger_json_logger import setup
setup(level="INFO", redact_fields={"password", "token", "secret"})
import logging
logging.info("Login", extra={"user": "alice", "password": "s3cret"})
# password field will appear as "***"
Redaction works recursively on nested dicts.
import logging
from philiprehberger_json_logger import setup, log_context
setup(level="INFO")
with log_context(request_id="abc-123", user="alice"):
logging.info("Processing request")
# log entry includes request_id and user fields
with log_context(step="validation"):
logging.info("Validating input")
# log entry includes request_id, user, and step fields
import logging
from philiprehberger_json_logger import JsonFormatter
handler = logging.FileHandler("app.log")
handler.setFormatter(JsonFormatter(extra_fields={"service": "worker"}, redact_fields={"token"}))
logger = logging.getLogger("worker")
logger.addHandler(handler)
logger.setLevel(logging.INFO)
| Name | Description |
|---|---|
JsonFormatter(*, extra_fields=None, redact_fields=None) | Logging formatter that outputs JSON lines. extra_fields is a dict of static fields merged into every entry. redact_fields is a set of field names replaced with "***". |
setup(level="INFO", *, extra_fields=None, redact_fields=None, logger=None) | Configure a logger with JSON output. Defaults to the root logger. Clears existing handlers. |
log_context(**kwargs) | Context manager that injects fields into all log entries within the block. Supports nesting. |
| Field | Description |
|---|---|
timestamp | ISO 8601 UTC timestamp |
level | Log level name (DEBUG, INFO, WARNING, ERROR, CRITICAL) |
message | Formatted log message |
logger | Logger name |
module | Source module name |
line | Source line number |
exception | Full traceback string (only present when logging an exception) |
Any extra={} kwargs passed to the log call are merged into the top-level JSON object. Static extra_fields from the formatter and active log_context() fields are also merged.
pip install -e .
python -m pytest tests/ -v
If you find this project useful: