---
url: /logly.zig/examples/metrics.md
description: >-
  Example of collecting logging metrics with Logly.zig. Track record counts,
  bytes written, error rates, and per-level statistics for observability.
---

# Metrics Example

Collect logging metrics for observability and monitoring.

## Basic Metrics Collection

```zig
const std = @import("std");
const logly = @import("logly");
const Metrics = logly.Metrics;

pub fn main() !void {
    var gpa = std.heap.DebugAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    // Create metrics collector
    var metrics = Metrics.init(allocator);
    defer metrics.deinit();

    // Record log metrics manually
    metrics.recordLog(.info, 45);    // info log, 45 bytes
    metrics.recordLog(.debug, 32);   // debug log, 32 bytes
    metrics.recordLog(.warning, 28); // warning log, 28 bytes
    metrics.recordLog(.err, 52);     // error log, 52 bytes
    metrics.recordLog(.info, 41);    // info log, 41 bytes

    // Get metrics snapshot
    const snapshot = metrics.getSnapshot();

    std.debug.print("Metrics:\n", .{});
    std.debug.print("  Total records: {d}\n", .{snapshot.totalRecords});
    std.debug.print("  Total bytes: {d}\n", .{snapshot.totalBytes});
    std.debug.print("  Dropped records: {d}\n", .{snapshot.droppedRecords});
    std.debug.print("  Error count: {d}\n", .{snapshot.errorCount});
    std.debug.print("  Uptime: {d}ms\n", .{snapshot.uptimeMs});
    std.debug.print("  Rate: {d:.2} records/sec\n", .{snapshot.recordsPerSecond});
    std.debug.print("  Throughput: {d:.2} bytes/sec\n", .{snapshot.bytesPerSecond});
}
```

## Pipeline Controls Example

Run the full pipeline-control example:

```bash
zig build run-pipeline_controls
```

It demonstrates chainable 0.2.0 configuration across async logging, thread pools, metrics exports, rules, scheduler maintenance, and rotation:

```zig
const config = logly.Config.default()
    .withHighThroughputPipeline()
    .withObservability("checkout.api")
    .withAsync(logly.AsyncConfig.lowLatency().buffer(256).batch(8).backpressure(0.75))
    .withThreadPool(logly.ThreadPoolConfig.ioBound().threads(4).queue(512).arena(true))
    .withRotation(logly.Config.RotationConfig.daily(7).withCompression(.zstd));
```

## Metrics Available

```zig
const snapshot = metrics.getSnapshot();

// Per-level counts (array indexed by level)
snapshot.levelCounts[0]  // trace
snapshot.levelCounts[1]  // debug
snapshot.levelCounts[2]  // info
snapshot.levelCounts[3]  // success
snapshot.levelCounts[4]  // warning
snapshot.levelCounts[5]  // err
snapshot.levelCounts[6]  // fail
snapshot.levelCounts[7]  // critical

// Aggregates
snapshot.totalRecords      // Total log count
snapshot.totalBytes        // Total bytes logged
snapshot.droppedRecords    // Count of dropped logs
snapshot.errorCount        // Count of errors

// Timing and rates
snapshot.uptimeMs          // Time since start (milliseconds)
snapshot.recordsPerSecond // Current record rate
snapshot.bytesPerSecond   // Current throughput rate
```

## Recording Events

```zig
var metrics = Metrics.init(allocator);
defer metrics.deinit();

// Record a log at a specific level with byte size
metrics.recordLog(.info, 100);
metrics.recordLog(.warning, 75);

// Record a dropped log (e.g., from sampling/filtering)
metrics.recordDrop();

// Record an error (e.g., write failure)
metrics.recordError();

// Reset all metrics to zero
metrics.reset();
```

## Per-Sink Metrics

```zig
// Add a sink to track
const file_sink_idx = try metrics.addSink("file_sink");
const console_sink_idx = try metrics.addSink("console_sink");

// Record sink-specific writes
metrics.recordSinkWrite(file_sink_idx, 256);
metrics.recordSinkWrite(console_sink_idx, 128);

// Record sink write errors
metrics.recordSinkError(file_sink_idx);
```

## Formatted Output

```zig
// Get formatted metrics string
const formatted = try metrics.format(allocator);
defer allocator.free(formatted);

std.debug.print("{s}\n", .{formatted});
// Output:
// Logly Metrics
//   Total Records: 5
//   Total Bytes: 198
//   Dropped: 0
//   Errors: 0
//   Uptime: 1234ms
//   Rate: 4.05 records/sec
//   Throughput: 160.45 bytes/sec
```

## Metrics Alerts

```zig
// Check for error rate threshold
const snapshot = metrics.getSnapshot();
const errorRate = @as(f64, @floatFromInt(snapshot.errorCount)) / 
                  @as(f64, @floatFromInt(snapshot.total_logs));

if (errorRate > 0.01) { // More than 1% errors
    // Trigger alert
    try alertSystem.notify("High error rate detected");
}
```

## Integration Examples

### Prometheus Format

```zig
pub fn prometheusMetrics(metrics: *Metrics) []const u8 {
    const s = metrics.getSnapshot();
    return std.fmt.allocPrint(allocator,
        \\# HELP logly_logs_total Total number of logs
        \\# TYPE logly_logs_total counter
        \\logly_logs_total {{level="debug"}} {}
        \\logly_logs_total {{level="info"}} {}
        \\logly_logs_total {{level="warning"}} {}
        \\logly_logs_total {{level="error"}} {}
        , .{s.debug_count, s.info_count, s.warning_count, s.errorCount}
    );
}
```

### Health Check

```zig
pub fn healthCheck(metrics: *Metrics) bool {
    const s = metrics.getSnapshot();
    
    // Unhealthy if:
    // - Error rate > 5%
    // - No logs in last 60 seconds
    // - Critical errors present
    
    if (s.critical_count > 0) return false;
    if (s.total_logs > 0) {
        const errorRate = @as(f64, s.errorCount) / @as(f64, s.total_logs);
        if (errorRate > 0.05) return false;
    }
    
    return true;
}
```

## Best Practices

1. **Monitor error rates** - Set up alerts for error rate spikes
2. **Track volume** - Watch for unusual log volume patterns
3. **Use dashboards** - Visualize metrics in real-time
4. **Reset periodically** - Clear metrics for fresh windows
5. **Export regularly** - Send metrics to monitoring systems

## New Methods (v0.0.9)

```zig
var metrics = Metrics.init(allocator);
defer metrics.deinit();

metrics.recordLog(.info, 100);
metrics.recordError();
metrics.recordDrop();

// Direct access methods
const total = metrics.totalRecordCount();
const bytes = metrics.totalBytesLogged();
const errors = metrics.errorCount();
const drops = metrics.droppedCount();

// Rate calculations (0.0 - 1.0)
const errRate = metrics.errorRate();
const dropRate = metrics.dropRate();
const rps = metrics.rate();

// Level-specific counts
const info_count = metrics.levelCount(.info);
const err_count = metrics.levelCount(.err);

// Uptime
const uptimeMs = metrics.uptime();
const uptime_sec = metrics.uptimeSeconds();

// Threshold checks
if (metrics.hasHighErrorRate(0.01)) {
    std.debug.print("Warning: High error rate!\n", .{});
}

if (metrics.hasHighDropRate(0.05)) {
    std.debug.print("Warning: High drop rate!\n", .{});
}

// State check
if (metrics.hasRecords()) {
    // Export metrics
}

// Reset
metrics.reset();
// Or use alias: metrics.clear();
```

## Aliases

| Alias | Method |
|-------|--------|
| `record` | `recordLog` |
| `log` | `recordLog` |
| `drop` | `recordDrop` |
| `dropped` | `recordDrop` |
| `recordErr` | `recordError` |
| `metricsSnapshot` | `getSnapshot` |
| `levels` | `formatLevelBreakdown` |
| `breakdown` | `formatLevelBreakdown` |
| `clear` | `reset` |
| `uptimeSec` | `uptimeSeconds` |

## See Also

* [Metrics Guide](/guide/metrics) - Detailed metrics documentation
* [Metrics API](/api/metrics) - Full API reference
