python-json-logger

Format Python's standard logging output as structured JSON

Library
PyPI
v4.2.0
267stars
BSD-2-Clause

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
67/100Good
Development Activity68
Maintenance56
Community68
Maturity48
Momentum28

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
76/100Good
Architecture74
Code Quality78
Innovation68
Learning Curve82

python-json-logger is a lightweight formatter for Python’s built-in logging module that renders log records as JSON objects instead of plain text. Because JSON logs are machine-readable, they slot directly into log aggregation and observability pipelines (ELK, Datadog, CloudWatch, Loki) without custom parsing rules.

It ships as a drop-in logging.Formatter subclass, so existing logging configuration (handlers, levels, filters) keeps working unchanged — only the output format changes. The library also supports pluggable serializers (stdlib json, orjson, msgspec) and encodes common non-JSON-native types like exceptions, datetimes, and dataclasses automatically.

What You Get

  • A JsonFormatter class that plugs into any existing logging.Handler via setFormatter()
  • Automatic JSON-safe encoding of exceptions, tracebacks, datetimes, enums, bytes, and dataclasses
  • Optional high-performance serialization backends via orjson and msgspec extras
  • Configurable field renaming, static fields, and reserved-attribute exclusion for controlling log shape
  • Full typing support (py.typed) for type-checked logging configuration

Common Use Cases

  • Shipping application logs to Elasticsearch/OpenSearch or Loki without a separate log-parsing layer
  • Emitting structured logs for cloud-native platforms (CloudWatch, Stackdriver, Datadog) that index JSON fields natively
  • Standardizing log format across microservices so every service emits the same JSON schema
  • Correlating request/trace IDs and custom context fields directly as top-level JSON keys for querying

Under The Hood

Architecture - The package centers on core.BaseJsonFormatter (src/pythonjsonlogger/core.py), which extracts fields from a logging.LogRecord, strips reserved attributes, merges in extra fields and any static fields configured at init, then hands the resulting dict to a serializer-specific subclass. json.py implements the default JsonFormatter using stdlib json.dumps plus a custom JsonEncoder that dispatches unencodable types (datetimes, exceptions, enums, bytes, dataclasses) to helper functions in defaults.py. Optional orjson.py and msgspec.py modules provide alternate formatter subclasses that swap in faster serializers while reusing the same core field-extraction logic, so the format contract stays identical across backends.

Tech Stack - Pure Python (100% of the codebase), targeting Python 3.10+, with zero required runtime dependencies — orjson and msgspec are optional extras rather than core requirements. Build tooling uses setuptools with pyproject.toml-only configuration, mypy for type checking (with a dedicated mypy.ini), pylint for linting, and mkdocs/mkdocs-material for documentation, reflecting a deliberately dependency-light design appropriate for a logging shim used across many downstream projects.

Code Quality - The tests/ directory contains 5 test modules covering the core formatter, JSON/orjson/msgspec backends, and default-encoding behavior, run via pytest and tox across supported Python versions. The codebase is fully typed (py.typed marker, TypeAlias usage, strict mypy.ini), uses consistent section-comment banners (### IMPORTS, ### CLASSES) for navigability, and documents deprecations explicitly (e.g. the __getattr__ shim in json.py warns when the old RESERVED_ATTRS location is accessed). Docstrings follow a consistent Google-style format with Args:/Note: sections throughout.

API Design - Because JsonFormatter is a drop-in logging.Formatter subclass, adopting it requires zero changes to existing logger/handler setup beyond handler.setFormatter(JsonFormatter()) — a very low integration cost. Constructor kwargs (json_default, json_encoder, json_serializer, json_indent, json_ensure_ascii) map directly onto familiar json.dumps parameters, minimizing new concepts for Python developers. The main ergonomic rough edge is the historical API churn (v3 moved RESERVED_ATTRS out of the main module), mitigated by deprecation warnings rather than hard breaks.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search