gen3logging
Logging routines to centralize format.
Basic usage
In the parent/root module:
from gen3logging import get_logger
logger = get_logger("{{service_name}}", log_level='info')
logger.info('Hello world!')
In a child module:
from gen3logging import get_logger
logger = get_logger(__name__)
logger.info('Hello world!')
logger = get_logger(__name__, log_level='debug')
logger.debug('I am a child logger but I now have my own custom log level!')
You must set the logging level on the parent logger!
Inheritance is by dotted name, so the root logger's name must be a prefix of the
child module's __name__. Naming the root after the top-level package (a module
in fence/auth.py has __name__ == "fence.auth", which inherits from fence)
is what makes this work. A root name that is not a prefix of its modules' names
gets no children.
The default log_level argument in get_logger is None, which means the default logging level for new loggers is NOTSET. This means that child loggers whose levels were not explicitly set will inherit logging levels and handlers from ancestor loggers. This makes it easier to do things like change application-wide logging levels by just setting the level on the parent logger. Levels and handlers can still be individually set on child nodes by providing a log_level argument.
See more about Python logging here.
Parameters
get_logger takes:
logger_name- name of the logger, orNonefor the root loggerfile_name(default:None) - if present, the logger will output logs to a file as well as stdoutlog_level(default:None) - one ofnotset,debug,info,warning,warn,error,critical, in any case. Anything else raisesValueErrorformat(default:None, meaning the format below) -%-style format string for text outputjson_logs(default:None, meaning theGEN3_JSON_LOGSenv var decides) - emit JSON instead of text
file_name, format and json_logs only apply when a logger first gets its
handlers, on the first call that sets a level other than notset. Calling
get_logger again for the same logger keeps its existing handlers, so set
GEN3_JSON_LOGS to switch a whole service to JSON regardless of call order.
Output format
By default logs are plain text:
[2025-01-15 12:22:04,031][ fence][ INFO] user logged in
When OpenTelemetry is active, trace context is appended automatically:
[2025-01-15 12:22:04,031][ fence][ INFO] user logged in [trace_id=4bf92f3577b34da6a3ce929d0e0e4736 span_id=00f067aa0ba902b7 service=fence]
The suffix carries only the fields that are available, and is absent entirely
when none are. It follows the message, ahead of any traceback or stack.
gen3logging does not depend on OpenTelemetry: populate these by
installing opentelemetry-instrumentation-logging and calling
LoggingInstrumentor().instrument(). Nothing needs to change here to pick them
up, and nothing fails when they are missing.
trace_id and span_id are either a usable id or absent.
Any %-style format string can replace the default:
logger = get_logger("gen3foo", log_level='info', format="%(levelname)s %(message)s")
Enabling JSON Logs
Set json_logs=True to emit one JSON object per line instead of the default format:
logger = get_logger("gen3foo", log_level='info', json_logs=True)
{"timestamp": "2025-01-15T18:22:04.031Z", "logger": "fence.auth", "level": "INFO", "message": "user logged in", "trace_id": null, "span_id": null, "service": null}
| Key | Value |
|---|---|
timestamp |
ISO 8601 UTC, millisecond precision |
logger |
logger name |
level |
level name, e.g. INFO |
message |
the formatted message, with %-style arguments interpolated |
trace_id, span_id, service |
OpenTelemetry correlation, null when unavailable |
exception |
traceback text, present only on records that carry exception info |
stack_info |
stack text, present only on records logged with stack_info=True |
Fields passed through a logging call's extra= are not included.
Because the message and traceback are JSON-escaped, a multi-line traceback stays on a single log line and can be parsed by a log aggregator without stitching.
To turn JSON on for a deployment without a code change, set the
GEN3_JSON_LOGS environment variable:
GEN3_JSON_LOGS=true
An explicit json_logs argument always wins over the environment variable, so a
service can force either format. When json_logs is omitted the environment
variable decides, and when neither is set, output is text. Enabling JSON
supersedes any format string.
Migrating from cdislogging
- Replace the
cdisloggingdependency withgen3logging>=2.0.0. - Replace
from cdislogging import ...withfrom gen3logging import ....
That is the whole migration. Output is identical to cdislogging 1.2.0
until you enable JSON or instrument with OpenTelemetry.
NOTE: The library also now contains a PEP 561 py.typed marker, which tells type checkers to enforce our typing.
Metadata
Release files for gen3logging 2.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 | |
|---|---|---|---|
| gen3logging-2.0.0.tar.gz | 10.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| gen3logging-2.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 22.5 kB
Release files / gen3logging-2.0.0.tar.gz
| Download URL | gen3logging-2.0.0.tar.gz |
|---|---|
| Size | 10.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
0c337f47132c16152a69de93e58e83a9b97123e67008a530d32d6d88dd9693eb
|
|
BLAKE2b-256 checksum How to use checksums |
5648789b277168e45395294fa809cdb56ab5a58cc1e7275a797ce91347fe165e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.5.1 CPython/3.13.16 Linux/6.17.0-1022-azure
|
Release files / gen3logging-2.0.0-py3-none-any.whl
| Download URL | gen3logging-2.0.0-py3-none-any.whl |
|---|---|
| Size | 12.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
43b8adae8698e72481b9ba6ffe5c1ecdebc25e772b79f5cd7a4b890a5e03d89b
|
|
BLAKE2b-256 checksum How to use checksums |
0cf92eb951c0a7285a5773fa8c12b95c8af4949a2af5c81763814b1339410fc0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.5.1 CPython/3.13.16 Linux/6.17.0-1022-azure
|