From 087f8fe84f0759e3bf1eb886615d3b9625d23f63 Mon Sep 17 00:00:00 2001 From: Travis Groth Date: Mon, 22 Jul 2019 18:09:37 -0400 Subject: [PATCH] Fix checksum integer overflow in metrics --- cmd/pomerium/main.go | 8 +++++--- internal/metrics/helpers_test.go | 10 +++++++++- internal/metrics/info.go | 12 ++++++------ internal/metrics/info_test.go | 6 +++--- 4 files changed, 23 insertions(+), 13 deletions(-) diff --git a/cmd/pomerium/main.go b/cmd/pomerium/main.go index 9c19ee647..4891304fe 100644 --- a/cmd/pomerium/main.go +++ b/cmd/pomerium/main.go @@ -213,11 +213,13 @@ func parseOptions(configFile string) (*config.Options, error) { metrics.AddPolicyCountCallback(o.Services, func() int64 { return int64(len(o.Policies)) }) - checksumInt, err := strconv.ParseInt(fmt.Sprintf("0x%s", o.Checksum()), 0, 64) + + checksumDec, err := strconv.ParseUint(o.Checksum(), 16, 64) if err != nil { - log.Warn().Err(err).Msg("Could not parse config checksum into integer") + log.Warn().Err(err).Msg("Could not parse config checksum into decimal") } - metrics.SetConfigChecksum(o.Services, checksumInt) + metrics.SetConfigChecksum(o.Services, checksumDec) + return o, nil } diff --git a/internal/metrics/helpers_test.go b/internal/metrics/helpers_test.go index 12b779318..b8f02a2e7 100644 --- a/internal/metrics/helpers_test.go +++ b/internal/metrics/helpers_test.go @@ -36,7 +36,15 @@ func testDataRetrieval(v *view.View, t *testing.T, want string) { } } -func testMetricRetrieval(metrics []*metricdata.Metric, t *testing.T, labels []metricdata.LabelValue, value int64, name string) { +func testMetricRetrieval(metrics []*metricdata.Metric, t *testing.T, labels []metricdata.LabelValue, value interface{}, name string) { + switch value.(type) { + case int64: + case float64: + case uint64: + default: + t.Errorf("Got an unexpected type for value: %T", value) + } + found := false for _, metric := range metrics { if metric.Descriptor.Name != name { diff --git a/internal/metrics/info.go b/internal/metrics/info.go index b0c9b3355..d822e7482 100644 --- a/internal/metrics/info.go +++ b/internal/metrics/info.go @@ -76,7 +76,7 @@ type metricRegistry struct { registry *metric.Registry buildInfo *metric.Int64Gauge policyCount *metric.Int64DerivedGauge - configChecksum *metric.Int64Gauge + configChecksum *metric.Float64Gauge sync.Once } @@ -99,8 +99,8 @@ func (r *metricRegistry) init() { log.Error().Err(err).Msg("internal/metrics: failed to register build info metric") } - r.configChecksum, err = r.registry.AddInt64Gauge("config_checksum_int64", - metric.WithDescription("Config checksum represented in int64 notation"), + r.configChecksum, err = r.registry.AddFloat64Gauge("config_checksum_decimal", + metric.WithDescription("Config checksum represented in decimal notation"), metric.WithLabelKeys("service"), ) if err != nil { @@ -149,7 +149,7 @@ func RegisterInfoMetrics() { metricproducer.GlobalManager().AddProducer(registry.registry) } -func (r *metricRegistry) setConfigChecksum(service string, checksum int64) { +func (r *metricRegistry) setConfigChecksum(service string, checksum uint64) { if r.configChecksum == nil { return } @@ -157,12 +157,12 @@ func (r *metricRegistry) setConfigChecksum(service string, checksum int64) { if err != nil { log.Error().Err(err).Msg("internal/metrics: failed to get config checksum metric") } - m.Set(checksum) + m.Set(float64(checksum)) } // SetConfigChecksum creates the configuration checksum metric. You must call RegisterInfoMetrics to // have this exported -func SetConfigChecksum(service string, checksum int64) { +func SetConfigChecksum(service string, checksum uint64) { registry.setConfigChecksum(service, checksum) } diff --git a/internal/metrics/info_test.go b/internal/metrics/info_test.go index 50eddfc47..c29285a49 100644 --- a/internal/metrics/info_test.go +++ b/internal/metrics/info_test.go @@ -49,7 +49,7 @@ func Test_SetBuildInfo(t *testing.T) { } SetBuildInfo("test_service") - testMetricRetrieval(registry.registry.Read(), t, wantLabels, 1, "build_info") + testMetricRetrieval(registry.registry.Read(), t, wantLabels, int64(1), "build_info") } func Test_AddPolicyCountCallback(t *testing.T) { @@ -65,11 +65,11 @@ func Test_AddPolicyCountCallback(t *testing.T) { func Test_SetConfigChecksum(t *testing.T) { registry = newMetricRegistry() - wantValue := int64(42) + wantValue := uint64(42) wantLabels := []metricdata.LabelValue{{Value: "test_service", Present: true}} SetConfigChecksum("test_service", wantValue) - testMetricRetrieval(registry.registry.Read(), t, wantLabels, wantValue, "config_checksum_int64") + testMetricRetrieval(registry.registry.Read(), t, wantLabels, float64(wantValue), "config_checksum_decimal") } func Test_RegisterInfoMetrics(t *testing.T) {