Skip to main content

Simple minimalist Python logging defaults

Project description

ok-py-logging-setup

Simple, opinionated Python logging setup with env-var configuration, logspam limiting and minimalist formatting.

You probably won't want to use this. You should consider these libraries instead:

  • structlog - fancy logging system with interconnects to Python logging
  • Rich - pretty text formatter, includes a logging prettifier
  • Pretty Pie Log - logging prettifier
  • logging518 - configure logging in pyproject.toml (or another TOML file)
  • Easy Logging - logging setup with YAML configuration
  • setup logging for me - even more minimal and idiosyncratic than this package!

Opinion-ifesto

Python's standard logging facility is usable enough but (over)complicated with a tree of loggers with attached handlers, formatters, and filters configured in app code. There is an external configuration system with ini-files and/or a custom socket protocol (!) that can customize that whole tree of loggers, handlers, formatters, and filters.

Modern 12-factor-ish apps don't want most of this. Logging should just go to stderr in some reasonable format; the app runner (Docker, systemd, etc) takes it from there. We just want an easy way to dial verbosity up and down for the app or subsystems depending on what we're debugging. That's what this library does (plus a few other tweaks I like).

Also, most logging formatters spend too much real estate on log levels, source locations, full timestamps, and other metadata. This library adds a minimalist formatter that skips most of that (see below). You can always search the code to find a message's origin! (Stack traces are still printed for exceptions, don't worry.)

Usage

Add this package as a dependency:

  • pip install ok-py-logging-setup
  • OR just copy ok_logging_setup.py (it has no dependencies)

Import the module and call ok_logging_setup.install() near program start:

import ok_logging_setup
...
def main():
    ok_logging_setup.install()
    ... run your app ...

The ok_logging_setup.install() call does the following:

  • makes a root stderr logger via logging.basicConfig, with log level INFO to start
  • interprets $OK_LOGGING_* environment variables (described below)
  • adds a formatter with minimal, legible output (described below)
  • adds a filter with simple logspam-protection (described below)
  • adds uncaught exception handlers that use this logger (and exits)
  • changes sys.stdout to line buffered, so print and logs interleave correctly
  • resets control-C handling (SIGINT) to insta-kill (SIG_DFL), not Python's InterruptException nonsense

Advanced usage:

  • pass a string-string dict to ok_logging_setup.install({ ... }) to set defaults for configuration variables below
  • call ok_logging_setup.skip_traceback_for(SomeClass) to not print stack traces for exceptions of that type

After installation, use .info, .error, etc as normal on the logger module itself, or if you're fancy, use per-subsystem Logger objects to log messages for selective filtering (see $OK_LOGGING_LEVEL below).

Configuration

These variables can be set in the environment, or passed in a dict to ok_logging_setup.install({ ... }) (the environment takes precedence).

$OK_LOGGING_LEVEL (default INFO)

  • set to a log level (DEBUG, INFO, WARNING, ERROR, CRITICAL) to only print messages of that severity or higher
  • use loggertag=severity to set the log level for a specific logger tag, eg. my.library=DEBUG
  • combine the above with commas, eg. WARNING,my.library=DEBUG,noisy.library=CRITICAL

The most specific matching rule will apply to any given message, eg. in the last example above a logger named noisy.library.submodule would only print CRITICAL messages.

$OK_LOGGING_REPEAT_PER_MINUTE (default 10)

The number of messages with the same "signature" (message format with digits removed) allowed in one minute before being blocked by spam protection (see below). Set to 0 to disable the spam filter entirely.

$OK_LOGGING_TIME_FORMAT and $OK_LOGGING_TIMEZONE

  • to timestamp log messages, set $OK_LOGGING_TIME_FORMAT to a strftime format
  • if set, $OK_LOGGING_TIMEZONE (from this list) is used for timestamps

Spam protection

If logs get emitted in a tight loop somehow, it can slow code down, fill up disks, and generally make a bad day. To mitigate spam, ok_logging_setup.install adds a filter that checks if a log message with the same "signature" (format string with digits removed) more than N times in a one minute period, subsequent instances of that same "signature" are dropped until the minute rolls over. It looks like this:

12:34:00 Spam message 1
12:34:01 Spam message 2
12:34:02 Spam message 3
12:34:03 Spam message 4
12:34:04 Spam message 5
12:34:05 Spam message 6
12:34:06 Spam message 7
12:34:07 Spam message 8
12:34:08 Spam message 9
12:34:09 Spam message 10
12:34:10 Spam message 11 [suppressing until 12:35]
12:35:00 Spam message 61
12:35:01 Spam message 62
12:35:02 Spam message 63
12:35:03 Spam message 64
12:35:04 Spam message 65
12:35:05 Spam message 66
12:35:06 Spam message 67
12:35:07 Spam message 68
12:35:08 Spam message 69
12:35:09 Spam message 70
12:35:10 Spam message 71 [suppressing until 12:36]
12:36:00 Spam message 121
12:36:01 Spam message 122
...

The "suppressing until ..." messages are appended so you know when log messages are potentially skipped. Spam filtering can be tuned by setting $OK_LOGGING_REPEAT_PER_MINUTE to the maximum number of messages with the same signature to allow per minute, or 0 to disable the filter entirely.

Log format

By default, log messages include a severity icon (emoji) and the message:

🕸 This is a debug message
This is an INFO message
⚠️ This is a WARNING message    
🔥 This is an ERROR message
💥 This is a CRITICAL message

If the message is logged with a named Logger object, the name is added as a prefix:

🔥 foo: This is an error message reported with a Logger named "foo"

If the message is logged from a named thread or a named asyncio task, the name is included

🔥 <Thread Name> This is an error message in a thread
🔥 [Task Name] This is an error message in a task

If you want timestamps, set $OK_LOGGING_TIME_FORMAT (see above):

$ export OK_LOGGING_TIME_FORMAT="%m-%d %H:%M:%S"
...
04-30 22:53:26 🔥 This is an error message

Exceptions are formatted in the normal way:

💥 Uncaught exception
Traceback (most recent call last):
  File "/home/egnor/source/ok-py-logging-setup/try_ok_logging_setup.py", line 109, in <module>
    main()
  File "/home/egnor/source/ok-py-logging-setup/try_ok_logging_setup.py", line 55, in main
    raise Exception("This is an uncaught exception")
Exception: This is an uncaught exception

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ok_logging_setup-0.2.tar.gz (20.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ok_logging_setup-0.2-py3-none-any.whl (7.7 kB view details)

Uploaded Python 3

File details

Details for the file ok_logging_setup-0.2.tar.gz.

File metadata

  • Download URL: ok_logging_setup-0.2.tar.gz
  • Upload date:
  • Size: 20.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.5.28

File hashes

Hashes for ok_logging_setup-0.2.tar.gz
Algorithm Hash digest
SHA256 c8e73b89a2435bbbe3c27c62ae3700c2f7fdba027e1150ad904700272836e4c0
MD5 5e40f5cded2d82ae5f757c4f7b4226c9
BLAKE2b-256 6eda153c82ccf3d6eeb00d0f09dd7b3f1211fc51376735acecdcaa1093dfba97

See more details on using hashes here.

File details

Details for the file ok_logging_setup-0.2-py3-none-any.whl.

File metadata

File hashes

Hashes for ok_logging_setup-0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 102f97c395be5921f4b7275f1eefea40695deb2e67048733b1f3fe7f766728bb
MD5 0dece5dfcf34ccbbfbdebf555c5fdd97
BLAKE2b-256 1f8d3820c5a42cf6a8f1ae175e3d2aa92c84954001777ba94e7859f25fdcd3db

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page