~bigbes/lethe

ref: da1827c5192d2784fcecf01578b5f307ea15a8c1 lethe/internal/platform/observability/metrics.go -rw-r--r-- 2.6 KiB
da1827c5 — Eugene Blikh docs: record collector endpoint and outbox checks 24 days ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package observability

import (
	"context"

	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/collectors"
)

// Metrics is the steward-managed Prometheus steward. It owns a private
// Registry (no global registry leakage) and the lethe-specific collectors
// other layers increment. The HTTP middleware (Phase 5) records request
// counters/histograms here; the ingest service (Phase 7) increments the
// ingest counters.
//
// Registering everything via Registry.MustRegister in Init keeps wiring in
// one place. Cardinality control on HTTPRequests/HTTPDuration is enforced by
// the middleware: the route label must come from chi's RoutePattern (never
// the raw URL path).
type Metrics struct {
	Registry *prometheus.Registry

	HTTPRequests *prometheus.CounterVec
	HTTPDuration *prometheus.HistogramVec

	IngestLinesAccepted   prometheus.Counter
	IngestLinesErrored    prometheus.Counter
	IngestChunksCommitted prometheus.Counter
}

// Init builds a fresh registry, attaches the standard process and Go runtime
// collectors, and registers the lethe-specific HTTP and ingest series.
func (m *Metrics) Init(_ context.Context) error {
	m.Registry = prometheus.NewRegistry()

	m.Registry.MustRegister(
		collectors.NewProcessCollector(collectors.ProcessCollectorOpts{}),
		collectors.NewGoCollector(),
	)

	m.HTTPRequests = prometheus.NewCounterVec(
		prometheus.CounterOpts{
			Name: "lethe_http_requests_total",
			Help: "Total HTTP requests handled, labelled by method, chi route pattern, and status code.",
		},
		[]string{"method", "route", "status"},
	)

	m.HTTPDuration = prometheus.NewHistogramVec(
		prometheus.HistogramOpts{
			Name:    "lethe_http_request_duration_seconds",
			Help:    "HTTP request duration in seconds, labelled by method and chi route pattern.",
			Buckets: prometheus.DefBuckets,
		},
		[]string{"method", "route"},
	)

	m.IngestLinesAccepted = prometheus.NewCounter(prometheus.CounterOpts{
		Name: "lethe_ingest_lines_accepted_total",
		Help: "Total ingest JSONL lines accepted (validated and queued for commit).",
	})
	m.IngestLinesErrored = prometheus.NewCounter(prometheus.CounterOpts{
		Name: "lethe_ingest_lines_errored_total",
		Help: "Total ingest JSONL lines rejected (validation, size, or schema failures).",
	})
	m.IngestChunksCommitted = prometheus.NewCounter(prometheus.CounterOpts{
		Name: "lethe_ingest_chunks_committed_total",
		Help: "Total ingest chunks successfully committed to the database.",
	})

	m.Registry.MustRegister(
		m.HTTPRequests,
		m.HTTPDuration,
		m.IngestLinesAccepted,
		m.IngestLinesErrored,
		m.IngestChunksCommitted,
	)
	return nil
}