Skip to main content

The library helps you to store logs in JSON format. Why is it important? Well, it facilitates integration with Logstash.

Usage example:

import logging

import json_log_formatter

formatter = json_log_formatter.JSONFormatter()

json_handler = logging.FileHandler(filename='/var/log/my-log.json')
json_handler.setFormatter(formatter)

logger = logging.getLogger('my_json')
logger.addHandler(json_handler)
logger.setLevel(logging.INFO)

logger.info('Sign up', extra={'referral_code': '52d6ce'})

try:
    raise ValueError('something wrong')
except ValueError:
    logger.error('Request failed', exc_info=True)

The log file will contain the following log record (inline).

{
    "message": "Sign up",
    "time": "2015-09-01T06:06:26.524448+00:00",
    "referral_code": "52d6ce"
}
{
    "message": "Request failed",
    "time": "2015-09-01T06:06:26.524449+00:00",
    "exc_info": "Traceback (most recent call last): ..."
}

If you use a log collection and analysis system, you might need to include the built-in log record attributes with VerboseJSONFormatter.

json_handler.setFormatter(json_log_formatter.VerboseJSONFormatter())
logger.error('An error has occured')
{
    "filename": "tests.py",
    "funcName": "test_file_name_is_testspy",
    "levelname": "ERROR",
    "lineno": 276,
    "module": "tests",
    "name": "my_json",
    "pathname": "/Users/bob/json-log-formatter/tests.py",
    "process": 3081,
    "processName": "MainProcess",
    "stack_info": null,
    "thread": 4664270272,
    "threadName": "MainThread",
    "message": "An error has occured",
    "time": "2021-07-04T21:05:42.767726+00:00"
}

If you need to flatten complex objects as strings, use FlatJSONFormatter.

json_handler.setFormatter(json_log_formatter.FlatJSONFormatter())
logger.error('An error has occured')

logger.info('Sign up', extra={'request': WSGIRequest({
    'PATH_INFO': 'bogus',
    'REQUEST_METHOD': 'bogus',
    'CONTENT_TYPE': 'text/html; charset=utf8',
    'wsgi.input': BytesIO(b''),
})})
{
    "message": "Sign up",
    "time": "2024-10-01T00:59:29.332888+00:00",
    "request": "<WSGIRequest: BOGUS '/bogus'>"
}

JSON libraries

You can use ujson or simplejson instead of built-in json library.

import json_log_formatter
import ujson

formatter = json_log_formatter.JSONFormatter()
formatter.json_lib = ujson

Django integration

Here is an example of how the JSON formatter can be used with Django.

LOGGING['formatters']['json'] = {
    '()': 'json_log_formatter.JSONFormatter',
}
LOGGING['handlers']['json_file'] = {
    'level': 'INFO',
    'class': 'logging.FileHandler',
    'filename': '/var/log/my-log.json',
    'formatter': 'json',
}
LOGGING['loggers']['my_json'] = {
    'handlers': ['json_file'],
    'level': 'INFO',
}

Let’s try to log something.

import logging

logger = logging.getLogger('my_json')

logger.info('Sign up', extra={'referral_code': '52d6ce'})

Custom formatter

You will likely need a custom log formatter. For instance, you want to log a user ID, an IP address and time as django.utils.timezone.now(). To do so you should override JSONFormatter.json_record().

class CustomisedJSONFormatter(json_log_formatter.JSONFormatter):
    def json_record(self, message: str, extra: dict, record: logging.LogRecord) -> dict:
        extra['message'] = message
        extra['user_id'] = current_user_id()
        extra['ip'] = current_ip()

        # Include builtins
        extra['level'] = record.levelname
        extra['name'] = record.name

        if 'time' not in extra:
            extra['time'] = django.utils.timezone.now()

        if record.exc_info:
            extra['exc_info'] = self.formatException(record.exc_info)

        return extra

Let’s say you want datetime to be serialized as a timestamp. Override mutate_json_record to convert it.

class CustomisedJSONFormatter(json_log_formatter.JSONFormatter):
    def mutate_json_record(self, json_record):
        for attr_name, attr in json_record.items():
            if isinstance(attr, datetime):
                json_record[attr_name] = attr.timestamp()

        return json_record

Tests

$ pip install -r requirements.txt
$ tox

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

json_log_formatter-1.2.1.tar.gz (5.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

json_log_formatter-1.2.1-py3-none-any.whl (6.6 kB view details)

Uploaded Python 3

File details

Details for the file json_log_formatter-1.2.1.tar.gz.

File metadata

  • Download URL: json_log_formatter-1.2.1.tar.gz
  • Upload date:
  • Size: 5.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for json_log_formatter-1.2.1.tar.gz
Algorithm Hash digest
SHA256 1d4fd14495ad7e694aa576259ba81acaa69e6945d9d780f32ed25373d7d5ae93
MD5 40a71b04f652d0c7ac500f9ddc97bc6b
BLAKE2b-256 dfebcaf193a5c77e3d9c1604dfa86fe87d9096e014303497134f23f6196a7685

See more details on using hashes here.

File details

Details for the file json_log_formatter-1.2.1-py3-none-any.whl.

File metadata

File hashes

Hashes for json_log_formatter-1.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 1e40432466c911ba2d106a302314b1c3b0019de44c762bef94e8f23138a415a7
MD5 32135fc1330fe93a81b5fc8ebfb375b4
BLAKE2b-256 c5a1b11bca303b81d07d5a686254ecbee35771d6fd050bdf0524a0003aeca306

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

1.2.1 This release

2 files

1.1.1

1 file

1.1

1 file

1.0

1 file

0.5.2

1 file

0.5.1

1 file

0.5.0

1 file

0.4.0

1 file

0.3.1

1 file

0.3.0

1 file

0.2.0

2 files

0.1.0

1 file

0.0.2

1 file

0.0.1

1 file

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page