Skip to main content

📝 dlogger

PyPI version Python 3.8+ License MIT Status

dlogger — simple logger for personal projects

(─‿‿─)

     ____    __
    / __ \  / /   ____   ____ _ ____ _ ___   _____
   / / / / / /   / __ \ / __ `// __ `// _ \ / ___/
  / /_/ / / /___/ /_/ // /_/ // /_/ //  __// /
 /_____/ /_____/\____/ \__, / \__, / \___//_/
                      /____/ /____/

📦 installation

pip install dlogger-drawiks

📑 quick start

from dlogger import logger

logger.info("hello, world!")
logger.error("something went wrong")

with configuration:

from dlogger import logger

logger.configure(
    level="INFO",
    log_file="app.log",
    rotation="10MB",
    retention="7 days",
    compression=True
)

logger.debug("this won't be shown")
logger.info("but this will")

🧩 features

  • 🎨 TrueColor output — HEX/RGB support powered by dcolor
  • 🚀 high performance — use of buffers and call context caching
  • 🧵 thread safety — stability in multithreaded applications thanks to locks
  • 💾 write guarantee — automatic buffer reset upon correct program termination
  • 📁 smart rotation — by size (10MB, 1GB) or time (1 day, 12 hours)
  • 🗑️ auto cleanup — scheduled deletion of old files (retention="30 days")
  • 📦 compression — automatic archiving of old logs to .gz
  • 🛠️ minimal dependencies — only dcolor
  • ✅ reliability — protection from memory leaks, data loss and deadlocks
  • 🏗️ modular architecture — extensible via handlers, formatters and filters

📖 usage

log levels

logger.configure(level="INFO")  # TRACE, DEBUG, INFO, SUCCESS, WARNING, ERROR, CRITICAL

size-based rotation

logger.configure(
    log_file="app.log",
    rotation="10MB"  # or "500KB", "1GB"
)

once the file reaches 10MB → app.log.20260216_143022

time-based rotation

logger.configure(
    log_file="app.log",
    rotation="1 day"  # or "12 hours", "1 week"
)

log retention

logger.configure(
    log_file="app.log",
    retention="7 days"  # or "2 weeks", "1 month"
)

logs older than 7 days will be deleted automatically

compression

logger.configure(
    log_file="app.log",
    rotation="10MB",
    compression=True  # old logs → .gz
)

full configuration

logger.configure(
    level="INFO",              # minimum log level
    log_file="logs/app.log",   # path to log file
    show_path=True,            # show module:function:
    rotation="10MB",           # size-based rotation
    retention="7 days",        # keep logs for 7 days
    compression=True,
    time_format="%H:%M:%S"     # time format - 14:30:22
)

💡 examples

simple logging

from dlogger import logger

logger.info("server started on port 8000")
logger.warning("memory usage at 80%")
logger.error("failed to connect to database")

with file

from dlogger import logger

logger.configure(
    level="DEBUG",
    log_file="app.log"
)

logger.debug("starting request processing")
logger.info("request processed successfully")

for production

from dlogger import logger

logger.configure(
    level="INFO",
    log_file="logs/production.log",
    rotation="50MB",
    retention="30 days",
    compression=True,
    time_format="%Y-%m-%d %H:%M:%S"
)

logger.info("application started")
logger.error("critical error in payments module")

extensibility (handlers, formatters, filters)

from dlogger import dLogger, ConsoleHandler, FileHandler, LevelFilter

# create your own logger
my_logger = dLogger()

# add handlers
my_logger.add_handler(ConsoleHandler(level="DEBUG"))
my_logger.add_handler(FileHandler("app.log", rotation="10MB"))

# or use the default logger and add/remove handlers
from dlogger import logger
logger.remove_handler(logger.handlers[0])  # remove console handler
logger.add_handler(FileHandler("debug.log", level="DEBUG"))

multiple loggers (get_logger)

from dlogger import get_logger

# like logging.getLogger()
app = get_logger("myapp")
module = get_logger("myapp.module")

# child logger inherits handlers and level from parent
app.info("message from app")
module.info("message from module")

multiple loggers (dLogger)

from dlogger import dLogger

# independent loggers for different modules
app_logger = dLogger().configure(level="INFO", log_file="app.log")
db_logger = dLogger().configure(level="DEBUG", log_file="db.log")

app_logger.info("application started")
db_logger.debug("database query executed")

filters (KeywordFilter, ModuleFilter)

from dlogger import logger, KeywordFilter, ModuleFilter, FileHandler

# exclude passwords and tokens from logs
handler = FileHandler("app.log")
handler.add_filter(KeywordFilter(exclude=["password", "token", "secret"]))
logger.add_handler(handler)

# log only specific modules
handler2 = FileHandler("debug.log")
handler2.add_filter(ModuleFilter(modules=["database:", "api:"]))
logger.add_handler(handler2)

exception logging

from dlogger import logger

# automatic - uses sys.exc_info()
try:
    result = 1 / 0
except:
    logger.exception("division by zero")

# with explicit exception
try:
    result = 1 / 0
except ZeroDivisionError as e:
    logger.exception("error", exc=e)

custom context

from dlogger import logger

# pass custom context
logger.info("message", context="my.module:function:")

# for external library integration
logger.debug("debug from library", context="library.module:handler:")

🖥️ uvicorn integration

quick way

from dlogger import logger, uvicorn_config
from uvicorn.config import Config
from uvicorn.server import Server

config = Config(
    "app:app",
    host="0.0.0.0",
    port=8000,
    log_config=uvicorn_config(logger)
)
server = Server(config=config)

from config file

Create dlogger.conf:

[loggers]
keys=root,repos,routers,utils

[logger_root]
level=DEBUG
log_file=app.log

[logger_repos]
level=INFO
log_file=repos.log
rotation=10MB
retention=7 days

[logger_routers]
level=WARNING

Then:

from dlogger import load
from uvicorn.config import Config
from uvicorn.server import Server

config = Config("app:app", log_config=load())
server = Server(config=config)

supported parameters in dlogger.conf:

  • level - log level
  • log_file - path to log file
  • rotation - rotation (10MB, 1GB, 1 day, 12 hours)
  • retention - retention (7 days, 1 month)
  • compression - compression (true/false)
  • time_format - time format

🔗 context binding (bind)

from dlogger import logger

# bind context to all logs
bound = logger.bind(request_id="abc-123", user_id=42)
bound.info("request processed")  # request_id=abc-123 user_id=42
bound.error("error")             # request_id=abc-123 user_id=42

# chaining
bound2 = logger.bind(service="api").bind(version="v1")

temporary context (contextualize)

from dlogger import logger

# context only within with-block
with logger.contextualize(request_id="xyz-789"):
    logger.info("inside block")    # request_id=xyz-789

logger.info("outside block")       # no request_id

📦 JSON mode

from dlogger import logger

logger.configure(
    level="INFO",
    log_file="app.log",
    serialize=True
)

logger.info("request processed")
# {"time":"2026-07-25 14:00:00","level":"INFO","level_value":20,"context":"module:func:","message":"request processed","pid":12345}

🏗️ NullHandler for libraries

if you're writing a library and want users to use dlogger:

from dlogger import NullHandler

# add NullHandler to avoid "No handlers" warning
import logging
logging.getLogger("mylib").addHandler(NullHandler())

📝 log format

console:

2026-02-17 14:09:13 | INFO     | src.bot:run: - init

file:

2026-02-17 14:09:13 | INFO     | src.main:run: init
2026-02-17 14:09:13 | ERROR    | src.main:run: error

📜 license

MIT

Metadata

Release files for dlogger-drawiks 0.4.0

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

Source distribution (sdist)

Source distribution for dlogger-drawiks 0.4.0
File Size Uploaded
dlogger_drawiks-0.4.0.tar.gz 21.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for dlogger-drawiks 0.4.0
File Interpreter ABI Platform
dlogger_drawiks-0.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 38.8 kB

Release files / dlogger_drawiks-0.4.0.tar.gz

Download URL dlogger_drawiks-0.4.0.tar.gz
Size 21.1 kB
Tags Source
SHA-256 checksum
How to use checksums
6e8195c9a4c3d2a67f42a5648c55cdac84605afadacd1d6694ccc68f5a5abc19
BLAKE2b-256 checksum
How to use checksums
8a502b5c529b263c0894c6218b9ded963ad007b834de0202a09b2238a74e3b75
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.6

Release files / dlogger_drawiks-0.4.0-py3-none-any.whl

Download URL dlogger_drawiks-0.4.0-py3-none-any.whl
Size 17.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c9c2d1e1dead9a69321f94650b9bf90cca9cc11f577a92cd7abc03275b09ba9a
BLAKE2b-256 checksum
How to use checksums
4b86d5df956660ab8f99d867abfdfde8ace59766bf9cd2c3230ad497f9519486
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.6

Release history Release notifications | RSS feed

This release

0.4.0 This release

2 release files

0.3.8

2 release files

0.3.7

2 release files

0.3.6

2 release files

0.3.5

2 release files

0.3.4

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.0

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