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-formatterVerified import paths — ran on the pinned version, not inferred.
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.
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.
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.
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.
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.
Ensure the package is correctly installed using pip: `pip install json-log-formatter`
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'
```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()})
```No dependency data recorded yet.