Skip to content
Edit this page

Home

Logly Logo

Rust-powered, Loguru-like logging for Python

PyPI Downloads Python License

Overview

Logly is a high-performance logging library for Python, powered by Rust. It combines the familiar Loguru-like API with the performance and safety guarantees of Rust.

Built with a modular Rust backend using PyO3/Maturin, Logly provides fast logging while maintaining memory safety and thread safety through Rust's ownership system.

Active Development

Logly is actively developed. Performance continues to improve with each release.

Note

The Documentation is up-to-date with the main branch so some features may be missing for the old releases on PyPI. also the docs are improving continuously. if you find any issues please report them on GitHub.

๐ŸŽฏ Why Logly?

Logly combines the simplicity of Python with the performance and safety of Rust, providing:

  • High Performance: Rust-powered backend with optimized data structures
  • Memory Safety: No data races, guaranteed thread safety
  • Comprehensive Solution: Full-featured logging with async, rotation, filtering, and callbacks
  • Developer Friendly: Intuitive API inspired by Loguru

โœจ Key Features

  • ๐Ÿš€ Rust-Powered Backend: High-performance logging with async buffering
  • ๐Ÿ“ฆ Modular Architecture: Clean separation (backend, config, format, utils)
  • ๐Ÿ”„ Async Logging: Background thread writing with configurable buffering
  • ๐Ÿ“‹ Structured JSON: Native JSON support with custom fields and pretty printing
  • ๐ŸŽจ Colored Levels: Automatic color mapping (TRACE=cyan, SUCCESS=green, WARNING=yellow, FAIL=magenta, etc.)
  • โš™๏ธ Per-Level Controls: Fine-grained control over console output, timestamps, colors, and storage
  • ๐Ÿ”ง Smart Rotation: Time-based (daily/hourly/minutely) and size-based rotation
  • ๐Ÿ—œ๏ธ Compression: Built-in gzip and zstd compression for rotated files
  • ๐ŸŽฏ Multi-Sink: Multiple outputs with independent filtering and formatting
  • ๐Ÿ” Rich Filtering: Filter by level, module, or function name
  • ๐Ÿ“ž Callbacks: Custom log processing with async execution, color styling, and filename/line number tracking
  • ๐Ÿ†• FAIL Level: New log level for operation failures (v0.1.5)
  • ๐Ÿ›ก๏ธ Memory Safe: Rust's ownership system prevents data races
  • ๐Ÿงต Thread Safe: Lock-free operations with optimized synchronization

Quick Navigation

Core Documentation

  • Quick Start Guide - Get up and running in 5 minutes with basic setup and examples
  • API Reference - Complete documentation of all methods and configuration options
  • Examples - Practical code examples for common logging scenarios
  • Installation Guide - Install Logly with pip, uv, or poetry

Advanced Topics


Quick Start

Installation

pip install logly

Basic Usage

NEW in v0.1.5: No configuration needed - just import and log!

from logly import logger

# That's it! Start logging immediately with colored output
logger.info("Application started", version="1.0.0")     # โœ… White
logger.success("Database connected")                    # โœ… Green
logger.warning("Cache is full")                         # โœ… Yellow
logger.error("Failed to connect", retry_count=3)        # โœ… Red
logger.fail("Authentication failed", user="alice")      # โœ… Magenta (NEW)

Why it works: - Logger is auto-configured on import (since v0.1.5) - Default settings: console=True, auto_sink=True, color=True - Console sink created automatically with colored levels - File sinks are NEVER automatic - add them explicitly

Advanced: Add File Sinks

from logly import logger

# Console already works, now add file logging
logger.add("logs/app.log", rotation="daily", retention=7)
logger.add("logs/errors.log", filter_min_level="ERROR")

logger.info("Logs to both console and files")

# Cleanup when done
logger.complete()

Core Concepts

1. Multiple Sinks

Route logs to different destinations with independent configurations:

# Console for development
logger.add("console")

# Daily rotated files for production
logger.add("logs/app.log", rotation="daily", retention=30)

# Errors to separate file
logger.add("logs/errors.log", filter_min_level="ERROR")

2. Structured Logging

Automatically capture structured data:

# Text mode: "User logged in user=alice ip=192.168.1.1"
logger.info("User logged in", user="alice", ip="192.168.1.1")

# JSON mode: {"timestamp": "...", "level": "INFO", "message": "...", "fields": {...}}
logger.configure(json=True)
logger.info("User logged in", user="alice", ip="192.168.1.1")

3. Context Management

Bind persistent context to log messages:

# Create context logger
request_logger = logger.bind(request_id="r-123", user="alice")

# All logs include context
request_logger.info("Request started")  # Includes request_id and user
request_logger.error("Request failed")  # Context preserved

# Temporary context
with request_logger.contextualize(step="validation"):
    request_logger.debug("Validating input")  # Includes step field

4. Async Callbacks

React to log events in real-time without blocking:

def alert_on_critical(record):
    if record.get("level") == "CRITICAL":
        send_notification(f"Critical error: {record['message']}")

callback_id = logger.add_callback(alert_on_critical)

# Callbacks execute in background threads
logger.critical("System out of memory")  # Alert sent asynchronously

Architecture

graph TB
    A[Python Application] --> B[_LoggerProxy]
    B --> C[Context Binding]
    C --> D[PyLogger Rust]
    D --> E[Async Writer Thread]
    D --> F[Callback Threads]
    E --> G[File Sinks]
    E --> H[Console Sink]
    F --> I[User Callbacks]

Components

  • _LoggerProxy - Python wrapper with context binding support
  • PyLogger - Rust core with tracing backend
  • Async Writer - Background thread for non-blocking file I/O
  • Callback System - Thread pool for async event handlers
  • Sink Management - Multiple output destinations with filters

Use Cases

Web Applications

from logly import logger
from fastapi import FastAPI, Request

app = FastAPI()
logger.add("console")
logger.add("logs/api.log", rotation="daily", retention=7)

@app.middleware("http")
async def log_requests(request: Request, call_next):
    request_logger = logger.bind(
        request_id=request.headers.get("X-Request-ID"),
        method=request.method,
        path=request.url.path
    )

    request_logger.info("Request received")
    response = await call_next(request)
    request_logger.info("Response sent", status_code=response.status_code)

    return response

Data Processing Pipelines

from logly import logger

logger.configure(json=True)
logger.add("logs/pipeline.log", size_limit="100MB", retention=10)

pipeline_logger = logger.bind(job_id="job-123", pipeline="etl")

for batch in process_data():
    with pipeline_logger.contextualize(batch_id=batch.id):
        pipeline_logger.info("Processing batch", records=len(batch))
        try:
            transform(batch)
            load(batch)
            pipeline_logger.success("Batch complete", duration=batch.elapsed)
        except Exception as e:
            pipeline_logger.exception("Batch failed")

Monitoring and Alerting

from logly import logger
import requests

def forward_to_monitoring(record):
    """Forward logs to external monitoring system"""
    if record.get("level") in ["ERROR", "CRITICAL"]:
        requests.post("https://monitoring.example.com/logs", json=record)

logger.add_callback(forward_to_monitoring)

# All errors automatically forwarded
logger.error("Database connection lost", retry_count=3)
logger.critical("Service unresponsive")

๐Ÿš€ Quick Start

Get up and running in 5 minutes

Quick Start Guide

๐Ÿ“š API Reference

Complete documentation of all methods

API Reference

๐Ÿ“ Changelog

See what's new in each version

View Changelog

โฌ‡๏ธ Installation

Install Logly with pip, uv, or poetry

Installation Guide


Community


License

Logly is licensed under the MIT License.