Package - Logger
Written by Joe Tilsed
Created: 24/11/2025
Overview
This package provides a structured logging system with JSON-formatted logs for Python applications. It supports scoped logging, categories, and structured messages, making it easier to handle complex logging scenarios in Python applications. The logger can output logs in JSON format, which is well-suited for down-stream log aggregation tools.
Source Code
The source code for this package can be found: https://bitbucket.org/joetilsed/jt_logger/src
Getting Started
The structured logger is designed to handle logs in a consistent JSON format with features like scopes and categories for better context management.
Install
pip install logger -i https://pkgs.dev.azure.com/bpsaasplatform/_packaging/Global-pypi/pypi/simple/
Basic Example
from logger import log
log.info("Application started")
Features
Basic Logging
The logger supports standard log levels such as debug, info, warning, error, and critical. Each log entry is output as a JSON object, which contains information such as timestamp, log level, message, and other metadata.
Logging with Scopes
You can define scopes for your logs, which provide additional context. These scopes can be pushed and popped as you enter or leave different logical sections of your code. Each log entry within a scope includes that scope's information.
Structured Logs with Extra Fields
Logs can contain additional structured information through the extra argument. This helps to provide detailed context for log entries in a structured manner.
Category-based Logging
The logger allows you to categorize your logs by setting a category name. This is helpful when you need to separate logs by functional area or concern.
Examples
Basic Log Example
from logger import log
log.info("Info message")
Example output:
{
"Timestamp": "2024-09-04T19:00:00.000Z",
"EventId": 0,
"LogLevel": "INFO",
"Category": "Program",
"Message": "Info message",
"State": {
"Message": "Info message",
"{OriginalFormat}": "Info message"
},
"Scopes": []
}
Scoped Log Example
Using scopes, you can add contextual information to the logs:
from logger import log
log.push_scope("SpanId:1e0c3d2ebcf9e1b7, TraceId:1af7651916cd43dd8448eb211c80319c, ParentId:0000000000000000")
log.info("User login started")
log.pop_scope()
log.info("User login finished")
Example output:
{
"Timestamp": "2024-09-04T19:00:00.000Z",
"EventId": 0,
"LogLevel": "INFO",
"Category": "Program",
"Message": "User login started",
"State": {
"Message": "User login started",
"{OriginalFormat}": "User login started"
},
"Scopes": [
{
"Message": "SpanId:1e0c3d2ebcf9e1b7, TraceId:1af7651916cd43dd8448eb211c80319c, ParentId:0000000000000000",
"SpanId": "1e0c3d2ebcf9e1b7",
"TraceId": "1af7651916cd43dd8448eb211c80319c",
"ParentId": "0000000000000000"
}
]
}
{
"Timestamp": "2024-09-04T19:00:00.001Z",
"EventId": 0,
"LogLevel": "INFO",
"Category": "Program",
"Message": "User login finished",
"State": {
"Message": "User login finished",
"{OriginalFormat}": "User login finished"
},
"Scopes": []
}
Category Log Example
Categorizing logs is useful when you want to differentiate log entries by module or functionality.
from logger import log
log.set_category("Authentication")
log.info("Login attempt for user 123")
log.set_category("DataProcessing")
log.info("Started data processing task")
Example output:
{
"Timestamp": "2024-09-04T19:00:00.000Z",
"EventId": 0,
"LogLevel": "INFO",
"Category": "Authentication",
"Message": "Login attempt for user 123",
"State": {
"Message": "Login attempt for user 123",
"{OriginalFormat}": "Login attempt for user 123"
},
"Scopes": []
}
{
"Timestamp": "2024-09-04T19:00:00.001Z",
"EventId": 0,
"LogLevel": "INFO",
"Category": "DataProcessing",
"Message": "Started data processing task",
"State": {
"Message": "Started data processing task",
"{OriginalFormat}": "Started data processing task"
},
"Scopes": []
}
Error Handling Log Example
Log exceptions or errors along with structured context:
from logger import log
try:
1 / 0 # This will raise an exception
except ZeroDivisionError as e:
log.error("An error occurred during calculation: {error}", event_id=1001, error=str(e))
Example output:
{
"Timestamp": "2024-09-04T19:00:00.000Z",
"EventId": 0,
"LogLevel": "ERROR",
"Category": "Program",
"Message": "An error occurred during calculation: division by zero",
"State": {
"Message": "An error occurred during calculation: division by zero",
"{OriginalFormat}": "An error occurred during calculation: {error}",
"error": "division by zero"
},
"Scopes": []
}
Customization
Logger Name
You can customize the logger name using the environment variable LOG_NAME or programmatically when setting up the logger:
from logger import setup_logger
custom_logger = setup_logger(name="CustomLogger")
custom_logger.info("This is a custom logger")
Log Level
The log level can be set via the environment variable LOG_LEVEL or passed to the setup_logger function:
from logger import setup_logger
debug_logger = setup_logger(level="DEBUG")
debug_logger.debug("This is a debug log")
Conclusion
This structured logger package is a powerful tool for managing complex logging needs in your Python application. With support for JSON-formatted logs, scopes, and categories, it helps in building a more organized, readable, and structured logging system.
If you have any issues or suggestions, feel free to open a pull request or reach out to Joe Tilsed.
# That's all folks....
Metadata
Release files for jt-logger 0.0.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 | Provenance | |
|---|---|---|---|---|
| jt_logger-0.0.1.tar.gz | 7.0 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| jt_logger-0.0.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 14.9 kB
Release files / jt_logger-0.0.1.tar.gz
| Download URL | jt_logger-0.0.1.tar.gz |
|---|---|
| Size | 7.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b8cd96f9424b8f3f29afbef006a974edb41366e043718c6bef4907be3e27e05b
|
|
BLAKE2b-256 checksum How to use checksums |
bafce652fc5ed5169c720e04570ee3577c1794b8452d83772629a6a49cd8bc98
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.7
|
Release files / jt_logger-0.0.1-py3-none-any.whl
| Download URL | jt_logger-0.0.1-py3-none-any.whl |
|---|---|
| Size | 7.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4060e8af4546f05c06cc1f965931050c292ba146e84e885f639f6d83c03f4c7d
|
|
BLAKE2b-256 checksum How to use checksums |
8790546e8e3526d136296d3bff69f56708307eda12e5c986e97e93ee5837011f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.7
|
Security for jt-logger 0.0.1
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.