What is TermaLogger
A straightworward, centralized way of using Structlog that makes common functionality dead simple and adds some nice extras along the way.
Usage
Simply import and create an instance of TermaLogger:
from termalogger import TermaLogger
log = TermaLogger("coolapp")
target_dir = Path("images/coolphotos")
for file in target_dir.iterdir():
log.info("Processing a photo...", label="photos", path=file)
...
You can provide a number of initial args, but the bound logger's name is the only required one.
The methodology behind TermaLogger follows that of the prevailant Twelve-Factor Logging, in that files are not of its concern. However, if you want that functionality, you can enable JSON output and set log.json_factory to use a factory such as structlog.BytesLoggerFactory(file="logfile"), where logfile is any Bytes file instance. Alternatively, you could do something like log.json_processors.append(log.line_tracker) and dump log.bytes_lines to a file, but using the line trackers is only really a good idea for tests.
Filtering
level - [__init__, settings, set_level] - (str | int)
Typical loglevel filtering. This uses Structlog's quite efficient make_filtering_bound_logger and is useful to set up the overall run environment. Can be either a number corresponding to a native loglevel or the level's name.
cache_logger_on_first_use - [__init__, settings] - (bool)
Directly corresponds to the Structlog opt: See Structlog performance docs
format_json - [__init__, set_json_output] - (bool)
Sets appropriate configurations for structured JSON output using orjson
filter - [__init__, settings, set_filter] - (list[str])
The real power behind LogWrapper is the label filtering. Labels effectively offer a much more versatile way of getting the information you want than jankily adding custom levels and trying to sift through them. This is the future, after all.
To use labels, simply add an event to a log message:
for fruit in fruit_list:
try:
log.debug("Processing a fruit...", labels=["fruit", "loop"], fruit=fruit)
# Do some fruity processing stuff
except Exception as exc:
log.error("Couldn't process a fruit!", label="fruit", fruit=fruit, exc_info=exc)
label and labels can be used interchangeably with either a single label or list of them. While debugging, you can start filtering out unwanted noise by setting:
log.settings(level="debug", filter={"debug": ["fruit"]})
Which would drop any debug messages not containing a "fruit" label.
Filtering is only performed on debug messages by default, meaning that if you set loglevel to debug, then any debug message with labels won't be shown if log.debug_filter=[] (default). This is not the case for higher levels unless you explicitly set log.set_filter({"warn": []}) or log.filter_enable["warn"] = True.
Tracking & Tests
Structlog's immensely powerful processor pipeline and the self-contained nature of using a class to pull its strings comes with another, quite convenient bonus: Event tracking. TermaLogger has three noteworthy attributes (lists) for keeping historical data:
self.events: Event dictionaries.self.str_lines: Rendered lines (strings)self.bytes_linesRendered lines (bytes)
Normally, these lists won't be populated with anything. It's only until you add the respective processors when they become useful:
from termalogger import TermaLogger
log = TermaLogger("app_tests")
# Event dictionary list
log.shared_processors.append(log.event_tracker)
# Rendered lines list (str or bytes, respectively)
log.console_processors.append(log.lines_tracker)
log.json_processors.append(log.lines_tracker)
# Recreate the logger with updated processors
log.settings()
At which point you'll see the aforementioned lists start to be populated by log entries! This is especially useful when building your tests, a more complete example of which can be found in TermaLogger's own test routines.
Other Stuff
Contributing
Contributions are very welcome!
- Issues: Don't hesitate to report something, even if it's as small as a semantics inconsistency.
- PRs: The main pointer to keep in mind is to take advantage Structlog's versatility wherever sensible when adding new things. Also ideally creating relevant tests!
Resources
- Come hang out and share cool stuff with the community on Discord!
- The (so far) one other project in the Terma* series: TermaConfig
License
Metadata
Release files for termalogger 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| termalogger-1.0.0.tar.gz | 18.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| termalogger-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 38.9 kB
Release files / termalogger-1.0.0.tar.gz
| Download URL | termalogger-1.0.0.tar.gz |
|---|---|
| Size | 18.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f1548a52bab5cec4147b41721f27225ce4caa33367a376ffc0fee921a691e245
|
|
BLAKE2b-256 checksum How to use checksums |
cbc6099a35dad35c476e1ba047bd84f9224d7cadac83ae87054e90d91ff2b52a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.12.9
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 31, 2025.
Transparency logRelease files / termalogger-1.0.0-py3-none-any.whl
| Download URL | termalogger-1.0.0-py3-none-any.whl |
|---|---|
| Size | 20.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
01b7bc424c8a614382ff364e562c5f745906fa719eae6ac7aada9355d0d82c84
|
|
BLAKE2b-256 checksum How to use checksums |
0f79fed4ae5e6665f26d2d16b032bd9c132fd812bcd9e782a1836afd7bc8bccc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.12.9
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 31, 2025.
Transparency log