Telemetry primitives + CandyWish session middleware
Counters, gauges, histograms, UpDownCounters, AsyncCounters, AsyncGauges with pluggable backends โ drop-in middleware for SSH session metrics. Six instrument kinds + four backends: InMemory, JsonStream, StatsD, Prometheus textfile, plus a Multi fan-out. Built-in cardinality tracking with FIFO eviction.
composer require sugarcraft/candy-metrics
use SugarCraft\Metrics\Registry;
use SugarCraft\Metrics\Backend\StatsdBackend;
$reg = new Registry(new StatsdBackend('127.0.0.1', 8125));
$reg->counter('http.requests', 1, ['route' => '/api/foo', 'status' => '200']);
$reg->gauge ('queue.depth', 42);
$stop = $reg->time('http.duration', ['route' => '/api/foo']);
handleRequest();
$stop();
// Pre-tag every emit:
$req = $reg->withTags(['request_id' => $rid, 'user' => $userId]);
$req->counter('events');
->withTags(['user' => $u]) returns a registry that pre-tags every emit.$stop = $reg->time('http.duration'); $stop() โ emit a histogram sample on close.cardinality().# TYPE / # HELP lines before first sample (Prometheus textfile collector metadata).| Class | Method | Description |
|---|---|---|
| Descriptor | new(name, help, type, labelKeys) | Metric registration DTO (type: counter|gauge|histogram|summary) |
| Registry | new(backend) | Create registry with backend |
| Registry | new(backend, defaultTags, cardinalityLimit) | Create registry with backend, default tags, and per-metric cardinality limit (default 10 000) |
| Registry | register(Descriptor) | Register metric descriptor for early TYPE/HELP emission |
| Registry | counter(name, value, tags) | Increment counter |
| Registry | gauge(name, value, tags) | Set gauge value |
| Registry | histogram(name, value, tags) | Record a histogram sample (14 classic buckets +Inf on Prometheus backend) |
| Registry | upDownCounter(name, amount, tags) | Add positive or negative increment to a synchronous up-down counter |
| Registry | asyncCounter(name, value, tags) | Record an observation from an asynchronous counter callback |
| Registry | asyncGauge(name, value, tags) | Record an observation from an asynchronous gauge callback |
| Registry | time(name, tags) | Time a block, returns callable |
| Registry | withTags(tags) | Pre-tag every emit |
| Registry | backend() | Returns the current backend |
| Registry | cardinality(name) | Number of unique label-value combinations currently tracked for a metric |
| Registry | deleteLabelValues(name, tags) | Evict a specific label combination (FIFO eviction also runs automatically when limit is exceeded) |
| UpDownCounter | new(registry, name, help) | Create an up-down counter instrument |
| UpDownCounter | add(amount, tags) | Add positive or negative increment |
| AsyncCounter | new(registry, name, help, callback, tags) | Create an async counter instrument |
| AsyncCounter | observe() | Invoke callback and record the returned sum |
| AsyncGauge | new(registry, name, help, callback, tags) | Create an async gauge instrument |
| AsyncGauge | observe() | Invoke callback and record the returned instantaneous value |
| InMemoryBackend | new() | In-memory storage |
| StatsdBackend | new(host, port) | StatsD protocol |
| PrometheusFileBackend | new(path) | Prometheus textfile (atomic write, 14 bucket boundaries +Inf) |
VHS-recorded GIFs of every example shipped with the library. Regenerated automatically on every push that touches the source.