diff --git a/README.md b/README.md index 4e856a9..0ab4857 100644 --- a/README.md +++ b/README.md @@ -207,12 +207,12 @@ won't be renamed. | `epmon_service_up` | gauge | Alerting: `epmon_service_up == 0` pages. State, not last probe. | | `epmon_probe_total{result="success"\|"failure"}` | counter | Raw outcome rates; burn-rate alerts. | | `epmon_probe_duration_seconds` | histogram | Latency: `histogram_quantile(0.99, sum(rate(epmon_probe_duration_seconds_bucket[5m])) by (service, le))` for p99 degradation and slow drift. Buckets: 5ms…10s. | -| `epmon_probe_skipped_total` | counter | Overlap-guard skips (scheduler shed load). | -| `epmon_store_queue_depth`, `epmon_store_cmd_queue_depth` | gauges | Internal backpressure; sustained non-zero deserves a look. | -| `epmon_store_dropped_total`, `epmon_store_write_timeout_total` | counters | Lost or aborted writes — alert on increase. | -| `epmon_service_history_migrated_total{result="ok"\|"no_match"}` | counter | Alias-migration outcomes after reloads. | -| `epmon_config_reload_total{result="ok"\|"error"}` | counter | Config reload outcomes. | -| `epmon_uptime_seconds`, `epmon_build_info` | gauge | Process age and build identity. | +| `epmon_probe_skipped_total` | counter | Reserved: overlap-guard skips (no guard exists yet; always zero). | +| `epmon_store_queue_depth`, `epmon_store_cmd_queue_depth` | gauges | Reserved: internal backpressure hooks for a future store actor; always zero. | +| `epmon_store_dropped_total`, `epmon_store_write_timeout_total` | counters | Reserved: unwritable today, so permanently zero — do not alert on them. | +| `epmon_service_history_migrated_total{result="ok"\|"no_match"}` | counter | Reserved: alias-migration outcomes (no migration path exists yet). | +| `epmon_config_reload_total{result="ok"\|"error"}` | counter | Reserved: config reload outcomes (no reload path exists yet). | +| `epmon_uptime_seconds`, `epmon_build_info` | gauge | Process age and build identity (`version`/`commit` from release ldflags). | ## Development diff --git a/cmd/epmon/main.go b/cmd/epmon/main.go index ce8c2a7..e61701c 100644 --- a/cmd/epmon/main.go +++ b/cmd/epmon/main.go @@ -109,6 +109,7 @@ func runDefault(args []string, stdout, stderr io.Writer) int { } registry := metrics.New() + registry.SetBuildInfo(version, commit) sched := scheduler.New(cfg, st, registry) sched.Run(ctx) defer sched.Stop() diff --git a/internal/metrics/metrics_test.go b/internal/metrics/metrics_test.go index 0c71d42..4d5a806 100644 --- a/internal/metrics/metrics_test.go +++ b/internal/metrics/metrics_test.go @@ -72,6 +72,19 @@ func TestHistogramBoundedState(t *testing.T) { } } +// TestBuildInfo pins the stamped build identity line. The binary wires +// its ldflags version/commit into the registry at boot (see runDefault); +// an empty rendering means that wiring regressed. +func TestBuildInfo(t *testing.T) { + r := New() + r.SetBuildInfo("v1.2.3", "abc1234") + out := r.Snapshot() + want := `epmon_build_info{version="v1.2.3",commit="abc1234"} 1` + if !strings.Contains(out, want) { + t.Errorf("snapshot missing %q\n%s", want, out) + } +} + func TestHandler(t *testing.T) { r := New() h := r.Handler()