Skip to main content

A modern, friendly Python logging library with colors, rotation, JSON output, context binding and decorators.

Project description

logthisx

A modern, friendly Python logging library with sensible defaults, colored console output, rotating files, structured JSON, context binding, and decorators. Built on top of the standard logging module so it composes naturally with the rest of the Python ecosystem.

PyPI Python versions License: MIT CI


Table of contents

Why logthisx

  • Looks good in your terminal out of the box, without forcing you to know the logging.config DSL.
  • Plays nicely with the standard library: every logthisx logger is a logging.Logger, so third-party libraries that already use logging inherit your configuration.
  • No mandatory third-party dependency. rich support is available as an optional extra.
  • Structured logging built in: JSON formatter with a stable schema for Docker, CI, log aggregators and observability tools.
  • Practical features that are tedious to wire up by hand: rotation, context binding, decorators, redaction.

Installation

pip install logthisx

With the optional rich extra for fancier console output:

pip install "logthisx[rich]"

logthisx supports Python 3.9 to 3.13.

Quickstart

from logthisx import configure, logger

configure(level="INFO", console=True, file="logs/app.log")

logger.info("Application started")
logger.success("Operation completed")
logger.warning("Something looks wrong")
logger.error("Something failed")
logger.debug("Debug value", extra={"value": 42})

You can also retrieve named loggers:

from logthisx import configure, get_logger

configure(level="DEBUG", console=True)

log = get_logger("my.app")
log.info("Ready")

The package is side-effect free on import: it does not touch the root logger unless you ask for it explicitly (logger_name="root").

Configuration

configure() is the single entry point that wires handlers and formatters together. It is idempotent: calling it again replaces the handlers it previously installed, so duplicated log lines are not a concern.

from logthisx import configure

configure(
    level="INFO",
    console=True,
    console_json=False,
    detailed=False,
    show_time=True,
    time_format="%Y-%m-%d %H:%M:%S",
    use_color=None,
    file="logs/app.log",
    file_json=False,
    max_bytes=5 * 1024 * 1024,
    backup_count=5,
    redact=True,
    custom_levels=False,
    logger_name="logthisx",
    propagate=False,
)

Alternatively, build a Config and pass it in:

from logthisx import Config, configure

cfg = Config(level="DEBUG", file="logs/app.log", file_json=True)
configure(config=cfg)

Or read it from the environment:

from logthisx import Config, configure

configure(config=Config.from_env())

Recognized environment variables (default prefix LOGTHISX_):

Variable Description
LOGTHISX_LEVEL Log level (DEBUG, INFO, WARNING, ...)
LOGTHISX_CONSOLE Enable console handler (1/0)
LOGTHISX_JSON Use JSON console output (1/0)
LOGTHISX_DETAILED Include module/function/line in console (1/0)
LOGTHISX_FILE Path to the log file
LOGTHISX_MAX_BYTES Rotation threshold in bytes
LOGTHISX_BACKUP_COUNT Number of rotated files to keep
LOGTHISX_REDACT Enable redaction of sensitive keys (1/0)

Console logging

The default console formatter is a colorized, compact one-liner. Colors are auto-detected based on whether stderr is a TTY; set use_color=True/False to force the behavior, or set NO_COLOR=1 / FORCE_COLOR=1 in the environment.

Enable the detailed mode to include module.function:line:

configure(level="DEBUG", console=True, detailed=True)

File logging

configure(file="logs/app.log") installs a RotatingFileHandler that:

  • Creates the parent directory if it does not exist.
  • Uses UTF-8 encoding by default.
  • Rotates the file once it reaches max_bytes (default 5 MiB).
  • Keeps backup_count historical files (default 5).
  • Returns a no-op handler and prints a warning if the file cannot be opened, so logging never crashes the host application.

JSON logging

Set console_json=True or file_json=True to switch to the JSON formatter. The schema is stable across releases and looks like:

{
  "timestamp": "2026-01-02T15:04:05.123456+00:00",
  "level": "INFO",
  "logger": "my.app",
  "module": "api",
  "function": "handle_request",
  "line": 42,
  "message": "Request received",
  "extra": {"request_id": "abc"},
  "exception": {
    "type": "ValueError",
    "message": "boom",
    "traceback": "..."
  }
}

extra is always present (possibly empty). exception is only present when the record carries exception information. Timestamps are ISO 8601 with explicit UTC offset.

Context binding

Attach structured context to every record without repeating yourself:

from logthisx import get_logger

log = get_logger("api").bind(request_id="abc123", user_id=42)
log.info("Request received")
log.info("Cache hit", extra={"cache_key": "users:42"})

bind() returns a new logger; the parent is not mutated. Chain calls to extend the context, and use unbind("user_id") to drop a key.

The context shows up in console output, in files and in JSON payloads.

Decorators

from logthisx.decorators import log_call, log_errors, log_time

@log_call(level="DEBUG", include_args=True)
def add(a, b):
    return a + b

@log_time(threshold_ms=50.0)
def slow_path():
    ...

@log_errors()
def risky():
    raise RuntimeError("boom")

All three decorators support both def and async def functions. They are cheap when the relevant level is disabled (a single isEnabledFor check).

Custom levels

logthisx ships with three extra levels:

Constant Value Default name
SUCCESS 25 SUCCESS
ALERT 35 ALERT
SPECIAL 45 SPECIAL

They are registered automatically when configure(custom_levels=True) is called, and exposed as methods (logger.success, logger.alert, logger.special).

Optional short aliases (II, DD, SS, WW, AA, EE, AZ, CC) can be turned on with custom_level_aliases=True. They are off by default to avoid polluting the global namespace for users who prefer standard names.

Exceptions

Use logger.exception("message") from inside an except: block. The traceback is rendered cleanly in the console and stored verbatim in files and inside the exception.traceback field of JSON records.

try:
    risky()
except Exception:
    logger.exception("risky failed")

Redaction

extra dictionaries are scanned for sensitive keys (password, token, api_key, secret, authorization, ...) and their values are replaced by *** before being written. Set configure(redact=False) to disable, or pass a custom set of keys to the formatters directly if you need a tighter or looser policy.

The redaction does not inspect the free-form message text. Replacing arbitrary substrings in messages is unreliable and gives a false sense of security. Pass secrets through extra so the redaction can do its job.

CLI

logthisx --version
logthisx demo            # Emit one record per level so you can preview output
logthisx demo --json     # Same, but in JSON
logthisx doctor          # End-to-end self-check (console, file, rotation, JSON)

logthisx demo is also handy for verifying that your terminal renders the colors correctly.

Migration from 0.1.x

logthisx 0.1 exposed four module-level functions:

from logthis import log_info, log_warn, log_error, enable_file_logging

enable_file_logging("logs/app.log")
log_info("hello")

These keep working in 0.2.0 but emit DeprecationWarning. The recommended new API is:

from logthisx import configure, logger

configure(level="INFO", console=True, file="logs/app.log")
logger.info("hello")
logger.warning("careful")
logger.error("broken")

See MIGRATION.md for the full guide.

Development

git clone https://github.com/laxyny/logthis.git
cd logthis
python -m pip install -e ".[dev]"
python -m ruff check src tests
python -m ruff format --check src tests
python -m pytest
python -m build

Contributions are welcome; see CONTRIBUTING.md.

License

Released under the MIT License.

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

logthisx-0.2.0.tar.gz (29.6 kB view details)

Uploaded Source

Built Distribution

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

logthisx-0.2.0-py3-none-any.whl (25.6 kB view details)

Uploaded Python 3

File details

Details for the file logthisx-0.2.0.tar.gz.

File metadata

  • Download URL: logthisx-0.2.0.tar.gz
  • Upload date:
  • Size: 29.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.13

File hashes

Hashes for logthisx-0.2.0.tar.gz
Algorithm Hash digest
SHA256 ff4cfbbe572da122ca0a8b8209b9360aeb0982378b5b9f627acc2b434d0aa713
MD5 6b9adb27cf68573778379d1a5a670459
BLAKE2b-256 2c0628225c0ad69cee41d98e29639b5e29d12727117d9e9a5a695cabfd4df86b

See more details on using hashes here.

File details

Details for the file logthisx-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: logthisx-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 25.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.13

File hashes

Hashes for logthisx-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6af1787c4fba6df74561d7e791ef8229229f1a57c6ec8128781dcfeba69c196c
MD5 7655c0bd6c33c389bbcb8c30e04cc6e4
BLAKE2b-256 3eaaa288f8a79f0eff030e7954f33562a20d5f74ae3764f74cdde526cfa31b53

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