Rust slog: High-Performance Structured Logging

The slog crate stands as a powerhouse in the Rust logging ecosystem, offering a comprehensive, structured logging solution designed for high-performance environments. Unlike simpler logging frameworks, slog embraces a composable, typed approach to logging that makes it particularly well-suited for complex, production-grade applications where both performance and rich contextual information are critical.

Why slog Excels for Complex Rust Applications

The slog framework distinguishes itself with several key advantages:

  • Exceptional performance: Designed from the ground up for minimal overhead
  • True structured logging: Records data rather than just formatted text messages
  • Hierarchical contexts: Supports nested logging contexts for organized output
  • Composable architecture: Allows sophisticated drain composition for flexible output routing
  • Type-safe by design: Catches logging errors at compile time rather than runtime
  • Feature-rich ecosystem: Offers numerous complementary crates for different output formats and destinations

Getting Started with slog

Implementing slog requires a slightly different approach compared to simpler logging frameworks. Begin by adding the necessary dependencies to your Cargo.toml:

rust
1234
[dependencies]
slog = "2.7"
slog-term = "2.9"
slog-async = "2.7"

Then set up a basic logger in your application:

rust
1235678910111213141516171819202122232425262728
use slog::{info, o, Drain, Logger};
use slog_term::{CompactFormat, TermDecorator};
use slog_async::Async;
fn main() {
// Create a terminal drain
let decorator = TermDecorator::new().build();
let drain = CompactFormat::new(decorator).build().fuse();
let drain = Async::new(drain).build().fuse();
// Create root logger with initial context
let log = Logger::root(drain, o!(
"version" => env!("CARGO_PKG_VERSION"),
"application" => "my_application"
));
// Log with structured data
info!(log, "Application started";
"database" => "users",
"startup_time_ms" => 350
);
// Create a child logger with additional context
let user_log = log.new(o!("component" => "user_service"));
info!(user_log, "User service initialized";
"active_connections" => 5
);
}

Enhancing slog with OpenTelemetry Integration

While slog provides powerful logging capabilities on its own, integrating it with an OpenTelemetry native observability solution elevates your application monitoring to new heights. This integration transforms structured logs into standardized telemetry data that can be collected, processed, and analyzed alongside metrics and traces.

The benefits of connecting slog with OpenTelemetry include:

  • Unified observability: Combine logs with metrics and traces in a single platform
  • Correlation capabilities: Link logs directly to related traces and spans
  • Standardized export: Use the OpenTelemetry protocol for vendor-neutral telemetry
  • Advanced filtering and analysis: Leverage structured data for powerful queries
  • Centralized management: Configure logging behavior through a central observability platform

Implementing OpenTelemetry with slog

To integrate slog with OpenTelemetry, you'll need to create a custom drain that forwards log records to the OpenTelemetry collector:

rust
12346789101112131415161718192021222324252627282930
use slog::{info, o, Drain, Logger};
use slog_term::{CompactFormat, TermDecorator};
use slog_async::Async;
use opentelemetry_slog::OpenTelemetryDrain;
fn main() {
// Set up standard terminal output
let decorator = TermDecorator::new().build();
let term_drain = CompactFormat::new(decorator).build().fuse();
// Create an OpenTelemetry drain
let otel_drain = OpenTelemetryDrain::new();
// Combine drains to send logs to both terminal and OpenTelemetry
let combined_drain = slog::Duplicate::new(term_drain, otel_drain).fuse();
let async_drain = Async::new(combined_drain).build().fuse();
// Create root logger
let log = Logger::root(async_drain, o!(
"service" => "order_processor",
"version" => env!("CARGO_PKG_VERSION")
));
// Logs will now flow to both the terminal and your OpenTelemetry platform
info!(log, "Processing new order";
"order_id" => "order-12345",
"customer_id" => "cust-789",
"items_count" => 5
);
}

Analyzing Rust slog OpenTelemetry Logs in Dash0

Pino logs can be directly routed into Dash0. Dash0 with OpenTelemetry provides the ability to filter, search, group, and triage within a simple user interface, with full keyboard support. Dash0 also gives full log context by showing trace context, the call and resource that created the log - including details like the Kubernetes Pod, server, and cloud environment.

Log AI also enhanced the logs with more semantical metadata and structure without any manual pattern declaration.

Conclusion: Enterprise-Grade Logging for Rust

The slog crate offers a sophisticated approach to logging that aligns with the needs of enterprise-grade Rust applications. Its emphasis on performance, type safety, and structured data makes it particularly valuable in environments where logging quality and efficiency are paramount.

When combined with an OpenTelemetry native observability solution, slog becomes part of a comprehensive monitoring strategy, allowing development teams to leverage both the performance benefits of slog and the standardized observability capabilities of OpenTelemetry. For complex Rust applications with demanding performance requirements, this combination represents the gold standard in application monitoring.

Last updated: March 28, 2025