Skip to main content

stlog

Python Badge UV Badge Task Badge Mergify Badge Renovate Badge MIT Licensed

Full documentation

What is it?

STandard STructured LOG (stlog) is Python 3.7+ structured logging library:

  • built on standard python logging and contextvars
  • very easy to configure with "good/opinionated" default values
  • which produces great output for both humans and machines
  • which believes in Twelve-Factor App principles about config and logs
  • dependency free (but can use fancy stuff (colors, augmented traceback...) from the rich library (if installed))

Features

  • standard, standard, standard: all stlog objects are built on standard python logging and are compatible with:
    • other existing handlers, formatters...
    • libraries which are using a standard logger (and stlog can automatically reinject the global context in log records produced by these libraries)
  • easy shorcuts to configure your logging
  • provides nice outputs for humans AND for machines (you can produce both at the same time)
  • structured with 4 levels of context you can choose or combine:
    • a global one set by environment variables (read at process start)
    • a kind of smart global one (thanks to contextvars)
    • a context linked to the logger object itself (defined during its building)
    • a context linked to the log message itself
  • a lot of configuration you can do with environment variables (in the spirit of Twelve-Factor App principles)

Non-Features

  • "A twelve-factor app never concerns itself with routing or storage of its output stream."
    • we are going to make an exception on this for log files
    • but we don't want to introduce complex/network outputs like syslog, elasticsearch, loki...
  • standard, standard, standard: we do not want to move away from standard python logging compatibility

What is structured logging?

Structured logging is a technique used in software development to produce log messages that are more easily parsed and analyzed by machines. Unlike traditional logging, which typically consists of free-form text messages, structured logging uses a well-defined format that includes named fields with specific data types.

The benefits of structured logging are many. By using a standard format, it becomes easier to automate the processing and analysis of logs. This can help with tasks like troubleshooting issues, identifying patterns, and monitoring system performance. It can also make it easier to integrate logs with other systems, such as monitoring and alerting tools.

Some common formats for structured logging include JSON, XML, and key-value pairs. In each case, the format includes a set of fields that provide information about the log message, such as the severity level, timestamp, source of the message, and any relevant metadata.

Structured logging is becoming increasingly popular as more developers recognize its benefits. Many logging frameworks and libraries now include support for structured logging, making it easier for developers to adopt the technique in their own projects.

(thanks to ChatGPT)

Quickstart

Installation

pip install stlog

Very minimal usage

import stlog

stlog.info("It works", foo="bar", x=123)
stlog.critical("Houston, we have a problem!")
 

Output (without rich library installed):

2023-03-29T14:48:37Z root [   INFO   ] It works {foo=bar x=123}
2023-03-29T14:48:37Z root [ CRITICAL ] Houston, we have a problem!
 

Output (with rich library installed):

rich output

Basic usage

from stlog import getLogger, setup

# Set the logging default configuration (human output on stderr)
setup()

# Get a logger
logger = getLogger(__name__)
logger.info("It works", foo="bar", x=123)
logger.critical("Houston, we have a problem!")
 

Output (without rich library installed):

2023-03-29T14:48:37Z __main__ [   INFO   ] It works {foo=bar x=123}
2023-03-29T14:48:37Z __main__ [ CRITICAL ] Houston, we have a problem!
 

Output (with rich library installed):

rich output

Usage with context

from stlog import LogContext, getLogger, setup

# Set the logging default configuration (human output on stderr)
setup()

# Get a logger
logger = getLogger(__name__)

# ...

# Set the (kind of) global execution context
# (thread, worker, async friendly: one context by execution)
# (for example in a wsgi/asgi middleware)

# You can do it through the logger with its `context` attribute (recommended):
logger.context.reset_context()
logger.context.add(request_id="4c2383f5")

# ...or through the LogContext static class directly (both are equivalent,
# logger.context *is* the LogContext static class):
LogContext.add(client_id=456, http_method="GET")

# ... in another file/class/...

logger.info("It works", foo="bar", x=123)
logger.critical("Houston, we have a problem!")
 

Output (without rich library installed):

2023-03-29T14:48:37Z __main__ [   INFO   ] It works {client_id=456 foo=bar http_method=GET request_id=4c2383f5 x=123}
2023-03-29T14:48:37Z __main__ [ CRITICAL ] Houston, we have a problem! {client_id=456 http_method=GET request_id=4c2383f5}
 

Output (with rich library installed):

rich output

What about if you want to get a more parsing friendly output (for example in JSON on stdout) while keeping the human output on stderr (without any context)?

import sys
from stlog import getLogger, setup
from stlog.output import StreamOutput
from stlog.formatter import HumanFormatter, JsonFormatter

setup(
    outputs=[
        StreamOutput(
            stream=sys.stderr,
            formatter=HumanFormatter(exclude_extras_keys_fnmatchs=["*"]),
        ),
        StreamOutput(stream=sys.stdout, formatter=JsonFormatter(indent=4)),
    ]
)

logger = getLogger(__name__)

# See previous example for details
logger.context.reset_context()
logger.context.add(request_id="4c2383f5")
logger.context.add(client_id=456, http_method="GET")
logger.info("It works", foo="bar", x=123)
logger.critical("Houston, we have a problem!")
 

Human output (on stderr):

2023-03-29T14:48:37Z __main__ [   INFO   ] It works
2023-03-29T14:48:37Z __main__ [ CRITICAL ] Houston, we have a problem!
 

JSON ouput (on stdout) for machines:

{
    "client_id": 456,
    "foo": "bar",
    "http_method": "GET",
    "level": "INFO",
    "logger": "__main__",
    "message": "It works",
    "request_id": "4c2383f5",
    "source": {
        "funcName": "<module>",
        "lineno": 22,
        "module": "qs3",
        "path": "/path/filename.py",
        "process": 6789,
        "processName": "MainProcess",
        "thread": 12345,
        "threadName": "MainThread"
    },
    "time": "2023-03-29T14:48:37.000Z",
    "x": 123
}
{
    "client_id": 456,
    "http_method": "GET",
    "level": "CRITICAL",
    "logger": "__main__",
    "message": "Houston, we have a problem!",
    "request_id": "4c2383f5",
    "source": {
        "funcName": "<module>",
        "lineno": 23,
        "module": "qs3",
        "path": "/path/filename.py",
        "process": 6789,
        "processName": "MainProcess",
        "thread": 12345,
        "threadName": "MainThread"
    },
    "time": "2023-03-29T14:48:37.000Z"
}
 

Metadata

Release files for stlog 0.5.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for stlog 0.5.1
File Size Uploaded
stlog-0.5.1.tar.gz 19.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for stlog 0.5.1
File Interpreter ABI Platform
stlog-0.5.1-py3-none-any.whl Python 3 none any Details

Total release size: 42.2 kB

Release files / stlog-0.5.1.tar.gz

Download URL stlog-0.5.1.tar.gz
Size 19.1 kB
Tags Source
SHA-256 checksum
How to use checksums
1f54017e27ed60647ef273a773b910422010a2f157aed9c8f139f3989278b29d
BLAKE2b-256 checksum
How to use checksums
516c331fc923f30133b30467452095901d2a89b3c8261e92259449ce6a8e18fa
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.31 {"installer":{"name":"uv","version":"0.11.31","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / stlog-0.5.1-py3-none-any.whl

Download URL stlog-0.5.1-py3-none-any.whl
Size 23.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
66ac3fb1df24a8dd83c9bd08e19736585f7ba70b6134ab292eb8446490740ca3
BLAKE2b-256 checksum
How to use checksums
ef3120a47925d48be5fd53233199fe8bf07fa3b772aaec13e445c2ce5cc79e7e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.31 {"installer":{"name":"uv","version":"0.11.31","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

0.5.1 This release

2 release files

0.5.0

2 release files

0.4.7

2 release files

0.4.6

2 release files

0.4.5

2 release files

0.4.4

2 release files

0.4.3

2 release files

0.4.2

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

0.0.8

2 release files

0.0.7

2 release files

0.0.5

2 release files

0.0.4

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page