Skip to main content

Add your description here

Project description

CharLabs

CharLabs PyLib Logging

Commit Activity

A comprehensive Python logging library that provides both traditional logging and structured logging (via structlog) with advanced task tracking capabilities.

Features

  • Dual Logging Backends: Support for both traditional Python logging and structured logging with structlog
  • Task Logger: Advanced task tracking with progress monitoring, timing, and automatic exception handling
  • Cloud Provider Support: Special configurations for cloud environments (GCP)
  • Exception Handling: Automatic setup of exception handlers for uncaught exceptions, thread exceptions, and asyncio exceptions
  • Configuration-driven: YAML-based configuration for traditional logging
  • Development-friendly: Rich console output for development environments

Installation

pip install charlabs-logging

Optional Dependencies

For different logging backends, install the appropriate dependency groups:

# For traditional logging with JSON output
pip install charlabs-logging[logging]

# For structured logging with structlog
pip install charlabs-logging[structlog]

# For development with rich console output
pip install charlabs-logging[dev]

Quick Start

Traditional Logging

from charlabs.logging import LogsSettings, setup_logs, TaskLogger

# Configure logging
settings = LogsSettings(logs_config_path="conf/logging.yaml")
setup_logs(settings)

# Use task logger with automatic progress tracking
items = list(range(1000))
with TaskLogger("data_processing", size=len(items)) as task:
    for item in task.iterate(items):
        # Your processing logic here - progress tracked automatically
        pass

Structured Logging with Structlog

from charlabs.logging.structlog import LogsSettings, setup_logs, TaskLogger
import structlog

# Setup structured logging
settings = LogsSettings(log_level="INFO")
setup_logs(settings, is_dev=True)  # Use is_dev=False for production

# Get a logger
logger = structlog.get_logger("my_app")
logger.info("Application started", version="1.0.0")

# Use task logger with structured logging and automatic progress tracking
items = list(range(1000))
with TaskLogger("data_processing", size=len(items)) as task:
    for item in task.iterate(items):
        # Your processing logic here - progress tracked automatically
        pass

Configuration

Traditional Logging Configuration

The library uses YAML configuration files that follow the Python logging configuration dictionary schema.

Example conf/logging.yaml:

version: 1
disable_existing_loggers: False

formatters:
  json:
    class: jsonlogger.JSONFormatter
    format: "%(asctime)s %(name)s %(message)s %(exc_info)s"

handlers:
  console:
    class: logging.StreamHandler
    level: INFO
    stream: ext://sys.stdout
    formatter: json

root:
  level: INFO
  handlers: [console]

Example development configuration conf/logging.dev.yaml:

version: 1
disable_existing_loggers: False

handlers:
  rich:
    class: rich.logging.RichHandler
    rich_tracebacks: True

loggers:
  app:
    level: DEBUG

root:
  handlers: [rich]

Structured Logging Configuration

from charlabs.logging.structlog import LogsSettings, LogsExecEnvironment

settings = LogsSettings(
    log_level="INFO",
    dev_log_level="DEBUG",
    exec_environment=LogsExecEnvironment.GCP,  # For GCP-specific formatting
    logger_names_extends=["my_custom_logger"]  # Add custom logger names
)

Task Logger

The Task Logger provides comprehensive task tracking with automatic timing, progress reporting, and exception handling.

Basic Usage

from charlabs.logging import TaskLogger  # or from charlabs.logging.structlog

# ✅ RECOMMENDED: Context manager usage
with TaskLogger("data_processing") as task:
    # Your task logic here
    pass

# ✅ Alternative: Manual control
task = TaskLogger("data_processing")
task.start()
try:
    # Your task logic here
    pass
finally:
    task.end()

Progress Tracking

# ✅ RECOMMENDED: Use task.iterate for automatic progress tracking
items = range(1000)
with TaskLogger("processing_items", size=len(items)) as task:
    for item in task.iterate(items):
        # Process item - progress is tracked automatically
        pass

# ✅ Alternative: Manual progress tracking (less preferred for loops)
with TaskLogger("processing_items", size=1000) as task:
    for i in range(1000):
        # Process item
        task.update(i + 1)  # Manual progress update

Best Practice: When iterating over collections, prefer using task.iterate() instead of manually calling task.update(). The iterate method automatically handles progress tracking and is more concise and less error-prone.

Advanced Configuration

from charlabs.logging._base.task_logger import TaskLoggerUpdate, TaskLoggerMsg

# Custom messages
custom_msg = TaskLoggerMsg(
    start="Beginning data processing...",
    end="Data processing completed in {duration}",
    progress="Processing... ({current}s elapsed)"
)

# Advanced configuration
task = TaskLogger(
    name="complex_task",
    size=1000,
    size_unit=(" record", " records"),
    progress_interval=5.0,  # Log progress every 5 seconds
    progress_min_interval=1.0,  # Minimum 1 second between progress logs
    progress_update=TaskLoggerUpdate.ALL,  # Log on both intervals and updates
    msg=custom_msg,
    auto_start=True,  # Start automatically on creation
    on_error=lambda e: print(f"Task failed: {e}")  # Custom error handler
)

Progress Update Modes

  • TaskLoggerUpdate.INTERVAL: Log progress only at time intervals (default)
  • TaskLoggerUpdate.UPDATE: Log progress on every update() call (including iterate())
  • TaskLoggerUpdate.ALL: Log progress on both intervals and updates

Best Practices

Use iterate() for Collections

When processing collections or iterables, always prefer task.iterate() over manual task.update() calls:

# ✅ PREFERRED: Automatic progress tracking
data = [1, 2, 3, 4, 5]
with TaskLogger("processing_data", size=len(data)) as task:
    for item in task.iterate(data):
        process(item)

# ❌ AVOID: Manual progress tracking in loops
data = [1, 2, 3, 4, 5]
with TaskLogger("processing_data", size=len(data)) as task:
    for i, item in enumerate(data):
        process(item)
        task.update(i + 1)  # Error-prone and verbose

Use update() for Non-Linear Progress

Reserve task.update() for scenarios where progress doesn't follow a simple iteration pattern:

# ✅ APPROPRIATE: Complex progress scenarios
with TaskLogger("batch_processing", size=total_records) as task:
    processed = 0
    while processed < total_records:
        batch = get_next_batch()
        process_batch(batch)
        processed += len(batch)
        task.update(processed)  # Manual update is appropriate here

Exception Handling

The library automatically sets up exception handlers for:

  • Uncaught exceptions: Main thread exceptions
  • Thread exceptions: Exceptions in spawned threads
  • Asyncio exceptions: Unhandled exceptions in async tasks
from charlabs.logging import LogsSettings, setup_logs

settings = LogsSettings(uncaught_log_name="errors")
setup_logs(settings)

# Now all uncaught exceptions will be logged to the "errors" logger

Cloud Provider Support (structlog only)

Google Cloud Platform (GCP)

When running on GCP, use the GCP execution environment for proper log formatting:

from charlabs.logging.structlog import LogsSettings, LogsExecEnvironment, setup_logs

settings = LogsSettings(exec_environment=LogsExecEnvironment.GCP)
setup_logs(settings, is_dev=False)

This automatically maps log levels to GCP's severity levels and includes appropriate metadata.

Development

Setup

# Clone the repository
git clone <repository-url>
cd charlabs_pylib_logging

# Install dependencies
uv sync

# Install pre-commit hooks
make pre-commit-install

Running Tests

make test

Code Quality

# Run linting
make lint

# Run type checking
make types

# Run pre-commit checks
make pre-commit

# Fix formatting and linting issues
make format-fix
make lint-fix

API Reference

LogsSettings Classes

charlabs.logging.LogsSettings

  • logs_config_path: Path to YAML logging configuration file
  • uncaught_log_name: Logger name for uncaught exceptions

charlabs.logging.structlog.LogsSettings

  • log_level: Application log level
  • dev_log_level: Development log level
  • exec_environment: Cloud execution environment
  • logger_names: List of logger names to configure
  • logger_names_extends: Additional logger names
  • uncaught_log_name: Logger name for uncaught exceptions

Task Logger Classes

BaseTaskLogger (Abstract)

Base class for task loggers with common functionality.

charlabs.logging.TaskLogger

Traditional logging implementation of task logger.

charlabs.logging.structlog.TaskLogger

Structured logging implementation of task logger.

Setup Functions

charlabs.logging.setup_logs(logs_settings: LogsSettings)

Sets up traditional logging from YAML configuration.

charlabs.logging.structlog.setup_logs(logs_settings: LogsSettings, *, is_dev: bool = False)

Sets up structured logging with structlog.

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

charlabs_logging-1.0.0.tar.gz (13.4 kB view details)

Uploaded Source

Built Distribution

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

charlabs_logging-1.0.0-py3-none-any.whl (13.5 kB view details)

Uploaded Python 3

File details

Details for the file charlabs_logging-1.0.0.tar.gz.

File metadata

  • Download URL: charlabs_logging-1.0.0.tar.gz
  • Upload date:
  • Size: 13.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for charlabs_logging-1.0.0.tar.gz
Algorithm Hash digest
SHA256 4fbf4b75d4bc8b073416ae616396c0f2e41fe3910546357472636c42021d500c
MD5 2859728dab139b5aaa32c82640532868
BLAKE2b-256 30a686f257e34e220f22fcee65b82e2bf817ba96aaa59a071d631a430e3c47db

See more details on using hashes here.

Provenance

The following attestation bundles were made for charlabs_logging-1.0.0.tar.gz:

Publisher: release.yaml on charlabsdev/pylib_logging

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

File details

Details for the file charlabs_logging-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for charlabs_logging-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 87300ab2da95721bd76b6abedb02b7b07c0ec886550727936d3513bfc7a44e82
MD5 0bff65cb8d957aaeaf8305dcf5b29d4b
BLAKE2b-256 a991c7091bad24f496ef5782c244b17d55bb71e6d0d42725ffc40b6d2c3d8a5f

See more details on using hashes here.

Provenance

The following attestation bundles were made for charlabs_logging-1.0.0-py3-none-any.whl:

Publisher: release.yaml on charlabsdev/pylib_logging

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

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