111 lines
3.2 KiB
Go
111 lines
3.2 KiB
Go
package metrics
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"go.opentelemetry.io/otel/attribute"
|
|
"go.opentelemetry.io/otel/metric"
|
|
|
|
"github.com/kanootoko/codevault/internal"
|
|
)
|
|
|
|
type Metrics struct {
|
|
HTTP HTTPMetrics
|
|
Value ValueMetrics
|
|
}
|
|
|
|
func NewMetrics(meter metric.Meter) Metrics {
|
|
metrics := Metrics{
|
|
HTTP: newHTTPMetrics(meter),
|
|
Value: newValueMetrics(meter),
|
|
}
|
|
addObservableMetrics(meter)
|
|
return metrics
|
|
}
|
|
|
|
type HTTPMetrics struct {
|
|
// Total HTTP requests with [route, status]
|
|
RequestsTotal metric.Int64Counter
|
|
|
|
// Request duration histogram in seconds with [route]
|
|
RequestDuration metric.Float64Histogram
|
|
}
|
|
|
|
func newHTTPMetrics(meter metric.Meter) HTTPMetrics {
|
|
requestsTotal, _ := meter.Int64Counter(
|
|
"http_requests_total",
|
|
metric.WithDescription("Total number of HTTP requests"),
|
|
)
|
|
requestDuration, _ := meter.Float64Histogram(
|
|
"http_request_duration_seconds",
|
|
metric.WithDescription("HTTP request duration histogram in seconds"),
|
|
metric.WithExplicitBucketBoundaries(0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1.0, 2.5, 5.0),
|
|
metric.WithUnit("s"),
|
|
)
|
|
return HTTPMetrics{
|
|
RequestsTotal: requestsTotal,
|
|
RequestDuration: requestDuration,
|
|
}
|
|
}
|
|
|
|
type ValueMetrics struct {
|
|
// Successful getValue lookups, with [code]. Only successful lookups carry a
|
|
// code label since the set of stored codes is bounded, unlike guessed/failed ones.
|
|
GetSuccessTotal metric.Int64Counter
|
|
|
|
// Failed getValue lookups, with [reason] (not_found|rate_limited).
|
|
GetFailedTotal metric.Int64Counter
|
|
|
|
// Successful setValue writes, with [user].
|
|
SetSuccessTotal metric.Int64Counter
|
|
|
|
// Failed setValue writes, with [reason] (bad_request|unauthorized).
|
|
SetFailedTotal metric.Int64Counter
|
|
}
|
|
|
|
func newValueMetrics(meter metric.Meter) ValueMetrics {
|
|
getSuccessTotal, _ := meter.Int64Counter(
|
|
"codevault_get_value_success_total",
|
|
metric.WithDescription("Total number of successful getValue lookups"),
|
|
)
|
|
getFailedTotal, _ := meter.Int64Counter(
|
|
"codevault_get_value_failed_total",
|
|
metric.WithDescription("Total number of failed getValue lookups"),
|
|
)
|
|
setSuccessTotal, _ := meter.Int64Counter(
|
|
"codevault_set_value_success_total",
|
|
metric.WithDescription("Total number of successful setValue writes"),
|
|
)
|
|
setFailedTotal, _ := meter.Int64Counter(
|
|
"codevault_set_value_failed_total",
|
|
metric.WithDescription("Total number of failed setValue writes"),
|
|
)
|
|
return ValueMetrics{
|
|
GetSuccessTotal: getSuccessTotal,
|
|
GetFailedTotal: getFailedTotal,
|
|
SetSuccessTotal: setSuccessTotal,
|
|
SetFailedTotal: setFailedTotal,
|
|
}
|
|
}
|
|
|
|
func addObservableMetrics(meter metric.Meter) {
|
|
timeStarted := time.Now()
|
|
_, _ = meter.Int64ObservableGauge(
|
|
"startup_time",
|
|
metric.WithDescription("Startup timestamp"),
|
|
metric.WithInt64Callback(func(ctx context.Context, io metric.Int64Observer) error {
|
|
io.Observe(timeStarted.Unix(), metric.WithAttributes(attribute.String("version", internal.Version)))
|
|
return nil
|
|
}),
|
|
)
|
|
_, _ = meter.Int64ObservableGauge(
|
|
"last_update_time",
|
|
metric.WithDescription("Current timestamp"),
|
|
metric.WithInt64Callback(func(ctx context.Context, io metric.Int64Observer) error {
|
|
io.Observe(time.Now().Unix(), metric.WithAttributes(attribute.String("version", internal.Version)))
|
|
return nil
|
|
}),
|
|
)
|
|
}
|