Skip to main content

Lightweight, zero-dependency logging wrapper with structured output, context injection, and file rotation

Project description

logtie

Lightweight, zero-dependency logging wrapper for Python. Structured output, context injection, colored terminal, JSON files, and file rotation — all configured in one call.

import logtie.log as log

log.configure(
    name="myapp",
    level=log.DEBUG,
    stdout=log.Stdout(
        fmt=log.LogFmt("[timestamp] [level] - [message]"),
        datefmt=log.TimeFmt("[year]-[month]-[day] [hour]:[minute]:[second]"),
        colored=True,
    ),
    file=log.File(path="app.log", datefmt="iso", json=True),
)

log.bind(request_id="abc-123")
log.info("user logged in", user_id=42)
log.warning("slow query", duration_ms=340)

Installation

pip install logtie

Requires Python 3.14+. No external dependencies.

Quick start

1. Configure once at startup

import logtie.log as log

log.configure(
    name="myapp",       # logger name
    level=log.DEBUG,    # global minimum level
    stdout=True,        # terminal output with defaults
)

configure() accepts True / a plain path string as shorthand for either handler with default settings. Pass a Stdout or File instance to customise.

2. Log

log.debug("connecting to database")
log.info("server started", port=8080)
log.warning("high memory usage", used_mb=1800)
log.error("request failed", status=500, path="/checkout")
log.critical("service unreachable")

try:
    ...
except Exception:
    log.exception("unexpected error")   # includes full traceback

Keyword arguments are attached to the log record as extra fields — they appear in JSON output automatically.

3. Context injection

Inject fields once; they're included in every subsequent record until removed.

log.bind(request_id="req-001", user_id=42)

log.info("request started")     # → includes request_id + user_id
log.debug("validating payload") # → same

log.unbind("user_id")           # remove one key
log.clear_binds()               # remove all

Context is backed by contextvars, so it's thread-safe and asyncio-safe — bind() inside an asyncio task only affects that task.

Handlers

Terminal (Stdout)

log.Stdout(
    fmt=log.LogFmt("[timestamp] [level] - [message]"),
    datefmt=log.TimeFmt("[year]-[month]-[day] [hour]:[minute]:[second].[ms]"),
    colored=True,
    colors=log.Colors(
        debug=log.AnsiColor.BRIGHT_BLACK,
        info="#00D4AA",          # hex truecolor
        warning="#FFA500",
    ),
    level=log.DEBUG,
    only=[log.DEBUG, log.INFO],  # restrict to specific levels
)

File (File)

log.File(
    path="app.log",
    datefmt="iso",      # ISO 8601 timestamps
    json=True,          # one JSON object per line
    level=log.WARNING,
    rotate_size=5 * 1024 * 1024,  # rotate at 5 MB
    backup_count=7,
)

File rotation

Parameter Behaviour
rotate_size=N Rotate when file reaches N bytes
rotate_lines=N Rotate when file reaches N lines
backup_count=N Number of backup files to keep (default 5)

Both use the same rename scheme: app.logapp.log.1app.log.2

JSON field mapping

By default JSON records use:

asctime → "timestamp",  name → "logger",  levelname → "level",
message → "message",    funcName → "function",  lineno → "line"

Override with json_fmt:

log.File(
    path="app.log",
    json=True,
    json_fmt={"asctime": "ts", "levelname": "severity", "message": "msg"},
)

Any extra kwargs passed to log calls are added to the JSON object as-is.

Format tokens

LogFmt — log line layout:

Token Value
[timestamp] formatted timestamp
[level] level name (INFO, WARNING …)
[message] log body
[name] logger name
[function] function name
[line] line number
[module] module name
[path] full file path
[process] process ID
[thread] thread ID

TimeFmt — timestamp format:

Token Value
[year] 4-digit year
[month] 2-digit month
[day] 2-digit day
[hour] hour (24 h)
[minute] minute
[second] second
[ms] milliseconds
[tz] timezone offset

Pass datefmt="iso" to either handler for ISO 8601 output instead.

Level routing

Send different levels to different destinations:

log.configure(
    name="myapp",
    level=log.DEBUG,
    stdout=log.Stdout(only=[log.DEBUG, log.INFO]),          # terminal: verbose
    file=log.File(path="alerts.log", only=[log.WARNING, log.ERROR, log.CRITICAL]),
)

Asyncio

logtie is asyncio-safe out of the box. Use queue=True to offload handler I/O to a background thread and keep the event loop unblocked:

log.configure(name="myapp", level=log.DEBUG, stdout=True, queue=True)

bind() is task-local — context set inside one coroutine doesn't leak into sibling tasks.

Examples

The examples/ directory has runnable scripts covering every feature.

License

MIT

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

logtie-0.1.0.tar.gz (10.3 kB view details)

Uploaded Source

Built Distribution

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

logtie-0.1.0-py3-none-any.whl (13.0 kB view details)

Uploaded Python 3

File details

Details for the file logtie-0.1.0.tar.gz.

File metadata

  • Download URL: logtie-0.1.0.tar.gz
  • Upload date:
  • Size: 10.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for logtie-0.1.0.tar.gz
Algorithm Hash digest
SHA256 35bf078779cc6bf2bd184ef3de3050ed153a20472389c097e919b177ee67375b
MD5 b7c323e236891d7c80d0b5675e17509d
BLAKE2b-256 7cda1ad824cb60c6b1af1ed5a837380b7d6c2aae5b4b377f141512e1c8089195

See more details on using hashes here.

File details

Details for the file logtie-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: logtie-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 13.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for logtie-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 14a6bdf2bb4e17fd921e8989ac54fb56ffc1017c5ca18561789f8eb680fd3e28
MD5 5c4ef9de872289cfd08d8812ffe5fa88
BLAKE2b-256 61ee38a63a6c6418b83b4298734025dccac3a6eff2fe21c26b51ace7b3ca9dd8

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