kerf 0.1.2

Simple tokio-based trace event collector
Documentation
# Kerf Tracing Crate Technical Overview

## Executive Summary

Kerf is an ergonomic Rust tracing crate designed to "slice" tracing events into organized "tabs" with sophisticated filtering capabilities. The name derives from the woodworking term "kerf" - the width of a cut made by a saw - reflecting its purpose of making precise cuts through the stream of tracing events.

**Major Architecture Update (2025-07-29)**: Kerf now features a revolutionary per-tab callback system with a builder pattern API, enabling clean separation of concerns while maintaining full backward compatibility and serializable configurations.

## Architecture Overview

```mermaid
graph TB
    A[Tracing Events] --> B[TracingSubscriber]
    B --> C[Event Processing]
    C --> D[Dispatcher]
    D --> E{Event Matching}
    E -->|Match Include| F[Captured Events]
    E -->|Match Exclude| G[Silenced Events]
    E -->|No Match| H[Dropped Events]
    F --> I{Per-Tab Routing}
    I --> I1[Tab A Callback]
    I --> I2[Tab B Callback]
    I --> I3[Tab N Callback]
    F --> J[Global Event Callback]
    G --> K[Silenced Callback]
    H --> L[Dropped Callback]
    D --> M[StatsTracker]
    M --> N[Statistics Snapshot]

    subgraph "New: Builder Pattern API"
        O[KerfBuilder] --> P[Tab Callback Registry]
        P --> Q[Per-Tab Callbacks]
        Q --> I
    end
```

## Core Components

### 1. Kerf (Main Interface) - `tracer.rs`

The main entry point providing:
- **Initialization**: `Kerf::init()` and `Kerf::init_default()`
- **Builder Pattern**: `KerfBuilder` for fluent configuration with per-tab callbacks
- **Tab Management**: Add, update, remove tabs dynamically
- **Callback Registration**: Set handlers for captured, silenced, and dropped events
- **Statistics Access**: Get comprehensive stats snapshots

Key methods:
- `set_callback()` - Handle captured events (global callback)
- `set_silenced_callback()` - Handle explicitly silenced events
- `set_dropped_callback()` - Handle unmatched events
- `add_tab()`, `update_tab()`, `remove_tab()` - Dynamic tab management
- `get_stats()`, `clear_stats()` - Statistics management

**New Builder API**:
- `with_tab_callback()` - Register per-tab event handlers
- `build()` - Finalize configuration and create Kerf instance

### 2. Event Processing - `event.rs`

Rich event representation with:
- **Core Data**: ID, timestamp, level, target, module path, file/line
- **Message & Fields**: Formatted message plus structured field data
- **Span Context**: Current span name and full hierarchy
- **Formatting**: Multiple display formats (basic, colored, with file info, full)

Notable features:
- ANSI color support for terminal output
- Multiline message handling
- Arc-wrapped for efficient sharing
- Comprehensive field extraction from tracing events

### 3. Matching System - `matcher.rs`

Sophisticated pattern matching with:
- **Level Filtering**: Hierarchical log level matching (ERROR includes WARN, INFO, etc.)
- **Pattern Types**: Module, file, span, and target pattern matching
- **Glob Support**: Wildcard patterns using regex conversion
- **Include/Exclude Logic**: Positive and negative filtering

Builder pattern API:
```rust
Match::info()
    .module_pattern("service_*")
    .exclude()
    .span_pattern("internal_*")
    .target_pattern("api_*")
```

### 4. Configuration System - `config.rs`

Flexible configuration with:
- **Tab Definition**: Named filter sets with matcher collections
- **Builder Pattern**: Fluent API for configuration construction
- **Statistics Config**: Comprehensive tracking options
- **Serialization**: Full serde support for persistence

Example usage:
```rust
Config::empty()
    .with_tab("api", Match::info().module_pattern("api_*"))
    .with_tab("errors", Match::error().all_modules())
    .with_stats(StatsConfig::default())
```

### 5. Event Dispatcher - `dispatcher.rs`

Central event routing engine:
- **Async Processing**: Tokio-based event handling
- **Tab Management**: Dynamic filter set updates
- **Event Classification**: Captured/Silenced/Dropped determination
- **Callback Orchestration**: Efficient event delivery with per-tab routing
- **Per-Tab Callback Registry**: HashMap-based callback storage for each tab
- **Pending Event Handling**: Queues events until callbacks are set

Processing logic:
1. Check exclusion filters first (silencing takes precedence)
2. Check inclusion filters for remaining events
3. Route to appropriate callbacks based on classification:
   - **Per-Tab Callbacks**: Events routed to specific tab callbacks based on matching
   - **Global Callbacks**: Events also sent to global handlers if configured
4. Update statistics tracking

**New Per-Tab Routing**:
- Events are matched against tab filters and routed to corresponding callbacks
- Each tab can have its own dedicated callback function
- Callbacks are stored as `Box<dyn Fn(ArcEvent) + Send + Sync>` for flexibility

### 6. Statistics Tracking - `stats.rs`

Comprehensive metrics collection:
- **Multi-dimensional Tracking**: By location, module, level, and event type
- **Atomic Counters**: Thread-safe performance tracking
- **Configurable Limits**: Prevent memory bloat with max tracking limits
- **Complete Snapshots**: Full statistical state capture
- **Real-time Updates**: Live statistics during event processing

Statistics categories:
- **Location Stats**: File:line tracking with event type breakdown
- **Module Stats**: Per-module event classification
- **Level Stats**: Event type counts by log level
- **Raw Stats**: Complete key-value tracking with timestamps

### 7. Tracing Integration - `tracing_subscriber.rs`

Custom tracing subscriber providing:
- **Span Tracking**: Thread-local span stack management
- **Context Enrichment**: Automatic span hierarchy building
- **Field Extraction**: Complete field data capture
- **Event Enhancement**: Span context injection into events
- **Memory Management**: Automatic span cleanup

## Key Design Patterns

### 1. Builder Pattern
Extensive use throughout for ergonomic API construction:
- `Match` builders for filter creation
- `Config` builders for tracer setup
- `Tab` builders for filter set definition
- **`KerfBuilder`** for fluent per-tab callback configuration (NEW)

### 2. Type-Safe Event Handling
Strong typing with:
- `ArcEvent` for shared event references
- Callback type aliases for clarity
- Result types for error handling

### 3. Async-First Architecture
Built on Tokio primitives:
- Unbounded channels for event streaming
- Oneshot channels for command responses
- Async/await throughout the API

### 4. Flexible Filtering
Multi-layered filtering system:
- Include/exclude semantics
- Pattern-based matching
- Level hierarchies
- Multiple pattern types per matcher

### 5. Per-Tab Callback Architecture (NEW)
Revolutionary callback system enabling:
- **Separation of Concerns**: Each tab handles its own events independently
- **Composable Configuration**: Mix and match tab behaviors without complex routing
- **Type Safety**: Strongly typed callback functions with compile-time verification
- **Backward Compatibility**: Existing global callback API remains fully functional

## Performance Characteristics

### Strengths
- **Lock-free Event Processing**: Atomic counters and channel-based communication
- **Efficient Pattern Matching**: Regex compilation with caching
- **Memory Management**: Arc-based sharing reduces allocations
- **Configurable Limits**: Prevents unbounded memory growth

### Considerations
- **Regex Overhead**: Pattern compilation cost for complex filters
- **Memory Usage**: Comprehensive statistics tracking can consume significant memory
- **Channel Backpressure**: Unbounded channels may accumulate events under high load

## Usage Patterns

### Basic Setup
```rust
let tracer = Kerf::init_default()?;
tracer.set_stdout_callback()?;
```

### Advanced Configuration (Traditional)
```rust
let config = Config::empty()
    .with_tab("api", Match::info().module_pattern("api_*"))
    .with_tab("errors", Match::error().all_modules())
    .with_stats(StatsConfig::default());

let tracer = Kerf::init(config)?;
```

### **NEW: Per-Tab Callback Configuration**
```rust
// Builder pattern with per-tab callbacks
let kerf = Kerf::init(config)?
    .with_tab_callback("console", |event| {
        println!("[CONSOLE] {}", event);
    })
    .with_tab_callback("errors", |event| {
        eprintln!("[ERROR] {}", event.colored());
        // Write to error log file
        write_to_error_log(&event);
    })
    .with_tab_callback("api", |event| {
        // Send to monitoring system
        send_to_metrics(&event);
    })
    .build().await?;
```

### **Hybrid Approach** (Per-Tab + Global)
```rust
let kerf = Kerf::init(config)?
    .with_tab_callback("console", |event| println!("{}", event))
    .with_tab_callback("errors", |event| write_to_file(&event))
    .build().await?;

// Global callback still works for cross-cutting concerns
kerf.set_callback(|event, tab_names| {
    // Handle events that match multiple tabs
    update_global_metrics(&event, &tab_names);
})?;
```

### Dynamic Management
```rust
tracer.add_tab("debug", Match::debug().module_pattern("service_*"))?;
tracer.update_tab("api", new_matcher_set)?;
tracer.remove_tab("debug")?;
```

### Statistics Monitoring
```rust
if let Ok(stats) = tracer.get_stats()?.await? {
    println!("Captured: {}", stats.total_counters[&(EventType::Captured, Level::INFO)]);
}
```

## Integration Recommendations

### For Development
- **Use per-tab callbacks** for clean separation of concerns
- Use comprehensive statistics tracking for debugging
- Leverage colored output for terminal visibility
- Implement dynamic tab management for runtime filtering

### For Production
- **Combine per-tab and global callbacks** for efficient event routing
- Configure appropriate statistics limits
- Use targeted filtering to reduce overhead
- Implement log rotation for file-based callbacks

### For Testing
- **Per-tab callbacks simplify test verification** - no complex routing logic
- Utilize the testing sender for event injection
- Use statistics snapshots for assertion validation

### **For TUI Applications (NEW)**
- Per-tab callbacks enable clean integration with UI components
- Each UI pane can register its own callback without manual routing
- ConsolePane integration becomes trivial with dedicated callbacks

## Recent Major Enhancements (2025-07-29)

### **Per-Tab Callback System**
- **Problem Solved**: Eliminated complex manual routing in global callbacks
- **Implementation**: `HashMap<String, Box<dyn Fn(ArcEvent) + Send + Sync>>` in dispatcher
- **Benefits**: Clean separation of concerns, composable tab behaviors
- **Backward Compatibility**: 100% - existing global callback API unchanged

### **Builder Pattern API**
- **New `KerfBuilder`**: Fluent API for per-tab callback configuration
- **Method**: `with_tab_callback(tab_name, callback)` for ergonomic setup
- **Integration**: Seamless with existing `Config` and `Tab` structures

### **Comprehensive Testing**
- **52 Total Tests**: All existing tests pass + 6 new per-tab callback tests
- **Coverage**: Builder pattern, per-tab routing, hybrid configurations
- **Validation**: No regressions, full feature compatibility

## Future Enhancement Opportunities

1. **Performance Optimizations**
   - Pattern compilation caching
   - Event batching for high-throughput scenarios
   - Memory pool allocation for events
   - **Per-tab callback optimization**: Reduce HashMap lookups

2. **Feature Extensions**
   - Time-based filtering (event age, rate limiting)
   - Conditional filtering (field value matching)
   - Plugin architecture for custom matchers
   - **Async per-tab callbacks**: Support for async callback functions

3. **Operational Improvements**
   - Built-in log rotation
   - Metrics export (Prometheus, etc.)
   - Configuration hot-reloading
   - **Dynamic callback registration**: Runtime callback updates

## Conclusion

Kerf represents a sophisticated approach to tracing event management, providing powerful filtering capabilities while maintaining ergonomic APIs. Its async-first architecture and comprehensive statistics make it well-suited for both development and production environments. The modular design allows for flexible deployment patterns while the builder-based configuration ensures type safety and ease of use.

**The recent per-tab callback architecture represents a revolutionary advancement**, solving the fundamental challenge of complex event routing while maintaining full backward compatibility. This enables:

- **Clean TUI Integration**: UI components can register dedicated callbacks without manual routing
- **Composable Configurations**: Mix and match tab behaviors independently
- **Separation of Concerns**: Each tab handles its own events autonomously
- **Simplified Testing**: No complex callback routing logic to test

The crate successfully achieves its goal of providing ergonomic "slicing" of tracing events, with the tab-based organization offering intuitive mental models for event categorization and routing. The new per-tab callback system elevates this from a filtering tool to a complete event orchestration platform.

**Current State**: Architecture transformation complete and fully tested. Ready for seamless TuiApp integration and ConsolePane enhancement.