queue_workers 0.5.1

A Redis-backed job queue system for Rust applications
Documentation
# Logging Setup Guide

This document provides detailed information about setting up logging for both development and production use of the `queue_workers` library.

## Production Setups

### env_logger Setup

Simple and lightweight logging suitable for basic applications:

```toml
[dependencies]
env_logger = "0.10"
log = "0.4"
```

```rust
use env_logger::{Builder, Env};
use log::LevelFilter;

// Basic setup
fn setup_basic_logging() {
    env_logger::init();
}

// Advanced setup
fn setup_production_logging() {
    Builder::from_env(Env::default().default_filter_or("info"))
        .format_timestamp_millis()
        .format_module_path(true)
        .format_target(false)
        .write_style(env_logger::WriteStyle::Always)
        .filter_module("queue_workers", LevelFilter::Info)
        .filter_module("redis", LevelFilter::Warn)
        .init();
}
```

### tracing Setup

Recommended for production applications with advanced observability needs:

```toml
[dependencies]
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter", "json"] }
tracing-appender = "0.2"
```

```rust
use tracing_subscriber::{
    fmt::{self, time::UtcTime},
    EnvFilter,
    Layer,
};
use tracing_appender::rolling::{RollingFileAppender, Rotation};

fn setup_production_tracing() {
    // Set up file appender
    let file_appender = RollingFileAppender::new(
        RollingFileAppender::builder()
            .rotation(Rotation::DAILY)
            .filename_prefix("queue-workers")
            .filename_suffix("log")
            .build_in("logs")
            .expect("Failed to create log directory")
    );

    // JSON formatter for structured logging
    let json_layer = fmt::layer()
        .json()
        .with_timer(UtcTime::rfc_3339())
        .with_thread_ids(true)
        .with_thread_names(true)
        .with_target(true)
        .with_file(true)
        .with_line_number(true)
        .with_writer(file_appender)
        .with_filter(EnvFilter::from_default_env()
            .add_directive("queue_workers=info".parse().unwrap())
            .add_directive("redis=warn".parse().unwrap()));

    // Console formatter for human-readable output
    let console_layer = fmt::layer()
        .pretty()
        .with_timer(UtcTime::rfc_3339())
        .with_thread_names(true)
        .with_target(true)
        .with_filter(EnvFilter::from_default_env()
            .add_directive("queue_workers=debug".parse().unwrap()));

    // Combine layers
    tracing_subscriber::registry()
        .with(json_layer)
        .with(console_layer)
        .init();
}
```

## Development and Testing

### Test Configuration

```rust
// tests/common/mod.rs
use std::sync::Once;
use env_logger::Builder;
use log::LevelFilter;

static INIT: Once = Once::new();

/// Initialize test logging
pub fn init_test_logging() {
    INIT.call_once(|| {
        Builder::new()
            .filter_level(LevelFilter::Debug)
            .is_test(true)
            .init();
    });
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_with_logging() {
        init_test_logging();
        // Your test code here
    }
}
```

### Development Time Logging

For local development with detailed logging:

```rust
// examples/development.rs
use tracing_subscriber::{fmt::format::FmtSpan, EnvFilter};

fn setup_development_logging() {
    tracing_subscriber::fmt()
        .with_env_filter(
            EnvFilter::from_default_env()
                .add_directive("queue_workers=debug".parse().unwrap())
                .add_directive("redis=debug".parse().unwrap())
        )
        .with_thread_names(true)
        .with_thread_ids(true)
        .with_file(true)
        .with_line_number(true)
        .with_span_events(FmtSpan::NEW | FmtSpan::CLOSE)
        .pretty()
        .init();
}
```

### Integration Test Setup

```rust
// tests/integration/mod.rs
use tracing_subscriber::fmt::format::FmtSpan;
use std::sync::Once;

static INIT: Once = Once::new();

pub fn init_integration_test_logging() {
    INIT.call_once(|| {
        tracing_subscriber::fmt()
            .with_test_writer()
            .with_max_level(tracing::Level::DEBUG)
            .with_thread_names(true)
            .with_thread_ids(true)
            .with_file(true)
            .with_line_number(true)
            .with_span_events(FmtSpan::NEW | FmtSpan::CLOSE)
            .pretty()
            .init();
    });
}

#[tokio::test]
async fn test_worker_integration() {
    init_integration_test_logging();
    // Your integration test code here
}
```

## Environment Variables

### Common Environment Variables

```bash
# Basic logging level
export RUST_LOG=debug

# Detailed configuration
export RUST_LOG="queue_workers=debug,redis=warn,tower=info"

# Production settings
export RUST_LOG="queue_workers=info,redis=warn,tower=warn"

# Test settings
export RUST_LOG="queue_workers=debug,redis=debug,tower=warn"
```

### Development Script

```bash
#!/bin/bash
# scripts/dev.sh

export RUST_LOG="queue_workers=debug,redis=debug"
export RUST_BACKTRACE=1
cargo run --example development
```

## Log Output Examples

### Production JSON Format

```json
{
  "timestamp": "2024-02-20T15:30:45.123Z",
  "level": "INFO",
  "target": "queue_workers::worker",
  "thread_id": 1,
  "thread_name": "worker-1",
  "message": "Job completed successfully",
  "job_id": "123e4567-e89b-12d3-a456-426614174000",
  "attempts": 1,
  "duration_ms": 234.56
}
```

### Development Format

```
2024-02-20T15:30:45.123Z DEBUG queue_workers::worker{worker_id=1 job_id=123e4567-e89b-12d3-a456-426614174000}
    at src/worker.rs:123
    thread_name = worker-1
    → new job received
    ⋮ processing job
    ← completed successfully
```

## Best Practices

1. **Production Logging**
   - Use JSON formatting for machine-readable logs
   - Include essential context (job IDs, timestamps, thread info)
   - Set appropriate log levels (INFO for normal operation)
   - Implement log rotation

2. **Development Logging**
   - Use pretty formatting for readability
   - Enable debug logging for detailed information
   - Include file and line numbers
   - Show thread information

3. **Test Logging**
   - Initialize logging once per test suite
   - Use test-specific writers
   - Enable debug logging for troubleshooting
   - Include timing information for performance analysis