Everything you need to turn Python stdlib logging into a proper structured logging library. Rather than fighting logging, let’s live with it.
import logging
import logstruct
logging.basicConfig(level=logging.INFO)
logging.root.handlers[0].setFormatter(logstruct.StructuredFormatter())
log = logstruct.getLogger(__name__)
log.info("Message with data", key1="val1", data=object())
This prints the following JSON to stderr that, if pretty-printed, looks as follows:
{
"time": "2025-01-19 09:49:36,489",
"logger": "__main__",
"level": "INFO",
"func": "<module>",
"line": 8,
"message": "Message with data",
"key1": "val1",
"data": "<object object at 0x765a8a9806f0>"
}
Features
StructuredLogger <logstruct.StructuredLogger> - a replacement for logging.Logger with a simplified interface for adding structured data to logs. (Usage <logger_usage>)
StructuredFormatter <logstruct.StructuredFormatter> - a logging.Formatter implementation that formats log records as JSON. (Usage <formatter_usage>)
contextual information <context_usage> to log records with logstruct.context_scope.
Easy to use and simple to configure, no dependencies.
Seamlessly integrates with any code using stdlib logging, e.g. Sentry SDK.
Human readable output for development - see demo_dev_mode.py <dev_mode_logging>.
Design principles
Play well with logging.
Be small.
Considerations
If the standard logging library adds a new kwarg to log methods, e.g. logging.Logger.info, this kwarg, when passed to StructuredLogger, will be merged into the extra dict until it is added to StructuredLogger methods. Using StructuredLogger is optional.
Logging integrations that rely on monkey-patching logging.Formatter.format won’t see it called because StructuredFormatter doesn’t call this method. Such reliance is extremely unlikely.
Development
While the project source is dependency-free, PDM is used for management of dev (testing) and doc (Sphinx/ReadTheDocs) dependencies.
pdm install
You should be able to get away with not using PDM as long as you don’t change dependencies.
pip install --editable . -r requirements-dev.txt -r requirements-doc.txt
When dependencies are changed, they need to be locked. This will also write requirements-{dev,doc}.txt.
pdm lock -G :all
Tests are run with pytest and Sphinx’s doctest target.
pdm run pytest
pdm run sphinx-build docs docs/_build -b doctest
Setuptools-SCM and build are used for building the project. Publishing is done in the CI, using the old twine method, even though PDM could be used.
British English is used in the project, out of fear of losing my settled status.
Metadata
Release files for logstruct 0.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| logstruct-0.2.1.tar.gz | 54.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| logstruct-0.2.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 69.3 kB
Release files / logstruct-0.2.1.tar.gz
| Download URL | logstruct-0.2.1.tar.gz |
|---|---|
| Size | 54.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2ac69748ec2e32dca24bc72c902726517071286ab35b0614d26915279da35c6c
|
|
BLAKE2b-256 checksum How to use checksums |
ac1d0242a446f1ff64f42e23f619215c0a3c34f9c8dd76b2761fb97979a18175
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.9
|
Release files / logstruct-0.2.1-py3-none-any.whl
| Download URL | logstruct-0.2.1-py3-none-any.whl |
|---|---|
| Size | 14.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f35a913d11267a2a274f6ffb5934c411de31f54c8af7581e16f588b20b345820
|
|
BLAKE2b-256 checksum How to use checksums |
a3848ef2518ebe9cb0f999317b77694405407d3954ac7447650a6a317542bb55
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.9
|