CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-python-json-logger

JSON formatter for Python's built-in logging package that enables structured, machine-readable log output

Pending
Overview
Eval results
Files

core-configuration.mddocs/

Core Configuration

Base formatter class and configuration system that provides extensive customization options for JSON log output. All formatter implementations inherit from BaseJsonFormatter.

Core Imports

from pythonjsonlogger.core import BaseJsonFormatter, str_to_object, merge_record_extra, RESERVED_ATTRS

For type checking:

from typing import Optional, Union, Dict, Any, List, Sequence, Container
import logging

Capabilities

BaseJsonFormatter Class

Abstract 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
        """

Core Utility Functions

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
    """

Usage Examples

Basic Configuration

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
)

Field Renaming

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
)

Static and Default Fields

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
    }
)

Custom Reserved Attributes

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
)

Exception and Stack Formatting

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"]}

String Prefix

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"}

Format String Styles

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)

Configuration Reference

Field Processing Order

  1. defaults: Added first, can be overridden
  2. required_fields: From format string parsing
  3. static_fields: Added after defaults, override previous values
  4. message_dict: From logging dict-style calls
  5. extra_fields: From LogRecord.dict (excluding reserved)
  6. timestamp: Added if configured

Reserved Attributes

Default reserved attributes (from RESERVED_ATTRS):

  • Standard LogRecord fields: name, levelname, levelno, pathname, filename, module, funcName, lineno, created, msecs, relativeCreated, thread, threadName, process, processName, message, exc_info, exc_text, stack_info, args, asctime
  • Python 3.12+: taskName

Format String Processing

The formatter parses format strings to identify required fields:

  • % style: %(field)s patterns
  • { style: {field} patterns
  • $ style: ${field} patterns

Parsed fields are automatically included in JSON output.

Install with Tessl CLI

npx tessl i tessl/pypi-python-json-logger

docs

core-configuration.md

index.md

json-formatting.md

performance-formatting.md

type-handling.md

utilities.md

tile.json