metrics

package
v0.4.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 20, 2026 License: BSD-3-Clause Imports: 5 Imported by: 0

Documentation

Overview

Package metrics owns the Prometheus instrumentation for the in-guest weft-microvm-agent. The daemon registers a small surface :

  • weft_microvm_agent_build_info{version,commit,date} — boot fingerprint
  • weft_microvm_agent_apply_total{concern,result} — Apply call counter
  • weft_microvm_agent_apply_duration_seconds{concern} — Apply latency histogram
  • weft_microvm_agent_nats_connected — 0/1 gauge
  • weft_microvm_agent_firewall_status_publishes_total{result} — firewallstatus.Emitter publishOnce counter
  • weft_microvm_agent_firewall_drops_packets_total — nftables drop tail-rule packet counter
  • weft_microvm_agent_firewall_drops_bytes_total — nftables drop tail-rule byte counter

Each NATS-driven subscriber (mesh / mounts / sshkeys / properties / boot) calls Recorder.RecordApply after running its ApplyFunc ; the concern label routes the observation to the right time-series. The firewallstatus emitter wires Recorder.RecordFirewallStatusPublish via its PublishHook seam — parallel to RecordApply but specific to the publish-loop reverse direction. The same emitter additionally calls Recorder.RecordFirewallDrops on every successful read so the kernel's counter+drop tail-rule surfaces as a monotonic Prometheus counter pair (rate() over them gives the live drop pps / Bps).

Mirrors the shape of openweft/weft-network's internal/metrics package — same Registry-not-Default policy, same Handler() wiring.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Recorder

type Recorder struct {
	// contains filtered or unexported fields
}

Recorder bundles the metrics + the helpers subscribers call from their Apply hot path. Construct once at startup ; share by pointer.

The recorder owns its own prometheus.Registry rather than using promauto's default — keeps test isolation tight (each New() is a clean slate) and prevents process-global pollution that would surface as collisions in unit tests run in the same binary.

func New

func New(version, commit, date string) *Recorder

New builds + registers the recorder against a fresh registry. version / commit / date come from main.go's -ldflags stamps so the build_info metric is useful in a multi-VM scrape.

func (*Recorder) Handler

func (r *Recorder) Handler() http.Handler

Handler returns the http.Handler serving /metrics. Caller wires it into a dedicated listener (different port from the Introspect gRPC) so the scrape surface doesn't share fate with the control plane.

func (*Recorder) RecordApply

func (r *Recorder) RecordApply(concern string, err error, dur time.Duration)

RecordApply records one Apply invocation : increments the counter (labelled ok / error from err) and observes the histogram (labelled by concern only — error vs ok latency are usually different distributions but the volume here is too low to justify the extra cardinality, and the counter already carries the success ratio).

Safe to call with a nil receiver — subscribers without metrics wiring (tests, non-prod main()s) get a no-op. Matches the pattern other Anthropic-style daemons use to keep test setup cheap.

func (*Recorder) RecordFirewallDrops added in v0.4.0

func (r *Recorder) RecordFirewallDrops(packets, bytes uint64)

RecordFirewallDrops folds one observation of the nftables drop tail-rule counter pair into the monotonic Prometheus counters.

The kernel counter is reset to 0 every time the firewall reconciler rebuilds the table (flush + reapply ; happens on every desired-state change). Prometheus counters, however, are supposed to be monotonic so rate() / increase() can detect process restarts vs real activity via the standard counter-reset heuristic.

The accumulator handles this : we keep the last raw (packets, bytes) value we saw the kernel report. On each call :

  • growth (current >= last) → Add(current - last) ; the published counter grows by the delta only.
  • reset (current < last) → the kernel rebuilt its table ; we reseed last := 0 and Add(current) so the next interval's worth of drops shows up immediately.

Packets and bytes are tracked independently in case the two counters drift across a rebuild boundary (they always reset together in practice, but the field-level guard keeps the invariant honest).

Nil-receiver-safe like RecordApply / RecordFirewallStatusPublish. Guarded by a mutex because the firewallstatus emitter is the sole caller today but the field is exposed to any future caller (e.g. a pull-model reconciler that ticks on a different schedule).

func (*Recorder) RecordFirewallStatusPublish added in v0.3.1

func (r *Recorder) RecordFirewallStatusPublish(err error)

RecordFirewallStatusPublish records one Emitter.publishOnce invocation in the firewallstatus loop : increments the counter labelled ok / error from err. Parallel to RecordApply (same ok / error convention) but separate metric because publish-loop and apply-loop have different operator narratives (the apply histogram only makes sense for the reconcile side).

Wired from cmd/weft-microvm-agent's startFirewallStatus via firewallstatus.Emitter.SetMetricsHook so the hook receives every publish outcome — happy path or transient transport hiccup.

Nil-receiver-safe like RecordApply / SetNATSConnected so tests that don't construct a Recorder still tick along.

func (*Recorder) Registry

func (r *Recorder) Registry() *prometheus.Registry

Registry exposes the underlying prometheus.Registry for tests + the rare case a caller wants to register a domain-specific metric alongside ours.

func (*Recorder) SetNATSConnected

func (r *Recorder) SetNATSConnected(connected bool)

SetNATSConnected flips the gauge. Call once from the NATS subscriber lifecycle on connect (true) ; call false on close. Nil-receiver-safe like RecordApply.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL