---
url: /logly.zig/examples/sampling.md
description: >-
  Example of log sampling with Logly.zig. Control log volume using probability
  sampling, rate limiting, and every-Nth strategies for high-throughput
  applications.
---

# Sampling Example

Control log throughput using sampling strategies for high-volume applications.

## Probability Sampling

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

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

    // Enable colors on Windows
     _ = logly.Terminal.enableAnsiColors();

    const logger = try logly.Logger.init(allocator);
    defer logger.deinit();

    // Create sampler with 50% probability
    var sampler = Sampler.init(allocator, .{ .probability = 0.5 });
    defer sampler.deinit();

    // Check if log should be sampled before logging
    var i: usize = 0;
    while (i < 100) : (i += 1) {
        if (sampler.shouldSample()) {
            try logger.infof("Log message {d}", .{i}, @src());
        }
    }
}
```

## Rate Limiting

```zig
// Rate limit to 100 messages per 1000ms (1 second)
var sampler = Sampler.init(allocator, .{ .rateLimit = .{
    .maxRecords = 100,
    .windowMs = 1000,
}});
defer sampler.deinit();

// After 100 logs/second, remaining logs are dropped until next window
for (0..200) |i| {
    if (sampler.shouldSample()) {
        try logger.infof("Message {d}", .{i}, @src());
    }
}
```

## Deterministic Key Sampling

```zig
var sampler = Sampler.init(allocator, .{ .probability = 0.2 });
defer sampler.deinit();

if (sampler.shouldSampleKey("user-123")) {
    std.debug.print("Deterministic sample\n", .{});
}
```

## Callbacks and Statistics

You can monitor sampling behavior using callbacks and statistics.

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

fn onReject(rate: f64, reason: Sampler.SampleRejectReason) void {
    std.debug.print("Sample rejected (rate: {d:.2}, reason: {s})\n", .{ rate, @tagName(reason) });
}

fn onRateExceeded(count: u32, max: u32) void {
    std.debug.print("Rate limit exceeded: {d}/{d}\n", .{ count, max });
}

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

    var sampler = Sampler.init(allocator, .{ .rateLimit = .{
        .maxRecords = 5,
        .windowMs = 1000,
    }});
    defer sampler.deinit();

    sampler.setRejectCallback(onReject);
    sampler.setRateLimitCallback(onRateExceeded);

    for (0..10) |i| {
        if (sampler.shouldSample()) {
            std.debug.print("Log {d} accepted\\n", .{i});
        }
    }

    const stats = sampler.getStats();
    std.debug.print("Stats: Total={d}, Accepted={d}, Rejected={d}\\n", .{
        stats.getTotal(),
        stats.getAccepted(),
        stats.getRejected(),
    });
}
```

## Adaptive Sampling

```zig
// Automatically adjust sampling based on throughput
var sampler = Sampler.init(allocator, .{ .adaptive = .{
    .targetRate = 1000,            // Target 1000 logs/second
    .minSampleRate = 0.01,        // Never go below 1%
    .maxSampleRate = 1.0,         // Up to 100%
    .adjustmentIntervalMs = 1000, // Adjust every second
}});
defer sampler.deinit();
```

## Every Nth Record

```zig
// Sample every 10th record
var sampler = Sampler.init(allocator, .{ .everyN = 10 });
defer sampler.deinit();

// Only every 10th log passes through
for (0..100) |i| {
    if (sampler.shouldSample()) {
        try logger.infof("Sampled message {d}", .{i}, @src());
    }
}
```

## Sampler Presets

```zig
const SamplerPresets = logly.SamplerPresets;

// No sampling - all records pass through
var none_sampler = SamplerPresets.none(allocator);
defer none_sampler.deinit();

// Sample approximately 10% of records
var sample_10 = SamplerPresets.sample10Percent(allocator);
defer sample_10.deinit();

// Limit to 100 records per second
var limit_100 = SamplerPresets.limit100PerSecond(allocator);
defer limit_100.deinit();

// Sample every 10th record
var every_10th = SamplerPresets.every10th(allocator);
defer every_10th.deinit();

// Adaptive sampling targeting 1000 records per second
var adaptive = SamplerPresets.adaptive1000PerSecond(allocator);
defer adaptive.deinit();
```

## Sampler Statistics

```zig
// Get current sampling statistics
const stats = sampler.getStats();
std.debug.print("Total records: {d}\n", .{stats.getTotal()});
std.debug.print("Accepted: {d}\n", .{stats.getAccepted()});
std.debug.print("Rejected: {d}\n", .{stats.getRejected()});
std.debug.print("Accept rate: {d:.2}%\n", .{stats.getAcceptRate() * 100});

// Reset sampler state
sampler.reset();
```

## When to Use Sampling

| Scenario | Recommended Sampling |
|----------|---------------------|
| Development | None (100%) |
| Staging | Light (50-100%) |
| Production | Moderate (10-50%) |
| High Traffic | Aggressive (1-10%) |
| Critical Systems | Errors at 100% |

## Best Practices

1. **Always keep errors** - Never sample error-level logs
2. **Monitor sample rates** - Ensure you're not missing important logs
3. **Adjust dynamically** - Use adaptive sampling for variable loads
4. **Document sampling** - Make sampling configuration visible

## New Presets (v0.0.9)

```zig
const SamplerPresets = logly.SamplerPresets;

// Additional probability presets
var sample_50 = SamplerPresets.sample50Percent(allocator);
var sample_1 = SamplerPresets.sample1Percent(allocator);

// Additional rate limit presets
var limit_10 = SamplerPresets.limit10PerSecond(allocator);
var limit_1000 = SamplerPresets.limit1000PerSecond(allocator);

// Additional every-n presets
var every_5 = SamplerPresets.every5th(allocator);
var every_100 = SamplerPresets.every100th(allocator);

// Adaptive sampling presets
var adaptive_100 = SamplerPresets.adaptive100PerSecond(allocator);
var adaptive_1000 = SamplerPresets.adaptive1000PerSecond(allocator);
```

## Aliases

| Alias | Method |
|-------|--------|
| `sample` | `shouldSample` |
| `check` | `shouldSample` |
| `allow` | `shouldSample` |
| `statistics` | `getStats` |
| `stats_` | `getStats` |
| `rate` | `getCurrentRate` |

## See Also

* [Sampling Guide](/guide/sampling) - Detailed sampling documentation
* [Sampler API](/api/sampler) - Full API reference
