Skip to main content

Custmon loggers to make debugging easy

Project description

๐Ÿงช logger-lab

Logging, reimagined as a system.

logger-lab is a composable Python logging toolkit built around a simple idea:

logging should be modular, readable, and adaptable โ€” for both humans and machines.

Instead of writing repetitive logging setup, you select from experiments, apply profiles, or compose your own logger by assembling them like a system.


๐Ÿš€ Installation

pip install logger-lab

โšก Quick Start

from logger_lab import get_logger

logger = get_logger(__name__, profile="INVESTIGATOR")

logger.info("System online")
logger.debug("Inspecting state")
logger.error("Something broke")

Summary of usage

Both enums and strings can be used as parameters for both get_logger() and lab():

import logging
from logger_lab import lab, get_logger,  ExperimentType

# Profiles (prebuilt combinations):
profile_logger = get_logger(name="profile_test", profile="conspiracy_theorist")

# Experiments (single handler factories):
experiment_logger = get_logger(name="experiment_test", experiment=ExperimentType.MINIMALIST)

# Fluent builder (custom composition):
built_logger = (
    lab()
    .with_experiment('STANDARD')
    .with_experiment(ExperimentType.FILE)
    .with_level(logging.DEBUG)
    .build(__name__)
)

๐Ÿงช Experiments

Experiments are atomic logging behaviours โ€” pure functions that return a list of configured handlers.

Each experiment controls exactly one thing: how logs are formatted and where they go.

Experiment Handler Description
standard RichHandler Colourised console output with traceback support
minimalist StreamHandler Plain LEVEL: message โ€” warnings only by default
verbose StreamHandler Full context: timestamp, module, function, line
file FileHandler Persistent plain-text log at logs/app.log
rotating_file RotatingFileHandler Auto-rotates at 5 MiB, keeps 3 backups
ai StreamHandler (stderr) Structured JSON โ€” Mosquito Lab Standard v1

Using a single experiment

from logger_lab import get_logger

logger = get_logger(__name__, experiment="minimalist")
logger.info("Ready")

๐Ÿงซ Profiles

Profiles are prebuilt combinations of experiments tuned for common use cases.

Profile Experiments Use case
observer minimalist Production โ€” warnings and above only
investigator standard + file Development โ€” Rich console + disk
conspiracy_theorist verbose + file + rotating_file Deep archival โ€” nothing missed
ai_agent ai Structured JSON for pipelines
from logger_lab import get_logger, ProfileType

payload = "super dangerous and malicious payload!"

logger = get_logger(__name__, profile=ProfileType.CONSPIRATOR)
logger.debug("Payload received: %s", payload)
logger.error("Unexpected response", exc_info=True)

๐Ÿงฌ Custom Composition

For full control, build your logger like a system:

from logger_lab import lab, ExperimentType

logger = (
    lab()
    .with_experiment(ExperimentType.MINIMALIST)
    .with_experiment(ExperimentType.FILE)
    .with_level("DEBUG")
    .build(__name__)
)

Mix a profile with additional experiments:

from logger_lab import lab, ExperimentType, ProfileType

logger = (
    lab()
    .with_profile(ProfileType.INVESTIGATOR)
    .with_experiment(ExperimentType.AI)
    .with_level("INFO")
    .build(__name__)
)

๐Ÿค– AI Logging (Core Feature)

logger-lab includes a structured logging format designed for AI systems.

Logs become machine-readable events, not just text.

Example Output

{
  "timestamp": "2026-05-05T12:00:00+00:00",
  "level": "INFO",
  "message": "User logged in",
  "source": {
    "module": "auth",
    "function": "login",
    "line": 88
  },
  "extra": {
    "event": "user_login",
    "context": { "user_id": 42 },
    "tags": ["auth"]
  }
}

Usage

Use log_event() โ€” it constructs a fresh extra dict on every call so successive calls never share mutable state:

from logger_lab import get_logger, log_event, ProfileType
import logging

logger = get_logger(__name__, profile=ProfileType.AGENT)

log_event(
    logger, logging.INFO, "User logged in",
    event="user_login",
    context={"user_id": 42},
    tags=["auth"],
)

๐Ÿšจ Error Handling

All exceptions inherit from LabError so you can catch broadly or precisely.

LabError
โ”œโ”€โ”€ LabRegistryError
โ”‚   โ”œโ”€โ”€ ExperimentNotFoundError    โ€” valid ExperimentType not registered
โ”‚   โ”œโ”€โ”€ ProfileNotFoundError       โ€” valid ProfileType not registered
โ”‚   โ”œโ”€โ”€ InvalidExperimentName      โ€” unrecognised experiment string
โ”‚   โ””โ”€โ”€ InvalidProfileName         โ€” unrecognised profile string
โ”œโ”€โ”€ LabConfigurationError
โ”‚   โ”œโ”€โ”€ InvalidLevelError          โ€” bad level string or int
โ”‚   โ”œโ”€โ”€ HandlerConfigurationError  โ€” handler failed to initialise
โ”‚   โ”‚   โ””โ”€โ”€ LogDirectoryError      โ€” log directory mkdir/access failure
โ”‚   โ”œโ”€โ”€ ExperimentRegistrationError โ€” callable doesn't satisfy ExperimentFactory
โ”‚   โ””โ”€โ”€ ProfileRegistrationError    โ€” callable doesn't satisfy ProfileFactory
โ””โ”€โ”€ BuilderError                   โ€” build() called with nothing queued

Broad catch

from logger_lab import get_logger, LabError

try:
    logger = get_logger(__name__, profile="typo")
except LabError as exc:
    print(f"logger-lab error: {exc}")

Precise catch

from logger_lab import get_logger, InvalidProfileName, BuilderError

try:
    logger = get_logger(__name__, profile="typo")
except InvalidProfileName as exc:
    print(f"Unknown profile: {exc}")   # lists valid names in the message
except BuilderError as exc:
    print(f"Builder misconfigured: {exc}")

๐Ÿ—๏ธ Architecture

logger_lab/
โ”œโ”€โ”€ __init__.py           โ† public API: get_logger(), lab(), log_event()
โ”œโ”€โ”€ core/
โ”‚   โ”œโ”€โ”€ enums.py          โ† ExperimentType, ProfileType
โ”‚   โ”œโ”€โ”€ registry.py       โ† EXPERIMENTS + PROFILES dicts, validated registration
โ”‚   โ””โ”€โ”€ builder.py        โ† LabBuilder fluent interface + lab() factory
โ”œโ”€โ”€ experiments/          โ† atomic handler factories (level) โ†’ list[Handler]
โ”‚   โ”œโ”€โ”€ standard.py       โ† RichHandler
โ”‚   โ”œโ”€โ”€ minimalist.py     โ† StreamHandler, warnings only
โ”‚   โ”œโ”€โ”€ verbose.py        โ† StreamHandler, full context
โ”‚   โ”œโ”€โ”€ file.py           โ† FileHandler
โ”‚   โ”œโ”€โ”€ rotating_file.py  โ† RotatingFileHandler
โ”‚   โ””โ”€โ”€ ai.py             โ† StreamHandler + JSONFormatter
โ”œโ”€โ”€ profiles/             โ† prebuilt logger configurations
โ”‚   โ”œโ”€โ”€ _base.py          โ† _build_profile() shared skeleton
โ”‚   โ”œโ”€โ”€ observer.py
โ”‚   โ”œโ”€โ”€ investigator.py
โ”‚   โ”œโ”€โ”€ conspiracy_theorist.py
โ”‚   โ””โ”€โ”€ ai_agent.py
โ”œโ”€โ”€ theories/             โ† explore different theories to invent new experiments
โ”‚   โ”œโ”€โ”€ _test_theory.py   โ† test a theory (even I don't know what'll happen)
โ”‚   โ”œโ”€โ”€ my_stuff_exp.py
โ”‚   โ””โ”€โ”€ your_stuff_exp.py
โ””โ”€โ”€ logging_kernel/       โ† shared infrastructure
    โ”œโ”€โ”€ errors.py         โ† full exception hierarchy
    โ”œโ”€โ”€ formatters.py     โ† JSONFormatter, log_event(), formatter factories
    โ”œโ”€โ”€ handlers.py       โ† _configure_handler(), get_log_dir()
    โ””โ”€โ”€ normalisers.py    โ† normalises all params,

๐Ÿงฌ Philosophy

logger-lab is built on three principles:

  1. Modularity โ€” Logging behaviour should be reusable and composable.
  2. Clarity โ€” Logs should be easy to read and understand.
  3. Structure โ€” Logs should be usable as data, not just text.

Logs are not just for debugging. They are inputs for analysis, automation, and intelligence.


๐Ÿงช Experimental Features

Some features live in the experimental zone (theories):

from logger_lab import get_logger
from logger_lab.core.enums import TheoryType

# THEORIES (single handler factories):
theory_logger = get_logger(name="doom", theory=TheoryType.TIMED_FILE)

These are unstable and may change.


๐Ÿค Contributing

Contributions are welcome.

Adding a new experiment

  1. Create logger_lab/theories/your_name_exp.py
  2. Define your_name_experiment(level: int = DEBUG, **kwargs) -> list[logging.Handler]
  3. Add the enum value to TheoryType in core/enums.py
  4. Manually register it in the THEORIES registry
  5. Test in _test_theory.py
  6. Document its purpose and behaviour
  7. After review, the Lab will add it to experiments logic

Adding a new profile

Currently just on a suggestion basis. I don't know about adding experimental logic for a profile


๐Ÿงญ Roadmap

  • More experiments (async, http, db, performance)
  • Advanced profiles
  • AI-assisted debugging tools
  • Distributed tracing support
  • py.typed marker + full type stub coverage

๐Ÿง‘โ€๐Ÿ’ป Author

Mosquito Lab (Cyber-Smoke) ๐Ÿ“ง mosquitolab2024@protonmail.com ๐Ÿ”— github.com/Mosquito-Lab/logger-lab


๐Ÿ“„ License

MIT LICENSE


๐ŸŒฑ Status

STABLE RELEASE: v0.1.1

  • Still in active development. New experiments, profiles, and capabilities are being added continuously.

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

logger_lab-0.1.1.tar.gz (28.9 kB view details)

Uploaded Source

Built Distribution

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

logger_lab-0.1.1-py3-none-any.whl (37.4 kB view details)

Uploaded Python 3

File details

Details for the file logger_lab-0.1.1.tar.gz.

File metadata

  • Download URL: logger_lab-0.1.1.tar.gz
  • Upload date:
  • Size: 28.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.4

File hashes

Hashes for logger_lab-0.1.1.tar.gz
Algorithm Hash digest
SHA256 846743885e2e382b1c18ecfd9399d6596fcf7811231e2ced835ab5d3a77ff442
MD5 4899b6fc3720571f0756cce426c2baf8
BLAKE2b-256 a6c3c183d5e2962ac3b17089133cec59e30264d5b624420ae11e1f7364e1c86e

See more details on using hashes here.

File details

Details for the file logger_lab-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for logger_lab-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 6eee0210ceeecbc45a899212c74963949eaa030e9ee20a15054a0be082a4f683
MD5 5540887f34a1a6078b06f90589b8dc76
BLAKE2b-256 21463a52e656858c8b3d085c205256e944451a5d59a1ff8505356e301333c92c

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