Python

Collect logs directly from any Python code, including Django.

Example

It's very easy to start sending logs from your Python app to Logtail:

from logtail import LogtailHandler
import logging
handler = LogtailHandler(source_token="<your-source-token>")
logger = logging.getLogger(__name__)
logger.handlers = []
logger.addHandler(handler)
logger.info('logtail is ready')
logger.warning('log structured data', extra={
item: {
url: "https://fictional-store.com/item-123",
price: 100.00
}
})

The snippet above will send the following JSON rows to Logtail:

{
"dt": "2021-03-29T11:24:21.788451Z",
"level": "info",
"message": "logtail is ready",
"context": {
"runtime": {
"function": "function_name",
"file": "script_file.py",
"line": 10,
"thread_id": "123456789",
"thread_name": "async_thread",
"logger_name": "logger"
},
"system": {
"pid": 123456,
"process_name": "python"
}
}
}
{
"dt": "2021-03-29T11:24:21.788451Z",
"level": "warning",
"message": "logt structured data",
"item": {
"url": "https://fictional-store.com/item-123",
"price": 100.00
},
"context": {
"runtime": {
"function": "function_name",
"file": "script_file.py",
"line": 11,
"thread_id": "123456789",
"thread_name": "async_thread",
"logger_name": "logger"
},
"system": {
"pid": 123456,
"process_name": "python"
}
}
}

Installation

Install the Logtail client library from PyPI as you would with any other package:

pip install logtail-python

Make sure you install the logtail-python package and not a different package with the logtail keyword in the package name from a different author.

Usage

Our library contains a class LogtailHandler that is meant to be used with the default Python logger:

from logtail import LogtailHandler
import logging
handler = LogtailHandler(source_token="<your-source-token>", level=logging.INFO)
logger = logging.getLogger(__name__)
logger.handlers = []
logger.addHandler(handler)

Once the handler is registered, you can start logging by using the debug, info, warning, error, critical, or exception methods.

All of these methods expect a string message and they allow adding additional dictionary passed as an extra:

logger.info('logtail is ready')
logger.warning('log structured data', extra={
name: {
first: "John",
last: "Smith"
},
id: 123456
})

Context

By default, we add information about the current runtime environment and about the current process into a context field of the logged item.

If you want to add some custom information to all logged items (e.g., the ID of the current user), you can do so by adding a custom context:

with logtail.context(user={ 'id': 123 }):
# ...
logger.info('new subscription')

This snippet will produce the following JSON log:

{
"dt": "2021-03-29T11:24:21.788451Z",
"level": "info",
"message": "new subscription",
"context": {
"runtime": {
"function": "function_name",
"file": "script_file.py",
"line": 3,
"thread_id": "123456789",
"thread_name": "async_thread",
"logger_name": "logger"
},
"system": {
"pid": 123456,
"process_name": "python"
},
"user": {
"id": 123
}
}
}

Contexts can also be nested. In that case, the dictionaries will be merged.