niko_trust/internal/server/metrics.go
Niko Marmeladkov 79df689f7a refactor: drop PoW, checkpoint chain, gossip, light node and BFT; keep WS
The decentralization stack overcomplicated the project. Removed:
internal/pow, internal/smt, internal/checkpoint, internal/bft,
internal/lightnode, cmd/lightnode, relay gossip/checkpoint/proof/BFT
endpoints, their docs, vectors and the blake3 dependency.

Kept: WebSocket streaming on the relay, the full protocol v1 object set
including DelegationClaim (0x07) and KeyRotation request/confirm
(0x08/0x09) with chain resolution in verify.Graph, TrustedIssuers,
batch fetch, stable cursor pagination, per-type metrics.

INV-1 reverts to its original form: the relay holds no keys again.
Everything removed remains reachable at commit 20cc52c.
2026-08-26 00:49:25 +03:00

95 lines
3.3 KiB
Go

package server
import (
"fmt"
"io"
"sort"
"strings"
"sync/atomic"
)
// Metrics holds the relay's in-process counters, exposed at /metrics in the
// Prometheus text exposition format. No external dependency: the values are
// plain atomic counters rendered as text.
type Metrics struct {
objectsStored atomic.Uint64
objectsRejected atomic.Uint64
objectsDeleted atomic.Uint64
challengesIssued atomic.Uint64
assertionsOK atomic.Uint64
assertionsFailed atomic.Uint64
requestsTotal atomic.Uint64
sessionsActive atomic.Int64
wsConnections atomic.Int64
wsMessagesSent atomic.Uint64
// objectsByType holds one counter per known object type name. The map is
// populated once at construction and never mutated afterwards, so
// concurrent reads are safe.
objectsByType map[string]*atomic.Uint64
}
// NewMetrics returns metrics with the per-type counters preallocated.
func NewMetrics() *Metrics {
m := &Metrics{objectsByType: make(map[string]*atomic.Uint64)}
for _, name := range []string{
"identity", "claim", "revocation", "approval_request",
"approval_response", "auth_assertion", "delegation",
"key_rotation_request", "key_rotation_confirm",
} {
m.objectsByType[name] = &atomic.Uint64{}
}
return m
}
// inc records an event.
func (m *Metrics) inc(f *atomic.Uint64) { f.Add(1) }
// incStoredType records one accepted object of the given type.
func (m *Metrics) incStoredType(typ string) {
if c, ok := m.objectsByType[typ]; ok {
c.Add(1)
}
}
// Write renders the counters in Prometheus text format.
func (m *Metrics) Write(w io.Writer) {
fmt.Fprintf(w, "# TYPE trust_objects_stored counter\n")
fmt.Fprintf(w, "trust_objects_stored %d\n", m.objectsStored.Load())
fmt.Fprintf(w, "# TYPE trust_objects_rejected counter\n")
fmt.Fprintf(w, "trust_objects_rejected %d\n", m.objectsRejected.Load())
fmt.Fprintf(w, "# TYPE trust_challenges_issued counter\n")
fmt.Fprintf(w, "trust_challenges_issued %d\n", m.challengesIssued.Load())
fmt.Fprintf(w, "# TYPE trust_assertions_ok counter\n")
fmt.Fprintf(w, "trust_assertions_ok %d\n", m.assertionsOK.Load())
fmt.Fprintf(w, "# TYPE trust_assertions_failed counter\n")
fmt.Fprintf(w, "trust_assertions_failed %d\n", m.assertionsFailed.Load())
fmt.Fprintf(w, "# TYPE trust_requests_total counter\n")
fmt.Fprintf(w, "trust_requests_total %d\n", m.requestsTotal.Load())
fmt.Fprintf(w, "# TYPE trust_sessions_active gauge\n")
fmt.Fprintf(w, "trust_sessions_active %d\n", m.sessionsActive.Load())
fmt.Fprintf(w, "# TYPE trust_ws_connections gauge\n")
fmt.Fprintf(w, "trust_ws_connections %d\n", m.wsConnections.Load())
fmt.Fprintf(w, "# TYPE trust_ws_messages_sent counter\n")
fmt.Fprintf(w, "trust_ws_messages_sent %d\n", m.wsMessagesSent.Load())
for _, typ := range sortedTypeNames(m.objectsByType) {
name := "trust_objects_stored_" + sanitizeMetricName(typ)
fmt.Fprintf(w, "# TYPE %s counter\n", name)
fmt.Fprintf(w, "%s %d\n", name, m.objectsByType[typ].Load())
}
}
// sortedTypeNames renders the per-type counters in stable order.
func sortedTypeNames(byType map[string]*atomic.Uint64) []string {
names := make([]string, 0, len(byType))
for k := range byType {
names = append(names, k)
}
sort.Strings(names)
return names
}
// sanitizeMetricName maps type names into metric-safe labels.
func sanitizeMetricName(s string) string {
return strings.NewReplacer("-", "_").Replace(s)
}