A crazy simple way to use Structlog.
Project description
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
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file termalogger-1.0.0.tar.gz.
File metadata
- Download URL: termalogger-1.0.0.tar.gz
- Upload date:
- Size: 18.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f1548a52bab5cec4147b41721f27225ce4caa33367a376ffc0fee921a691e245
|
|
| MD5 |
2bfad4b057632350f7019d34776a1568
|
|
| BLAKE2b-256 |
cbc6099a35dad35c476e1ba047bd84f9224d7cadac83ae87054e90d91ff2b52a
|
Provenance
The following attestation bundles were made for termalogger-1.0.0.tar.gz:
Publisher:
auto-publish.yml on Zentheon/termalogger
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
termalogger-1.0.0.tar.gz -
Subject digest:
f1548a52bab5cec4147b41721f27225ce4caa33367a376ffc0fee921a691e245 - Sigstore transparency entry: 454237273
- Sigstore integration time:
-
Permalink:
Zentheon/termalogger@a21d5a1cbf6d0db4abd0b7adeedb70f53f126868 -
Branch / Tag:
refs/tags/1.0.0 - Owner: https://github.com/Zentheon
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
auto-publish.yml@a21d5a1cbf6d0db4abd0b7adeedb70f53f126868 -
Trigger Event:
push
-
Statement type:
File details
Details for the file termalogger-1.0.0-py3-none-any.whl.
File metadata
- Download URL: termalogger-1.0.0-py3-none-any.whl
- Upload date:
- Size: 20.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
01b7bc424c8a614382ff364e562c5f745906fa719eae6ac7aada9355d0d82c84
|
|
| MD5 |
cbc5d3637929c90300531ee058bd9e5d
|
|
| BLAKE2b-256 |
0f79fed4ae5e6665f26d2d16b032bd9c132fd812bcd9e782a1836afd7bc8bccc
|
Provenance
The following attestation bundles were made for termalogger-1.0.0-py3-none-any.whl:
Publisher:
auto-publish.yml on Zentheon/termalogger
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
termalogger-1.0.0-py3-none-any.whl -
Subject digest:
01b7bc424c8a614382ff364e562c5f745906fa719eae6ac7aada9355d0d82c84 - Sigstore transparency entry: 454237292
- Sigstore integration time:
-
Permalink:
Zentheon/termalogger@a21d5a1cbf6d0db4abd0b7adeedb70f53f126868 -
Branch / Tag:
refs/tags/1.0.0 - Owner: https://github.com/Zentheon
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
auto-publish.yml@a21d5a1cbf6d0db4abd0b7adeedb70f53f126868 -
Trigger Event:
push
-
Statement type: