Skip to main content

LoggerPlusPlus

ALIGNED, READABLE LOGGING

Enhanced logging for Python, built on Loguru — keep Loguru's simple, powerful API and add auto-aligned identifier columns, width-aware truncation, ready-made colorized formats, and convenience decorators. A small, dependency-light library meant to be shared across every service in a stack.

PyPI Python CI CodeQL License

Configure a sink with an auto-width format, bind an identifier, and log. Identifier columns align themselves to the longest value seen, overflow is truncated where you ask, and the whole API stays a transparent, drop-in proxy over Loguru.


Why LoggerPlusPlus

  • Columns that align themselves. Write {identifier:<auto} in a format and every identifier is padded to the widest one seen so far — no manual widths, no jitter between lines.
  • Truncation you control. Cap a field with [width] and choose the side: left, right, or middle, each with an ellipsis.
  • Ready-made formats, resolved by name. Five colorized layouts (Classic, Short, Ops, Debug, Minimal) that a service can select from configuration.
  • A transparent Loguru proxy. Everything Loguru exposes (sinks, levels, filters, backtraces, bind, contextualize, ...) remains available; a few names are enhanced, none are hidden.
  • Convenience decorators. catch, opt, log_timing, and log_io, each accepting an identifier or a pre-bound logger.
  • Small and safe to depend on. Runtime deps are just loguru and colorama; the package configures no sinks at import time and never prints.

Installation

pip install loggerplusplus
# or
poetry add loggerplusplus

Requires Python 3.9+.


Quickstart

import sys

from loggerplusplus import add, remove, logger

remove()  # drop Loguru's default handler first
add(
    sink=sys.stderr,
    level="DEBUG",
    format=(
        "<green>{time:YYYY-MM-DD HH:mm:ss.SSS}</green> | "
        "<level>{level.name:<8}</level> | "
        "[<blue>{identifier:<auto[18~middle]}</blue>] | "
        "<level>{message}</level>"
    ),
)

logger.bind(identifier="MAIN").info("Hello from main")
2025-09-25 14:03:12.345 | INFO     | [MAIN] | Hello from main

logger is the enhanced, ready-to-use singleton (a drop-in for Loguru's logger). The same API is also available on the loggerplusplus singleton and as the top-level functions add / remove / catch / opt / log_timing / log_io.


Auto-width alignment

{identifier:<auto} is not valid Loguru syntax on its own — LoggerPlusPlus rewrites it. The auto width tracks the longest value observed for that field over the process lifetime and pads every line to it, so a column never shrinks and never jitters. LoggerClass (below) pre-registers its identifier so alignment is correct from the very first line.

[MAIN]           | starting
[WORKER]         | working
[LONG-SERVICE-A] | columns grew, and stay aligned

The token grammar is {field:<align><width>[cap~trunc]}:

Part Values Meaning
align < > ^ left / right / center (default <)
width auto or an integer grow-to-fit, or a fixed width
cap integer, in [...] maximum width
trunc left right middle which side to cut when overflowing, with

field may be a record attribute (level.name), a dotted path, or extra[key].


Truncation

"{identifier:<auto[18~middle]}"   # grow to fit, but never wider than 18, cut in the middle
"{name:<20~right}"                 # fixed width 20, cut the tail
"{extra[service]:>auto[12~left]}"  # right-aligned, capped at 12, cut the head

VeryLongServiceName capped at 12 with ~middle renders as VeryL…Name.


Ready-made formats

Each format is a subclass of str, so an instance is a format string and can be passed straight to add(format=...). Formats are resolved by name, which is convenient for configuration:

import sys

from loggerplusplus import loggerplusplus, formats

loggerplusplus.remove()
loggerplusplus.add(sink=sys.stdout, level="DEBUG", format=formats.ShortFormat())

# Select one by name (e.g. from an env var), with a safe fallback:
chosen = "OpsFormat"
loggerplusplus.add(sink=sys.stdout, format=getattr(formats, chosen, formats.DebugFormat)())
Format Contents
ClassicFormat time, level, identifier, source name:line, message
ShortFormat time, level, identifier, message
OpsFormat time, level, identifier, process/thread, message
DebugFormat time, level, identifier, process/thread, source name:line, message
MinimalFormat identifier, message

Every format accepts overrides such as colorized=False (plain output for file sinks) and per-field widths (level_width=, identifier_width=, ...). See docs/FORMATS.md.


LoggerClass

Any class can get a bound self.logger whose identifier defaults to the class name:

from loggerplusplus import LoggerClass

class Service(LoggerClass):
    def run(self):
        self.logger.info("Service is running")

Service().run()
Service(identifier="Custom").run()   # explicit identifier

Decorators

from loggerplusplus import catch, log_timing, log_io

@catch(identifier="WORKER", level="ERROR")
def risky():
    raise RuntimeError("Boom!")

@log_timing(identifier="TASK", exit_message="Finished {func} in {duration:.2f}s")
@log_io(identifier="CALC", log_args=True, log_return=True)
def compute(a, b):
    return a + b

catch also works as a context manager; opt accepts either an identifier or a pre-bound logger. See docs/USAGE.md.


Architecture

add(format=str)
   ├─ parser.prepare_auto_format()   rewrite {identifier:<auto} into {extra[__lp_auto_N__]}
   ├─ runtime.compose_filter()       loguru calls this once per record, before formatting —
   │                                 the injection point for the padded/truncated value
   ├─ registry (_AUTO)               thread-safe max-observed width per field (monotonic)
   └─ loguru formatting

A fuller explanation is in docs/REFERENCE.md.


Public API

from loggerplusplus import (
    loggerplusplus,   # enhanced singleton (drop-in for loguru's logger)
    logger,           # alias of the singleton
    LoggerPlusPlus,   # the proxy class
    LoggerClass,      # mixin providing self.logger
    formats,          # ClassicFormat, ShortFormat, OpsFormat, DebugFormat, MinimalFormat
    add, remove,      # sink management
    catch, opt,       # loguru helpers with identifier binding
    log_timing, log_io,  # timing / I/O decorators
    __version__,
)

The public surface is a stability contract: names are added, never renamed or removed without a major version bump. Full signatures in docs/REFERENCE.md.


Documentation

Document Contents
docs/INSTALL.md Installation, requirements, and version support
docs/USAGE.md Task-oriented guide: sinks, formats, decorators
docs/FORMATS.md The five formats and the auto-width token grammar
docs/REFERENCE.md API reference and the auto-width pipeline internals
CHANGELOG.md Release history (maintained by release-please)
CONTRIBUTING.md Development workflow, the CI gate, and releasing

Project layout

src/loggerplusplus/
├── __init__.py        public API
├── proxy.py           LoggerPlusPlus — transparent proxy over loguru.logger
├── api.py             add() — wires the format parser into loguru.add
├── parser.py          auto-width token grammar
├── runtime.py         per-record width / truncation computation
├── registry.py        thread-safe max-observed width
├── logger_class.py    LoggerClass mixin
├── decorators.py      catch · opt · log_timing · log_io
└── formats/           BaseFormat + Classic · Short · Ops · Debug · Minimal

Development

poetry install
poetry run black src tests test_module
poetry run ruff check src tests test_module
poetry run mypy src
poetry run pytest            # 100% coverage; the CI gate is 95%

The CI matrix runs the suite on Python 3.9–3.13 across Linux, macOS, and Windows. See CONTRIBUTING.md.


License

LoggerPlusPlus is licensed under the GNU General Public License v3.0 — see LICENSE. It builds on top of Loguru (MIT).

Author

Created and maintained by Florian BARRE. Website · LinkedIn · GitHub

Download files

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

Source Distribution

loggerplusplus-1.1.0.tar.gz (51.2 kB view details)

Uploaded Source

Built Distribution

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

loggerplusplus-1.1.0-py3-none-any.whl (60.0 kB view details)

Uploaded Python 3

File details

Details for the file loggerplusplus-1.1.0.tar.gz.

File metadata

  • Download URL: loggerplusplus-1.1.0.tar.gz
  • Upload date:
  • Size: 51.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for loggerplusplus-1.1.0.tar.gz
Algorithm Hash digest
SHA256 c091bf1487b96ce87560a9751326993b461f7704912545405a5bb366dd77f530
MD5 60ef85f7590f630d2ab9bbb3a3c2e42c
BLAKE2b-256 84a4888ce6ef6df6f0e206c68c4c321124419ffd3d415402ac3573561dd6f276

See more details on using hashes here.

Provenance

The following attestation bundles were made for loggerplusplus-1.1.0.tar.gz:

Publisher: publish.yml on Florian-BARRE/LoggerPlusPlus

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file loggerplusplus-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: loggerplusplus-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 60.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for loggerplusplus-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e957eb8218860ae0f149574b06d35c85dac4a3a18529b85ae3eeb6e6d0b992c6
MD5 e51e3064f4e946961624d9073fcf7202
BLAKE2b-256 5be5d03631e5a2d300425d77d50aad694956932e9e23cba1267752994c5555b4

See more details on using hashes here.

Provenance

The following attestation bundles were made for loggerplusplus-1.1.0-py3-none-any.whl:

Publisher: publish.yml on Florian-BARRE/LoggerPlusPlus

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

1.1.0 This release

2 files

1.0.5

2 files

1.0.4

2 files

1.0.3

2 files

1.0.2

2 files

1.0.1

2 files

1.0.0

2 files

0.2.3

2 files

0.2.2

2 files

0.2.1

2 files

0.2.0

2 files

0.1.7

2 files

0.1.6

2 files

0.1.5

2 files

0.1.4

2 files

0.1.3

2 files

0.1.2

2 files

0.1.1

2 files

0.1.0

2 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