Registry / observability / json-log-formatter

json-log-formatter

JSON →
library1.2.1pypypi✓ verified 23d ago

The `json-log-formatter` library provides a Python logging formatter that outputs log records as JSON strings. This structured logging approach facilitates easier integration with log aggregation and analysis systems like Logstash or ElasticSearch. The library is currently at version 1.1.1 and appears to be actively maintained, with regular updates to support modern Python logging practices.

pip install json-log-formatter
INSTALL
IMPORT
SIG · JSON-LOG-FORMATTER
J
json-log-formatter
observabilitypythonv1.2.1
Install
1.6s avg
Import
29ms
Disk
16MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v1.2.1 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.95 runs
installs and imports cleanly · install 0.0s · import 0.032s · 17.8MB
glibc
py 3.103.95 runs
installs and imports cleanly · install 1.6s · import 0.026s · 18MB
16MB installed
● package 16MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

JSONFormatter
from json_log_formatter import JSONFormatter
This is the primary formatter class for basic JSON output.
VerboseJSONFormatter
from json_log_formatter import VerboseJSONFormatter
Use this formatter to include all built-in log record attributes.
FlatJSONFormatter
from json_log_formatter import FlatJSONFormatter
Use this formatter to flatten complex objects into strings.

This quickstart demonstrates how to set up a basic logger using `JSONFormatter` to output structured JSON logs to standard output. It shows logging of informational messages with custom `extra` fields and how exceptions are handled.

import logging import sys from json_log_formatter import JSONFormatter # Configure a basic logger logger = logging.getLogger('my_app') logger.setLevel(logging.INFO) # Create a JSON formatter instance formatter = JSONFormatter() # Create a StreamHandler that writes to stdout handler = logging.StreamHandler(sys.stdout) handler.setFormatter(formatter) # Add the handler to the logger logger.addHandler(handler) # Log some messages logger.info('User signed up', extra={'user_id': 123, 'email': 'test@example.com'}) logger.warning('Payment failed', extra={'order_id': 'abc-123', 'reason': 'card declined'}) try: raise ValueError('Something went wrong!') except ValueError: logger.error('An unexpected error occurred', exc_info=True, extra={'transaction_id': 'xyz-456'})
Debug
Known issues
gotchaAs of v0.3.0, the formatter attempts a 'best effort' to serialize log records containing non-serializable values (e.g., WSGIRequest objects) instead of raising a TypeError. While this prevents crashes, it might result in altered or omitted data for those specific fields if not explicitly handled.
fix
Review logs to understand how non-serializable objects are represented. If specific serialization is required, override `JSONFormatter.json_record()` or ensure objects are pre-processed to be JSON-serializable.
affects: >=0.3.0
gotchaWhen using alternative JSON libraries like `ujson` or `simplejson` (by overriding `JSONFormatter.json_serializer`), be aware that `ujson` specifically does not support the `json.dumps(default=f)` argument. This can lead to `TypeError` exceptions or silently skipped attributes if objects cannot be serialized directly.
fix
If using `ujson` with custom types, ensure all objects passed to the logger are natively serializable by `ujson` or pre-serialize them. Alternatively, override `JSONFormatter.json_record()` to handle complex types explicitly before `ujson` attempts serialization. Consider `simplejson` for better `default` argument support.
affects: All versions
gotchaTo add custom fields to every log record (e.g., user ID, IP address) or to customize the serialization of specific object types (e.g., `datetime` objects to timestamps), you must override the `json_record()` method in a custom formatter subclass. Not doing so will prevent these customizations from appearing in your logs.
fix
Subclass `JSONFormatter` and override the `json_record(self, message, extra, record)` method to manipulate the dictionary before JSON serialization. For example, add `extra` fields or format `datetime` objects.
affects: All versions
gotchaLogging sensitive data (e.g., passwords, API keys, PII) in JSON logs is a significant security risk. JSON's flexible structure makes it easy to accidentally include more data than intended, which can violate privacy regulations.
fix
Implement strict data filtering and redaction mechanisms *before* data reaches the logger. Carefully review `extra` dictionaries and any objects passed for serialization to ensure no sensitive information is present.
affects: All versions
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'json_log_formatter'
The `json-log-formatter` package is not installed in the current Python environment or there's a typo in the import statement.
fix
Ensure the package is correctly installed using pip: `pip install json-log-formatter`
ValueError: Formatting field not found in record: 'custom_field_name'
This error occurs when the formatter's `fmt` string (or a custom `json_record` method) expects a `LogRecord` attribute, such as `custom_field_name`, that is not present in the log record being processed. This often happens when `extra` fields are not consistently provided or not correctly integrated into the formatter's logic.
fix
When using a custom field in the formatter, ensure it's always provided via the `extra` dictionary in your logging calls, or implement a custom `json_record` method in a subclass of `JSONFormatter` to handle missing fields gracefully by providing a default value or skipping them.

Example with `extra`:
```python
import logging
from json_log_formatter import JSONFormatter

class CustomFormatter(JSONFormatter):
    def json_record(self, message: str, extra: dict, record: logging.LogRecord) -> dict:
        extra['message'] = message
        # Add 'custom_field_name' with a default if not present
        extra['custom_field_name'] = extra.get('custom_field_name', 'N/A')
        if 'time' not in extra:
            from datetime import datetime, timezone
            extra['time'] = datetime.now(timezone.utc).isoformat()
        return extra

formatter = CustomFormatter()
handler = logging.StreamHandler()
handler.setFormatter(formatter)
logger = logging.getLogger('my_app')
logger.addHandler(handler)
logger.setLevel(logging.INFO)

logger.info('Log with custom field', extra={'custom_field_name': 'value1'})
logger.info('Log without custom field') # This will now default to 'N/A'
```
TypeError: Object of type X is not JSON serializable
You are attempting to log a Python object (e.g., a `datetime` object, a custom class instance, or a SQLAlchemy model) in the `extra` dictionary or as part of the `LogRecord` attributes that the default `json` library cannot serialize into a JSON string.
fix
Implement a custom `mutate_json_record` method in a subclass of `JSONFormatter` to convert non-serializable objects into a serializable format (like strings) before JSON serialization.

```python
import logging
from json_log_formatter import JSONFormatter
from datetime import datetime

class MyNonSerializableObject:
    def __init__(self, value):
        self.value = value
    def __str__(self):
        return f"MyObject: {self.value}"

class CustomJSONFormatter(JSONFormatter):
    def mutate_json_record(self, json_record: dict) -> dict:
        for key, value in json_record.items():
            if isinstance(value, datetime):
                json_record[key] = value.isoformat()
            elif isinstance(value, MyNonSerializableObject):
                json_record[key] = str(value) # Convert to string
        return super().mutate_json_record(json_record)

formatter = CustomJSONFormatter()
handler = logging.StreamHandler()
handler.setFormatter(formatter)
logger = logging.getLogger('my_app')
logger.addHandler(handler)
logger.setLevel(logging.INFO)

logger.info('Logging custom object', extra={'my_data': MyNonSerializableObject('test_data'), 'current_time': datetime.now()})
```
Upgrade
Version history
1.2.1latest on PyPI · released Jun 8, 2026
Audit
Dependencies

No dependency data recorded yet.

Agent activity
15 hits · last 30 days
node
12
OpenAI (training)
2
Resources
json-log-formatter — pip install json-log-formatter · libregistry