candycore/candy-metrics

Telemetry primitives for SugarCraft / CandyWish — counters, gauges, histograms with pluggable backends (in-memory, StatsD UDP, Prometheus textfile, JSON stream). Drop-in middleware for SSH session metrics.

Maintainers

Package info

github.com/sugarcraft/candy-metrics

Documentation

pkg:composer/candycore/candy-metrics

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 1

Open Issues: 0

v0.2.0 2026-05-07 02:01 UTC

This package is not auto-updated.

Last update: 2026-05-08 01:39:22 UTC


README

candy-metrics

CandyMetrics

CI codecov Packagist Version License PHP

Lightweight telemetry primitives for SugarCraft / CandyWish servers. Counters, gauges, histograms with pluggable backends — drop-in middleware for SSH session metrics.

composer require sugarcraft/candy-metrics

Concepts

Primitive Behaviour
Counter Monotonic value that accumulates (connect counts, errors).
Gauge Instantaneous value that replaces on set (queue depth, RSS).
Histogram Distribution of samples (latency, payload size).

A Registry is the application-facing facade; it forwards every emit to the configured Backend. Backends decide how to persist or forward.

Usage

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();

withTags() returns a registry that pre-tags every emit:

$req = $reg->withTags(['request_id' => $rid, 'user' => $userId]);
$req->counter('events');   // tagged with request_id + user automatically

Backends

InMemoryBackend

Useful for tests and for fanning out to multiple backends. Counters add up, gauges hold the last value, histograms keep every sample.

JsonStreamBackend

Newline-delimited JSON, one event per line. The simplest, most diagnostic-friendly target. Default writes to stderr.

{"ts":"2026-05-02T16:30:00+00:00","kind":"counter","name":"hits","value":1,"tags":{"route":"/x"}}

StatsdBackend

UDP datagrams in the etsy / DogStatsD wire format. Tags emitted as |#k:v,... (drop with dogstatsd: false for legacy servers).

hits:1|c|#route:/x,env:prod

PrometheusFileBackend

Atomically rewrites a .prom textfile-collector file with the current state of every metric. Pairs with node_exporter --collector.textfile.directory=…. Counter values accumulate across flush()s; histograms expose _count and _sum.

MultiBackend

Fan out to multiple backends — e.g. live StatsD plus a JSON audit trail.

$reg = new Registry(new MultiBackend(
    new StatsdBackend(),
    new JsonStreamBackend('/var/log/metrics.jsonl'),
));

CandyWish session middleware

Wires session telemetry into a CandyWish stack:

use SugarCraft\Wish\Server;
use SugarCraft\Metrics\Registry;
use SugarCraft\Metrics\Backend\PrometheusFileBackend;
use SugarCraft\Metrics\Middleware\SessionMetrics;

$reg = new Registry(new PrometheusFileBackend('/var/lib/wish/metrics.prom'));

Server::new()
    ->use(new SessionMetrics($reg))
    ->use(/* ... your stack ... */)
    ->serve();

Per session this emits:

Metric Type Tags
wish.session.connect counter user, term
wish.session.duration histogram user, term
wish.session.error counter user, term, exception

Pass extraTags (a callable receiving the Session) to add things like client subnet, geo, build version.

Status

Phase 9+ — first cut. 23 tests / 57 assertions across Registry, four backends, and the SessionMetrics middleware.