Skip to main content

Crate context_logger

Crate context_logger 

Source
Expand description

§Overview

A lightweight, ergonomic library for adding structured context to your logs.

context-logger enhances the standard Rust log crate ecosystem by allowing you to attach rich contextual information to your log messages without changing your existing logging patterns.

Modern applications often need rich, structured context in logs to provide insight into runtime behavior. This library simplifies the process by:

  • Adding structured context to logs without modifying the existing logging statements.
  • Propagating log context across async boundaries.
  • Allowing dynamic context updates.
  • Supporting nested contexts to build hierarchical relationships.

This library provides a wrapper around other existing logger implementations, acting as a middleware layer that enriches log records with additional context before passing them to the underlying logger. It works with any logger that implements the standard Log trait, making it compatible with popular logging frameworks like env_logger, log4rs and others.

§Basic example

use context_logger::{ContextLogger, LogContext, LogContextExt as _};
use log::info;

fn main() {
    // Create a logger.
    let env_logger = env_logger::builder().build();
    let max_level = env_logger.filter();
    // Wrap it with ContextLogger to enable context propagation.
    let context_logger = ContextLogger::new(env_logger)
        // Add version default record.
        .default_record("version", "1.0.0");
    // Initialize the resulting logger.
    context_logger.init(max_level);
    // Create a context.
    let context = LogContext::new()
        // Record that will be inherited by child contexts.
        .with_inherited_record("request_id", "req-123")
        // Local record that will only be present in this context.
        .with_local_record("user_id", 42);
    // Use the context.
    context.in_scope(|| {
        // Log with context automatically attached
        info!("Processing request"); // Will include version=1.0.0 request_id=req-123 and user_id=42  
    })
}

§Async Context Propagation

Context logger supports async functions and can propagate log context across .await points.

use context_logger::{ContextLogger, LogContext, FutureExt, LogScope};
use log::info;

async fn process_user_data(user_id: &str) {
    let context = LogContext::new().with_local_record("user_id", user_id);

    async {
        info!("Processing user data"); // Includes user_id

        // Context automatically propagates through .await points
        fetch_user_preferences().await;

        info!("User data processed"); // Still includes user_id
    }
    .in_log_context(context)
    .await;
}

async fn fetch_user_preferences() {
    // Add additional context for this specific operation
    LogScope::add_record("operation", "fetch_preferences");
    info!("Fetching preferences"); // Includes both user_id and operation
}

async fn spawn_background_job(user_id: &str) {
    let context = LogContext::new().with_local_record("user_id", user_id);

    async {
        // The scope stack is thread-local: capture the active context
        // before crossing the task boundary with tokio::spawn.
        let context = LogScope::current_context();
        tokio::spawn(
            async move {
                info!("Running background job"); // Includes user_id
            }
            .in_log_context(context),
        )
        .await
        .unwrap();
    }
    .in_log_context(context)
    .await;
}

Re-exports§

pub use self::future::FutureExt;

Modules§

future
Future types.

Structs§

ContextLogger
A logger wrapper that enhances log records with scope records.
LogContext
A set of records that can be attached to a logging scope.
LogRecords
A set of records that can be attached to a logging scope.
LogScope
A guard that represents an active logging context on the current thread’s scope stack.
LogValue
Represents a value that can be stored in a log field.

Traits§

LogContextExt
Extension trait for LogContext to run code within a temporary logging scope.