JSON formatter for Python's built-in logging package that enables structured, machine-readable log output
—
Base formatter class and configuration system that provides extensive customization options for JSON log output. All formatter implementations inherit from BaseJsonFormatter.
from pythonjsonlogger.core import BaseJsonFormatter, str_to_object, merge_record_extra, RESERVED_ATTRSFor type checking:
from typing import Optional, Union, Dict, Any, List, Sequence, Container
import loggingAbstract base class providing core JSON logging functionality and configuration options.
class BaseJsonFormatter(logging.Formatter):
def __init__(
self,
fmt: Optional[str] = None,
datefmt: Optional[str] = None,
style: str = "%",
validate: bool = True,
*,
prefix: str = "",
rename_fields: Optional[Dict[str, str]] = None,
rename_fields_keep_missing: bool = False,
static_fields: Optional[Dict[str, Any]] = None,
reserved_attrs: Optional[Sequence[str]] = None,
timestamp: Union[bool, str] = False,
defaults: Optional[Dict[str, Any]] = None,
exc_info_as_array: bool = False,
stack_info_as_array: bool = False,
) -> None:
"""
Base JSON formatter initialization with extensive configuration options.
Standard logging parameters:
- fmt: string representing fields to log
- datefmt: format to use when formatting asctime field
- style: how to extract log fields from fmt (%, {, $)
- validate: validate fmt against style
JSON-specific parameters:
- prefix: string prefix added to formatted output
- rename_fields: dict to rename field names in output
- rename_fields_keep_missing: include missing fields when renaming
- static_fields: dict of fields with static values added to all logs
- reserved_attrs: list of fields to skip when outputting JSON
- timestamp: add timestamp field (True, False, or custom key name)
- defaults: dict of default fields added before all other fields
- exc_info_as_array: break exc_info into array of lines
- stack_info_as_array: break stack_info into array of lines
"""
def format(self, record: logging.LogRecord) -> str:
"""
Format a log record and serialize to JSON.
Parameters:
- record: the log record to format
Returns:
JSON string representation of the log record
"""
def parse(self) -> List[str]:
"""
Parse format string looking for field substitutions.
Supports %, {}, and $ style format strings.
Returns:
List of field names to be extracted and serialized
"""
def serialize_log_record(self, log_record: LogRecord) -> str:
"""
Return final representation of the log record.
Applies prefix and calls jsonify_log_record.
Parameters:
- log_record: the log record dictionary
Returns:
Final formatted string
"""
def add_fields(
self,
log_record: Dict[str, Any],
record: logging.LogRecord,
message_dict: Dict[str, Any],
) -> None:
"""
Extract fields from a LogRecord for logging.
Can be overridden to implement custom field extraction logic.
Parameters:
- log_record: dictionary that will be logged
- record: the original LogRecord to extract data from
- message_dict: dictionary logged instead of a message
"""
def jsonify_log_record(self, log_record: LogRecord) -> str:
"""
Convert log record into JSON string.
Abstract method that must be implemented by subclasses.
Parameters:
- log_record: the data to serialize
Returns:
JSON string representation
"""
def process_log_record(self, log_record: LogRecord) -> LogRecord:
"""
Custom processing hook for log records.
Can be overridden to modify log records before serialization.
Parameters:
- log_record: incoming log data
Returns:
Processed log record
"""
def formatException(self, ei) -> Union[str, list[str]]:
"""
Format and return exception information.
Parameters:
- ei: exception info tuple
Returns:
Formatted exception as string or list of strings if exc_info_as_array is True
"""
def formatStack(self, stack_info) -> Union[str, list[str]]:
"""
Format and return stack information.
Parameters:
- stack_info: stack info string
Returns:
Formatted stack as string or list of strings if stack_info_as_array is True
"""Utility functions for string-to-object conversion and log record merging.
def str_to_object(obj: Any) -> Any:
"""
Import strings to an object, leaving non-strings as-is.
Converts module.function strings to actual callable objects.
Parameters:
- obj: the object or string to process
Returns:
Imported object if string, otherwise original object
"""
def merge_record_extra(
record: logging.LogRecord,
target: Dict,
reserved: Container[str],
rename_fields: Optional[Dict[str, str]] = None,
) -> Dict:
"""
Merge extra attributes from LogRecord into target dictionary.
Parameters:
- record: logging.LogRecord instance
- target: dictionary to update
- reserved: container with reserved keys to skip
- rename_fields: optional dict for renaming field names
Returns:
Updated target dictionary
"""import logging
from pythonjsonlogger.json import JsonFormatter
# Basic formatter with field selection
formatter = JsonFormatter('%(levelname)s %(name)s %(message)s')
# Custom format with timestamp
formatter = JsonFormatter(
'%(levelname)s %(message)s',
timestamp=True # Adds "timestamp" field
)
# Custom timestamp field name
formatter = JsonFormatter(
'%(levelname)s %(message)s',
timestamp="log_time" # Adds "log_time" field
)from pythonjsonlogger.json import JsonFormatter
# Rename fields in output
formatter = JsonFormatter(
'%(levelname)s %(name)s %(message)s',
rename_fields={
'levelname': 'level',
'name': 'logger',
'message': 'msg'
}
)
# Keep missing fields when renaming (with None values)
formatter = JsonFormatter(
'%(levelname)s %(message)s',
rename_fields={'nonexistent': 'missing'},
rename_fields_keep_missing=True
)from pythonjsonlogger.json import JsonFormatter
# Add static fields to every log record
formatter = JsonFormatter(
'%(levelname)s %(message)s',
static_fields={
'service': 'my-app',
'version': '1.0.0',
'environment': 'production'
}
)
# Add default fields that can be overridden
formatter = JsonFormatter(
'%(levelname)s %(message)s',
defaults={
'component': 'unknown',
'user_id': None
}
)from pythonjsonlogger.json import JsonFormatter
from pythonjsonlogger.core import RESERVED_ATTRS
# Use custom reserved attributes list
custom_reserved = list(RESERVED_ATTRS) + ['custom_field']
formatter = JsonFormatter(
'%(levelname)s %(message)s',
reserved_attrs=custom_reserved
)
# Minimal reserved attributes (include more fields)
formatter = JsonFormatter(
'%(levelname)s %(message)s',
reserved_attrs=['args', 'msg'] # Only skip these fields
)from pythonjsonlogger.json import JsonFormatter
# Format exceptions and stack traces as arrays
formatter = JsonFormatter(
'%(levelname)s %(message)s',
exc_info_as_array=True,
stack_info_as_array=True
)
# Example output for exception:
# {"levelname": "ERROR", "message": "Error occurred", "exc_info": ["Traceback...", " File...", "ValueError: error"]}from pythonjsonlogger.json import JsonFormatter
# Add prefix to all log output
formatter = JsonFormatter(
'%(levelname)s %(message)s',
prefix='[JSON] '
)
# Output: [JSON] {"levelname": "INFO", "message": "test"}from pythonjsonlogger.json import JsonFormatter
# Percent style (default)
formatter = JsonFormatter('%(levelname)s %(message)s')
# Brace style
formatter = JsonFormatter('{levelname} {message}', style='{')
# Dollar style
formatter = JsonFormatter('${levelname} ${message}', style='$')
# Custom style (requires validate=False)
formatter = JsonFormatter('custom_format', style='custom', validate=False)Default reserved attributes (from RESERVED_ATTRS):
The formatter parses format strings to identify required fields:
%(field)s patterns{field} patterns${field} patternsParsed fields are automatically included in JSON output.
Install with Tessl CLI
npx tessl i tessl/pypi-python-json-logger