{"id":2081,"library":"json-log-formatter","title":"JSON Log Formatter","description":"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.","status":"active","version":"1.1.1","language":"python","source_language":"en","source_url":"https://github.com/marselester/json-log-formatter","tags":["logging","json","formatter","logstash","structured logging","python"],"install":[{"cmd":"pip install json-log-formatter","lang":"bash","label":"Install stable version"}],"dependencies":[],"imports":[{"note":"This is the primary formatter class for basic JSON output.","symbol":"JSONFormatter","correct":"from json_log_formatter import JSONFormatter"},{"note":"Use this formatter to include all built-in log record attributes.","symbol":"VerboseJSONFormatter","correct":"from json_log_formatter import VerboseJSONFormatter"},{"note":"Use this formatter to flatten complex objects into strings.","symbol":"FlatJSONFormatter","correct":"from json_log_formatter import FlatJSONFormatter"}],"quickstart":{"code":"import logging\nimport sys\nfrom json_log_formatter import JSONFormatter\n\n# Configure a basic logger\nlogger = logging.getLogger('my_app')\nlogger.setLevel(logging.INFO)\n\n# Create a JSON formatter instance\nformatter = JSONFormatter()\n\n# Create a StreamHandler that writes to stdout\nhandler = logging.StreamHandler(sys.stdout)\nhandler.setFormatter(formatter)\n\n# Add the handler to the logger\nlogger.addHandler(handler)\n\n# Log some messages\nlogger.info('User signed up', extra={'user_id': 123, 'email': 'test@example.com'})\nlogger.warning('Payment failed', extra={'order_id': 'abc-123', 'reason': 'card declined'})\n\ntry:\n    raise ValueError('Something went wrong!')\nexcept ValueError:\n    logger.error('An unexpected error occurred', exc_info=True, extra={'transaction_id': 'xyz-456'})","lang":"python","description":"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."},"warnings":[{"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.","message":"As 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.","severity":"gotcha","affected_versions":">=0.3.0"},{"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.","message":"When 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.","severity":"gotcha","affected_versions":"All versions"},{"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.","message":"To 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.","severity":"gotcha","affected_versions":"All versions"},{"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.","message":"Logging 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.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"search_vec":"'1.1.1':45 'activ':50 'aggreg':31 'analysi':33 'appear':47 'approach':25 'current':42 'easier':27 'elasticsearch':38 'facilit':26 'formatt':3,8,14,63 'integr':28 'json':1,6,20,62 'json-log-formatt':5 'librari':9,40 'like':35 'log':2,7,13,17,24,30,59,61,66 'logstash':36,64 'maintain':51 'modern':57 'output':16 'practic':60 'provid':10 'python':12,58,67 'record':18 'regular':53 'string':21 'structur':23,65 'support':56 'system':34 'updat':54 'version':44","created_at":"2026-04-09T18:42:42.884345+00:00","updated_at":"2026-04-16T15:54:29.156489+00:00","problems":[{"fix":"Ensure the package is correctly installed using pip: `pip install json-log-formatter`","cause":"The `json-log-formatter` package is not installed in the current Python environment or there's a typo in the import statement.","error":"ModuleNotFoundError: No module named 'json_log_formatter'"},{"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.\n\nExample with `extra`:\n```python\nimport logging\nfrom json_log_formatter import JSONFormatter\n\nclass CustomFormatter(JSONFormatter):\n    def json_record(self, message: str, extra: dict, record: logging.LogRecord) -> dict:\n        extra['message'] = message\n        # Add 'custom_field_name' with a default if not present\n        extra['custom_field_name'] = extra.get('custom_field_name', 'N/A')\n        if 'time' not in extra:\n            from datetime import datetime, timezone\n            extra['time'] = datetime.now(timezone.utc).isoformat()\n        return extra\n\nformatter = CustomFormatter()\nhandler = logging.StreamHandler()\nhandler.setFormatter(formatter)\nlogger = logging.getLogger('my_app')\nlogger.addHandler(handler)\nlogger.setLevel(logging.INFO)\n\nlogger.info('Log with custom field', extra={'custom_field_name': 'value1'})\nlogger.info('Log without custom field') # This will now default to 'N/A'\n```","cause":"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.","error":"ValueError: Formatting field not found in record: 'custom_field_name'"},{"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.\n\n```python\nimport logging\nfrom json_log_formatter import JSONFormatter\nfrom datetime import datetime\n\nclass MyNonSerializableObject:\n    def __init__(self, value):\n        self.value = value\n    def __str__(self):\n        return f\"MyObject: {self.value}\"\n\nclass CustomJSONFormatter(JSONFormatter):\n    def mutate_json_record(self, json_record: dict) -> dict:\n        for key, value in json_record.items():\n            if isinstance(value, datetime):\n                json_record[key] = value.isoformat()\n            elif isinstance(value, MyNonSerializableObject):\n                json_record[key] = str(value) # Convert to string\n        return super().mutate_json_record(json_record)\n\nformatter = CustomJSONFormatter()\nhandler = logging.StreamHandler()\nhandler.setFormatter(formatter)\nlogger = logging.getLogger('my_app')\nlogger.addHandler(handler)\nlogger.setLevel(logging.INFO)\n\nlogger.info('Logging custom object', extra={'my_data': MyNonSerializableObject('test_data'), 'current_time': datetime.now()})\n```","cause":"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.","error":"TypeError: Object of type X is not JSON serializable"}],"ecosystem":"pypi","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":"1.2.1","cli_name":"","cli_version":null,"type":"library","homepage":null,"github":"https://github.com/marselester/json-log-formatter","docs":null,"changelog":null,"pypi":"https://pypi.org/project/json-log-formatter/","npm":null,"openapi_spec":null,"status_page":null,"smithery":null,"categories":["observability","serialization"],"base_url":null,"auth_type":null,"provenance":{"verified_status":"passing","verified_at":"2026-06-28","last_verified":"2026-08-28","next_check":"2026-07-28","install_tag":null}}