Skip to content

Logging Handlers

Logly can use any Python logging.Handler instance as a sink. This enables integration with any library or service that provides a stdlib logging handler.

Basic Usage

python
import logging
from logly import logger

# Use any logging.Handler as a sink
handler = logging.StreamHandler()
logger.add(handler, level="INFO")
logger.info("This goes through the handler")

Supported Handlers

Any logging.Handler subclass works:

python
import logging
from logly import logger

# RotatingFileHandler
from logging.handlers import RotatingFileHandler
logger.add(RotatingFileHandler("app.log", maxBytes=10_000_000, backupCount=5))

# SysLogHandler
from logging.handlers import SysLogHandler
logger.add(SysLogHandler(address="/dev/log"))

# SocketHandler
from logging.handlers import SocketHandler
logger.add(SocketHandler("localhost", 9020))

# SMTPHandler
from logging.handlers import SMTPHandler
logger.add(SMTPHandler("smtp.example.com", "from@example.com", "to@example.com", "Log Alert"))

# HTTPHandler
from logging.handlers import HTTPHandler
logger.add(HTTPHandler("logs.example.com", "/ingest", method="POST"))

# QueueHandler
from logging.handlers import QueueHandler
import queue
logger.add(QueueHandler(queue.Queue()))

How It Works

When you pass a logging.Handler to logger.add():

  1. Logly wraps the handler as a callable sink
  2. Each log message is converted to a logging.LogRecord
  3. The handler's emit() method is called with the record
  4. Exception info is automatically forwarded when available

Level Mapping

Logly automatically maps message text to detect the log level for the handler:

Logly LevelPython Level
TRACE, DEBUGlogging.DEBUG
INFO, NOTICE, SUCCESSlogging.INFO
WARNINGlogging.WARNING
ERROR, FAILlogging.ERROR
CRITICAL, FATALlogging.CRITICAL

Example: Custom Handler

python
import logging
from logly import logger

class AlertHandler(logging.Handler):
    def emit(self, record: logging.LogRecord) -> None:
        msg = self.format(record)
        if record.levelno >= logging.ERROR:
            send_alert(msg)

logger.add(AlertHandler(), level="ERROR")
logger.error("This triggers an alert")

Example: Multiple Handler Sinks

python
import logging
from logly import logger

# Route different levels to different handlers
logger.add(logging.StreamHandler(), level="INFO")
logger.add(logging.FileHandler("errors.log"), level="ERROR")
logger.add(logging.FileHandler("all.log"), level="DEBUG")

Parameters

python
logger.add(
    handler,          # logging.Handler instance
    level="INFO",     # Minimum level for Logly filtering
    format=None,      # Logly format (not used for handler)
    **kwargs,         # Other add() parameters
)

INFO

When using a logging.Handler, the format parameter controls Logly's internal formatting before the message reaches the handler. The handler's own formatter (set via handler.setFormatter()) handles final output formatting.

Released under the MIT License.