mirror of
https://github.com/coder/coder.git
synced 2025-07-03 16:13:58 +00:00
chore: add tx metrics and logs for serialization errors (#15215)
Before db_metrics were all or nothing. Now `InTx` metrics are always recorded, and query metrics are opt in. Adds instrumentation & logging around serialization failures in the database.
This commit is contained in:
3
coderd/coderdtest/promhelp/doc.go
Normal file
3
coderd/coderdtest/promhelp/doc.go
Normal file
@ -0,0 +1,3 @@
|
||||
// Package promhelp provides helper functions for asserting Prometheus
|
||||
// metric values in unit tests.
|
||||
package promhelp
|
87
coderd/coderdtest/promhelp/metrics.go
Normal file
87
coderd/coderdtest/promhelp/metrics.go
Normal file
@ -0,0 +1,87 @@
|
||||
package promhelp
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"maps"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
ptestutil "github.com/prometheus/client_golang/prometheus/testutil"
|
||||
io_prometheus_client "github.com/prometheus/client_model/go"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// RegistryDump returns the http page for a given registry's metrics.
|
||||
// Very useful for visual debugging.
|
||||
func RegistryDump(reg *prometheus.Registry) string {
|
||||
h := promhttp.HandlerFor(reg, promhttp.HandlerOpts{})
|
||||
rec := httptest.NewRecorder()
|
||||
req, _ := http.NewRequestWithContext(context.Background(), http.MethodGet, "/", nil)
|
||||
h.ServeHTTP(rec, req)
|
||||
resp := rec.Result()
|
||||
data, _ := io.ReadAll(resp.Body)
|
||||
_ = resp.Body.Close()
|
||||
return string(data)
|
||||
}
|
||||
|
||||
// Compare can be used to compare a registry to some prometheus formatted
|
||||
// text. If any values differ, an error is returned.
|
||||
// If metric names are passed in, only those metrics will be compared.
|
||||
// Usage: `Compare(reg, RegistryDump(reg))`
|
||||
func Compare(reg prometheus.Gatherer, compare string, metricNames ...string) error {
|
||||
return ptestutil.GatherAndCompare(reg, strings.NewReader(compare), metricNames...)
|
||||
}
|
||||
|
||||
// HistogramValue returns the value of a histogram metric with the given name and labels.
|
||||
func HistogramValue(t testing.TB, reg prometheus.Gatherer, metricName string, labels prometheus.Labels) *io_prometheus_client.Histogram {
|
||||
t.Helper()
|
||||
|
||||
labeled := MetricValue(t, reg, metricName, labels)
|
||||
require.NotNilf(t, labeled, "metric %q with labels %v not found", metricName, labels)
|
||||
return labeled.GetHistogram()
|
||||
}
|
||||
|
||||
// GaugeValue returns the value of a gauge metric with the given name and labels.
|
||||
func GaugeValue(t testing.TB, reg prometheus.Gatherer, metricName string, labels prometheus.Labels) int {
|
||||
t.Helper()
|
||||
|
||||
labeled := MetricValue(t, reg, metricName, labels)
|
||||
require.NotNilf(t, labeled, "metric %q with labels %v not found", metricName, labels)
|
||||
return int(labeled.GetGauge().GetValue())
|
||||
}
|
||||
|
||||
// CounterValue returns the value of a counter metric with the given name and labels.
|
||||
func CounterValue(t testing.TB, reg prometheus.Gatherer, metricName string, labels prometheus.Labels) int {
|
||||
t.Helper()
|
||||
|
||||
labeled := MetricValue(t, reg, metricName, labels)
|
||||
require.NotNilf(t, labeled, "metric %q with labels %v not found", metricName, labels)
|
||||
return int(labeled.GetCounter().GetValue())
|
||||
}
|
||||
|
||||
func MetricValue(t testing.TB, reg prometheus.Gatherer, metricName string, labels prometheus.Labels) *io_prometheus_client.Metric {
|
||||
t.Helper()
|
||||
|
||||
metrics, err := reg.Gather()
|
||||
require.NoError(t, err)
|
||||
|
||||
for _, m := range metrics {
|
||||
if m.GetName() == metricName {
|
||||
for _, labeled := range m.GetMetric() {
|
||||
mLabels := make(prometheus.Labels)
|
||||
for _, v := range labeled.GetLabel() {
|
||||
mLabels[v.GetName()] = v.GetValue()
|
||||
}
|
||||
if maps.Equal(mLabels, labels) {
|
||||
return labeled
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
Reference in New Issue
Block a user