From 295c9c1dc22b905ff2ce727c770a27c3e2fc9b3c Mon Sep 17 00:00:00 2001 From: brawndou <112038567+brawndou@users.noreply.github.com> Date: Mon, 30 Jan 2023 13:00:28 -0800 Subject: [PATCH] Fix for bad prometheus metrics name (#205) * improved internal metrics config setup * internal metric names are sanitized at runtime --- m3/reporter_integration_test.go | 2 +- m3/scope_test.go | 3 +- scope.go | 32 +++-- scope_registry.go | 72 +++++----- scope_registry_test.go | 6 +- scope_test.go | 232 +++++++++++++++++++------------- 6 files changed, 204 insertions(+), 143 deletions(-) diff --git a/m3/reporter_integration_test.go b/m3/reporter_integration_test.go index 8238d01e..4ccfe586 100644 --- a/m3/reporter_integration_test.go +++ b/m3/reporter_integration_test.go @@ -110,7 +110,7 @@ func testProcessFlushOnExit(t *testing.T, i int) { require.Equal(t, 1, len(server.Service.getBatches())) require.NotNil(t, server.Service.getBatches()[0]) // 3 metrics are emitted by mainFileFmt plus various other internal metrics. - require.Equal(t, internalMetrics+cardinalityMetrics+3, len(server.Service.getBatches()[0].GetMetrics())) + require.Equal(t, internalMetrics+3, len(server.Service.getBatches()[0].GetMetrics())) metrics := server.Service.getBatches()[0].GetMetrics() fmt.Printf("Test %d emitted:\n%v\n", i, metrics) } diff --git a/m3/scope_test.go b/m3/scope_test.go index 4886e954..23bbaf99 100644 --- a/m3/scope_test.go +++ b/m3/scope_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -53,6 +53,7 @@ func newTestReporterScope( Prefix: scopePrefix, Tags: scopeTags, CachedReporter: r, + MetricsOption: tally.SendInternalMetrics, }, shortInterval) return r, scope, func() { diff --git a/scope.go b/scope.go index 7888fc48..1418348d 100644 --- a/scope.go +++ b/scope.go @@ -1,4 +1,4 @@ -// Copyright (c) 2022 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -28,7 +28,17 @@ import ( "go.uber.org/atomic" ) +// InternalMetricOption is used to configure internal metrics. +type InternalMetricOption int + const ( + // Unset is the "no-op" config, which turns off internal metrics. + Unset InternalMetricOption = iota + // SendInternalMetrics turns on internal metrics submission. + SendInternalMetrics + // OmitInternalMetrics turns off internal metrics submission. + OmitInternalMetrics + _defaultInitialSliceSize = 16 ) @@ -95,15 +105,15 @@ type scope struct { // ScopeOptions is a set of options to construct a scope. type ScopeOptions struct { - Tags map[string]string - Prefix string - Reporter StatsReporter - CachedReporter CachedStatsReporter - Separator string - DefaultBuckets Buckets - SanitizeOptions *SanitizeOptions - registryShardCount uint - skipInternalMetrics bool + Tags map[string]string + Prefix string + Reporter StatsReporter + CachedReporter CachedStatsReporter + Separator string + DefaultBuckets Buckets + SanitizeOptions *SanitizeOptions + registryShardCount uint + MetricsOption InternalMetricOption } // NewRootScope creates a new root Scope with a set of options and @@ -173,7 +183,7 @@ func newRootScope(opts ScopeOptions, interval time.Duration) *scope { s.tags = s.copyAndSanitizeMap(opts.Tags) // Register the root scope - s.registry = newScopeRegistryWithShardCount(s, opts.registryShardCount, opts.skipInternalMetrics) + s.registry = newScopeRegistryWithShardCount(s, opts.registryShardCount, opts.MetricsOption) if interval > 0 { s.wg.Add(1) diff --git a/scope_registry.go b/scope_registry.go index 4d5e6b38..15ad280e 100644 --- a/scope_registry.go +++ b/scope_registry.go @@ -1,4 +1,4 @@ -// Copyright (c) 2022 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -35,9 +35,9 @@ var ( // Metrics related. internalTags = map[string]string{"version": Version} - counterCardinalityName = "tally.internal.counter-cardinality" - gaugeCardinalityName = "tally.internal.gauge-cardinality" - histogramCardinalityName = "tally.internal.histogram-cardinality" + counterCardinalityName = "tally_internal_counter_cardinality" + gaugeCardinalityName = "tally_internal_gauge_cardinality" + histogramCardinalityName = "tally_internal_histogram_cardinality" ) type scopeRegistry struct { @@ -45,8 +45,11 @@ type scopeRegistry struct { root *scope // We need a subscope per GOPROC so that we can take advantage of all the cpu available to the application. subscopes []*scopeBucket - // Toggles internal metrics reporting. - skipInternalMetrics bool + // Internal metrics related. + internalMetricsOption InternalMetricOption + sanitizedCounterCardinalityName string + sanitizedGaugeCardinalityName string + sanitizedHistogramCardinalityName string } type scopeBucket struct { @@ -54,16 +57,23 @@ type scopeBucket struct { s map[string]*scope } -func newScopeRegistryWithShardCount(root *scope, shardCount uint, skipInternalMetrics bool) *scopeRegistry { +func newScopeRegistryWithShardCount( + root *scope, + shardCount uint, + internalMetricsOption InternalMetricOption, +) *scopeRegistry { if shardCount == 0 { shardCount = uint(runtime.GOMAXPROCS(-1)) } r := &scopeRegistry{ - root: root, - subscopes: make([]*scopeBucket, shardCount), - seed: maphash.MakeSeed(), - skipInternalMetrics: skipInternalMetrics, + root: root, + subscopes: make([]*scopeBucket, shardCount), + seed: maphash.MakeSeed(), + internalMetricsOption: internalMetricsOption, + sanitizedCounterCardinalityName: root.sanitizer.Name(counterCardinalityName), + sanitizedGaugeCardinalityName: root.sanitizer.Name(gaugeCardinalityName), + sanitizedHistogramCardinalityName: root.sanitizer.Name(histogramCardinalityName), } for i := uint(0); i < shardCount; i++ { r.subscopes[i] = &scopeBucket{ @@ -228,24 +238,26 @@ func (r *scopeRegistry) removeWithRLock(subscopeBucket *scopeBucket, key string) // Records internal Metrics' cardinalities. func (r *scopeRegistry) reportInternalMetrics() { - if r.skipInternalMetrics { + if r.internalMetricsOption != SendInternalMetrics { return } counters, gauges, histograms := atomic.Int64{}, atomic.Int64{}, atomic.Int64{} rootCounters, rootGauges, rootHistograms := atomic.Int64{}, atomic.Int64{}, atomic.Int64{} - r.ForEachScope(func(ss *scope) { - counterSliceLen, gaugeSliceLen, histogramSliceLen := int64(len(ss.countersSlice)), int64(len(ss.gaugesSlice)), int64(len(ss.histogramsSlice)) - if ss.root { // Root scope is referenced across all buckets. - rootCounters.Store(counterSliceLen) - rootGauges.Store(gaugeSliceLen) - rootHistograms.Store(histogramSliceLen) - return - } - counters.Add(counterSliceLen) - gauges.Add(gaugeSliceLen) - histograms.Add(histogramSliceLen) - }) + r.ForEachScope( + func(ss *scope) { + counterSliceLen, gaugeSliceLen, histogramSliceLen := int64(len(ss.countersSlice)), int64(len(ss.gaugesSlice)), int64(len(ss.histogramsSlice)) + if ss.root { // Root scope is referenced across all buckets. + rootCounters.Store(counterSliceLen) + rootGauges.Store(gaugeSliceLen) + rootHistograms.Store(histogramSliceLen) + return + } + counters.Add(counterSliceLen) + gauges.Add(gaugeSliceLen) + histograms.Add(histogramSliceLen) + }, + ) counters.Add(rootCounters.Load()) gauges.Add(rootGauges.Load()) @@ -253,15 +265,15 @@ func (r *scopeRegistry) reportInternalMetrics() { log.Printf("counters: %v, gauges: %v, histograms: %v\n", counters.Load(), gauges.Load(), histograms.Load()) if r.root.reporter != nil { - r.root.reporter.ReportCounter(counterCardinalityName, internalTags, counters.Load()) - r.root.reporter.ReportCounter(gaugeCardinalityName, internalTags, gauges.Load()) - r.root.reporter.ReportCounter(histogramCardinalityName, internalTags, histograms.Load()) + r.root.reporter.ReportCounter(r.sanitizedCounterCardinalityName, internalTags, counters.Load()) + r.root.reporter.ReportCounter(r.sanitizedGaugeCardinalityName, internalTags, gauges.Load()) + r.root.reporter.ReportCounter(r.sanitizedHistogramCardinalityName, internalTags, histograms.Load()) } if r.root.cachedReporter != nil { - numCounters := r.root.cachedReporter.AllocateCounter(counterCardinalityName, internalTags) - numGauges := r.root.cachedReporter.AllocateCounter(gaugeCardinalityName, internalTags) - numHistograms := r.root.cachedReporter.AllocateCounter(histogramCardinalityName, internalTags) + numCounters := r.root.cachedReporter.AllocateCounter(r.sanitizedCounterCardinalityName, internalTags) + numGauges := r.root.cachedReporter.AllocateCounter(r.sanitizedGaugeCardinalityName, internalTags) + numHistograms := r.root.cachedReporter.AllocateCounter(r.sanitizedHistogramCardinalityName, internalTags) numCounters.ReportCount(counters.Load()) numGauges.ReportCount(gauges.Load()) numHistograms.ReportCount(histograms.Load()) diff --git a/scope_registry_test.go b/scope_registry_test.go index c669a422..c7b27e11 100644 --- a/scope_registry_test.go +++ b/scope_registry_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2022 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -55,7 +55,7 @@ func TestVerifyCachedTaggedScopesAlloc(t *testing.T) { func TestNewTestStatsReporterOneScope(t *testing.T) { r := newTestStatsReporter() - root, closer := NewRootScope(ScopeOptions{Reporter: r, skipInternalMetrics: false}, 0) + root, closer := NewRootScope(ScopeOptions{Reporter: r, MetricsOption: SendInternalMetrics}, 0) s := root.(*scope) numFakeCounters := 3 @@ -101,7 +101,7 @@ func TestNewTestStatsReporterOneScope(t *testing.T) { func TestNewTestStatsReporterManyScopes(t *testing.T) { r := newTestStatsReporter() - root, closer := NewRootScope(ScopeOptions{Reporter: r, skipInternalMetrics: false}, 0) + root, closer := NewRootScope(ScopeOptions{Reporter: r, MetricsOption: SendInternalMetrics}, 0) wantCounters, wantGauges, wantHistograms := int64(3), int64(2), int64(1) s := root.(*scope) diff --git a/scope_test.go b/scope_test.go index 0c7b0330..8bd24616 100644 --- a/scope_test.go +++ b/scope_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2022 Uber Technologies, Inc. +// Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -288,8 +288,10 @@ type testStatsReporterCachedHistogramValueBucket struct { } func (b testStatsReporterCachedHistogramValueBucket) ReportSamples(v int64) { - b.histogram.r.ReportHistogramValueSamples(b.histogram.name, b.histogram.tags, - b.histogram.buckets, b.bucketLowerBound, b.bucketUpperBound, v) + b.histogram.r.ReportHistogramValueSamples( + b.histogram.name, b.histogram.tags, + b.histogram.buckets, b.bucketLowerBound, b.bucketUpperBound, v, + ) } type testStatsReporterCachedHistogramDurationBucket struct { @@ -299,8 +301,10 @@ type testStatsReporterCachedHistogramDurationBucket struct { } func (b testStatsReporterCachedHistogramDurationBucket) ReportSamples(v int64) { - b.histogram.r.ReportHistogramDurationSamples(b.histogram.name, b.histogram.tags, - b.histogram.buckets, b.bucketLowerBound, b.bucketUpperBound, v) + b.histogram.r.ReportHistogramDurationSamples( + b.histogram.name, b.histogram.tags, + b.histogram.buckets, b.bucketLowerBound, b.bucketUpperBound, v, + ) } func (r *testStatsReporter) ReportHistogramValueSamples( @@ -351,7 +355,7 @@ func (r *testStatsReporter) Flush() { func TestWriteTimerImmediately(t *testing.T) { r := newTestStatsReporter() - s, closer := NewRootScope(ScopeOptions{Reporter: r, skipInternalMetrics: true}, 0) + s, closer := NewRootScope(ScopeOptions{Reporter: r, MetricsOption: OmitInternalMetrics}, 0) defer closer.Close() r.tg.Add(1) s.Timer("ticky").Record(time.Millisecond * 175) @@ -360,7 +364,7 @@ func TestWriteTimerImmediately(t *testing.T) { func TestWriteTimerClosureImmediately(t *testing.T) { r := newTestStatsReporter() - s, closer := NewRootScope(ScopeOptions{Reporter: r, skipInternalMetrics: true}, 0) + s, closer := NewRootScope(ScopeOptions{Reporter: r, MetricsOption: OmitInternalMetrics}, 0) defer closer.Close() r.tg.Add(1) tm := s.Timer("ticky") @@ -370,7 +374,7 @@ func TestWriteTimerClosureImmediately(t *testing.T) { func TestWriteReportLoop(t *testing.T) { r := newTestStatsReporter() - s, closer := NewRootScope(ScopeOptions{Reporter: r, skipInternalMetrics: true}, 10) + s, closer := NewRootScope(ScopeOptions{Reporter: r, MetricsOption: OmitInternalMetrics}, 10) defer closer.Close() r.cg.Add(1) @@ -388,7 +392,7 @@ func TestWriteReportLoop(t *testing.T) { func TestCachedReportLoop(t *testing.T) { r := newTestStatsReporter() - s, closer := NewRootScope(ScopeOptions{CachedReporter: r, skipInternalMetrics: true}, 10) + s, closer := NewRootScope(ScopeOptions{CachedReporter: r, MetricsOption: OmitInternalMetrics}, 10) defer closer.Close() r.cg.Add(1) @@ -406,9 +410,9 @@ func TestCachedReportLoop(t *testing.T) { func testReportLoopFlushOnce(t *testing.T, cached bool) { r := newTestStatsReporter() - scopeOpts := ScopeOptions{CachedReporter: r, skipInternalMetrics: true} + scopeOpts := ScopeOptions{CachedReporter: r, MetricsOption: OmitInternalMetrics} if !cached { - scopeOpts = ScopeOptions{Reporter: r, skipInternalMetrics: true} + scopeOpts = ScopeOptions{Reporter: r, MetricsOption: OmitInternalMetrics} } s, closer := NewRootScope(scopeOpts, 10*time.Minute) @@ -446,7 +450,7 @@ func TestReporterFlushOnce(t *testing.T) { func TestWriteOnce(t *testing.T) { r := newTestStatsReporter() - root, closer := NewRootScope(ScopeOptions{Reporter: r, skipInternalMetrics: true}, 0) + root, closer := NewRootScope(ScopeOptions{Reporter: r, MetricsOption: OmitInternalMetrics}, 0) defer closer.Close() s := root.(*scope) @@ -517,10 +521,10 @@ func TestHistogramSharedBucketMetrics(t *testing.T) { var ( r = newTestStatsReporter() scope = newRootScope(ScopeOptions{ - Prefix: "", - Tags: nil, - CachedReporter: r, - skipInternalMetrics: true, + Prefix: "", + Tags: nil, + CachedReporter: r, + MetricsOption: OmitInternalMetrics, }, 0) builder = func(s Scope) func(map[string]string) { buckets := MustMakeLinearValueBuckets(10, 10, 3) @@ -543,9 +547,11 @@ func TestHistogramSharedBucketMetrics(t *testing.T) { defer wg.Done() val := strconv.Itoa(i % 4) - record(map[string]string{ - "key": val, - }) + record( + map[string]string{ + "key": val, + }, + ) time.Sleep(time.Duration(rand.Float64() * float64(time.Second))) }() @@ -589,10 +595,10 @@ func TestConcurrentUpdates(t *testing.T) { counterIncrs = 5000 rs = newRootScope( ScopeOptions{ - Prefix: "", - Tags: nil, - CachedReporter: r, - skipInternalMetrics: true, + Prefix: "", + Tags: nil, + CachedReporter: r, + MetricsOption: OmitInternalMetrics, }, 0, ) scopes = []Scope{rs} @@ -638,9 +644,9 @@ func TestCounterSanitized(t *testing.T) { r := newTestStatsReporter() root, closer := NewRootScope(ScopeOptions{ - Reporter: r, - SanitizeOptions: &alphanumericSanitizerOpts, - skipInternalMetrics: true, + Reporter: r, + SanitizeOptions: &alphanumericSanitizerOpts, + MetricsOption: OmitInternalMetrics, }, 0) defer closer.Close() @@ -696,7 +702,7 @@ func TestCounterSanitized(t *testing.T) { func TestCachedReporter(t *testing.T) { r := newTestStatsReporter() - root, closer := NewRootScope(ScopeOptions{CachedReporter: r, skipInternalMetrics: true}, 0) + root, closer := NewRootScope(ScopeOptions{CachedReporter: r, MetricsOption: OmitInternalMetrics}, 0) defer closer.Close() s := root.(*scope) @@ -733,7 +739,7 @@ func TestCachedReporter(t *testing.T) { func TestRootScopeWithoutPrefix(t *testing.T) { r := newTestStatsReporter() - root, closer := NewRootScope(ScopeOptions{Reporter: r, skipInternalMetrics: true}, 0) + root, closer := NewRootScope(ScopeOptions{Reporter: r, MetricsOption: OmitInternalMetrics}, 0) defer closer.Close() s := root.(*scope) @@ -767,7 +773,9 @@ func TestRootScopeWithoutPrefix(t *testing.T) { func TestRootScopeWithPrefix(t *testing.T) { r := newTestStatsReporter() - root, closer := NewRootScope(ScopeOptions{Prefix: "foo", Reporter: r, skipInternalMetrics: true}, 0) + root, closer := NewRootScope( + ScopeOptions{Prefix: "foo", Reporter: r, MetricsOption: OmitInternalMetrics}, 0, + ) defer closer.Close() s := root.(*scope) @@ -801,7 +809,11 @@ func TestRootScopeWithPrefix(t *testing.T) { func TestRootScopeWithDifferentSeparator(t *testing.T) { r := newTestStatsReporter() - root, closer := NewRootScope(ScopeOptions{Prefix: "foo", Separator: "_", Reporter: r, skipInternalMetrics: true}, 0) + root, closer := NewRootScope( + ScopeOptions{ + Prefix: "foo", Separator: "_", Reporter: r, MetricsOption: OmitInternalMetrics, + }, 0, + ) defer closer.Close() s := root.(*scope) @@ -835,7 +847,9 @@ func TestRootScopeWithDifferentSeparator(t *testing.T) { func TestSubScope(t *testing.T) { r := newTestStatsReporter() - root, closer := NewRootScope(ScopeOptions{Prefix: "foo", Reporter: r, skipInternalMetrics: true}, 0) + root, closer := NewRootScope( + ScopeOptions{Prefix: "foo", Reporter: r, MetricsOption: OmitInternalMetrics}, 0, + ) defer closer.Close() tags := map[string]string{"foo": "bar"} @@ -877,7 +891,7 @@ func TestSubScope(t *testing.T) { func TestSubScopeClose(t *testing.T) { r := newTestStatsReporter() - rs, closer := NewRootScope(ScopeOptions{Prefix: "foo", Reporter: r, skipInternalMetrics: true}, 0) + rs, closer := NewRootScope(ScopeOptions{Prefix: "foo", Reporter: r, MetricsOption: OmitInternalMetrics}, 0) // defer closer.Close() _ = closer @@ -968,7 +982,11 @@ func TestTaggedSubScope(t *testing.T) { r := newTestStatsReporter() ts := map[string]string{"env": "test"} - root, closer := NewRootScope(ScopeOptions{Prefix: "foo", Tags: ts, Reporter: r, skipInternalMetrics: true}, 0) + root, closer := NewRootScope( + ScopeOptions{ + Prefix: "foo", Tags: ts, Reporter: r, MetricsOption: OmitInternalMetrics, + }, 0, + ) defer closer.Close() s := root.(*scope) @@ -1000,19 +1018,23 @@ func TestTaggedSubScope(t *testing.T) { assert.EqualValues(t, ts, counters["foo.beep"].tags) assert.EqualValues(t, 1, counters["foo.boop"].val) - assert.EqualValues(t, map[string]string{ - "env": "test", - "service": "test", - }, counters["foo.boop"].tags) + assert.EqualValues( + t, map[string]string{ + "env": "test", + "service": "test", + }, counters["foo.boop"].tags, + ) assert.EqualValues(t, 1, histograms["foo.baz"].valueSamples[50.0]) assert.EqualValues(t, ts, histograms["foo.baz"].tags) assert.EqualValues(t, 1, histograms["foo.bar"].valueSamples[50.0]) - assert.EqualValues(t, map[string]string{ - "env": "test", - "service": "test", - }, histograms["foo.bar"].tags) + assert.EqualValues( + t, map[string]string{ + "env": "test", + "service": "test", + }, histograms["foo.bar"].tags, + ) } func TestTaggedSanitizedSubScope(t *testing.T) { @@ -1020,11 +1042,11 @@ func TestTaggedSanitizedSubScope(t *testing.T) { ts := map[string]string{"env": "test:env"} root, closer := NewRootScope(ScopeOptions{ - Prefix: "foo", - Tags: ts, - Reporter: r, - SanitizeOptions: &alphanumericSanitizerOpts, - skipInternalMetrics: true, + Prefix: "foo", + Tags: ts, + Reporter: r, + SanitizeOptions: &alphanumericSanitizerOpts, + MetricsOption: OmitInternalMetrics, }, 0) defer closer.Close() s := root.(*scope) @@ -1040,10 +1062,12 @@ func TestTaggedSanitizedSubScope(t *testing.T) { counters := r.getCounters() assert.EqualValues(t, 1, counters["foo_beep"].val) - assert.EqualValues(t, map[string]string{ - "env": "test_env", - "service": "test_service", - }, counters["foo_beep"].tags) + assert.EqualValues( + t, map[string]string{ + "env": "test_env", + "service": "test_service", + }, counters["foo_beep"].tags, + ) } func TestTaggedExistingReturnsSameScope(t *testing.T) { @@ -1053,7 +1077,11 @@ func TestTaggedExistingReturnsSameScope(t *testing.T) { nil, {"env": "test"}, } { - root, closer := NewRootScope(ScopeOptions{Prefix: "foo", Tags: initialTags, Reporter: r, skipInternalMetrics: true}, 0) + root, closer := NewRootScope( + ScopeOptions{ + Prefix: "foo", Tags: initialTags, Reporter: r, MetricsOption: OmitInternalMetrics, + }, 0, + ) defer closer.Close() rootScope := root.(*scope) @@ -1085,52 +1113,62 @@ func TestSnapshot(t *testing.T) { // Should be able to call Snapshot any number of times and get same result. for i := 0; i < 3; i++ { - t.Run(fmt.Sprintf("attempt %d", i), func(t *testing.T) { - snap := s.Snapshot() - counters, gauges, timers, histograms := - snap.Counters(), snap.Gauges(), snap.Timers(), snap.Histograms() - - assert.EqualValues(t, 1, counters["foo.beep+env=test"].Value()) - assert.EqualValues(t, commonTags, counters["foo.beep+env=test"].Tags()) - - assert.EqualValues(t, 2, gauges["foo.bzzt+env=test"].Value()) - assert.EqualValues(t, commonTags, gauges["foo.bzzt+env=test"].Tags()) - - assert.EqualValues(t, []time.Duration{ - 1 * time.Second, - 2 * time.Second, - }, timers["foo.brrr+env=test"].Values()) - assert.EqualValues(t, commonTags, timers["foo.brrr+env=test"].Tags()) - - assert.EqualValues(t, map[float64]int64{ - 0: 0, - 2: 1, - 4: 0, - math.MaxFloat64: 1, - }, histograms["foo.fizz+env=test"].Values()) - assert.EqualValues(t, map[time.Duration]int64(nil), histograms["foo.fizz+env=test"].Durations()) - assert.EqualValues(t, commonTags, histograms["foo.fizz+env=test"].Tags()) - - assert.EqualValues(t, map[float64]int64(nil), histograms["foo.buzz+env=test"].Values()) - assert.EqualValues(t, map[time.Duration]int64{ - time.Second * 2: 1, - time.Second * 4: 0, - math.MaxInt64: 0, - }, histograms["foo.buzz+env=test"].Durations()) - assert.EqualValues(t, commonTags, histograms["foo.buzz+env=test"].Tags()) - - assert.EqualValues(t, 1, counters["foo.boop+env=test,service=test"].Value()) - assert.EqualValues(t, map[string]string{ - "env": "test", - "service": "test", - }, counters["foo.boop+env=test,service=test"].Tags()) - }) + t.Run( + fmt.Sprintf("attempt %d", i), func(t *testing.T) { + snap := s.Snapshot() + counters, gauges, timers, histograms := + snap.Counters(), snap.Gauges(), snap.Timers(), snap.Histograms() + + assert.EqualValues(t, 1, counters["foo.beep+env=test"].Value()) + assert.EqualValues(t, commonTags, counters["foo.beep+env=test"].Tags()) + + assert.EqualValues(t, 2, gauges["foo.bzzt+env=test"].Value()) + assert.EqualValues(t, commonTags, gauges["foo.bzzt+env=test"].Tags()) + + assert.EqualValues( + t, []time.Duration{ + 1 * time.Second, + 2 * time.Second, + }, timers["foo.brrr+env=test"].Values(), + ) + assert.EqualValues(t, commonTags, timers["foo.brrr+env=test"].Tags()) + + assert.EqualValues( + t, map[float64]int64{ + 0: 0, + 2: 1, + 4: 0, + math.MaxFloat64: 1, + }, histograms["foo.fizz+env=test"].Values(), + ) + assert.EqualValues(t, map[time.Duration]int64(nil), histograms["foo.fizz+env=test"].Durations()) + assert.EqualValues(t, commonTags, histograms["foo.fizz+env=test"].Tags()) + + assert.EqualValues(t, map[float64]int64(nil), histograms["foo.buzz+env=test"].Values()) + assert.EqualValues( + t, map[time.Duration]int64{ + time.Second * 2: 1, + time.Second * 4: 0, + math.MaxInt64: 0, + }, histograms["foo.buzz+env=test"].Durations(), + ) + assert.EqualValues(t, commonTags, histograms["foo.buzz+env=test"].Tags()) + + assert.EqualValues(t, 1, counters["foo.boop+env=test,service=test"].Value()) + assert.EqualValues( + t, map[string]string{ + "env": "test", + "service": "test", + }, counters["foo.boop+env=test,service=test"].Tags(), + ) + }, + ) } } func TestCapabilities(t *testing.T) { r := newTestStatsReporter() - s, closer := NewRootScope(ScopeOptions{Reporter: r, skipInternalMetrics: true}, 0) + s, closer := NewRootScope(ScopeOptions{Reporter: r, MetricsOption: OmitInternalMetrics}, 0) defer closer.Close() assert.True(t, s.Capabilities().Reporting()) assert.False(t, s.Capabilities().Tagging()) @@ -1158,8 +1196,8 @@ func TestScopeDefaultBuckets(t *testing.T) { 90 * time.Millisecond, 120 * time.Millisecond, }, - Reporter: r, - skipInternalMetrics: true, + Reporter: r, + MetricsOption: OmitInternalMetrics, }, 0) defer closer.Close() @@ -1190,7 +1228,7 @@ func newTestMets(scope Scope) testMets { func TestReturnByValue(t *testing.T) { r := newTestStatsReporter() - root, closer := NewRootScope(ScopeOptions{Reporter: r, skipInternalMetrics: true}, 0) + root, closer := NewRootScope(ScopeOptions{Reporter: r, MetricsOption: OmitInternalMetrics}, 0) defer closer.Close() s := root.(*scope) @@ -1207,7 +1245,7 @@ func TestReturnByValue(t *testing.T) { func TestScopeAvoidReportLoopRunOnClose(t *testing.T) { r := newTestStatsReporter() - root, closer := NewRootScope(ScopeOptions{Reporter: r, skipInternalMetrics: true}, 0) + root, closer := NewRootScope(ScopeOptions{Reporter: r, MetricsOption: OmitInternalMetrics}, 0) s := root.(*scope) s.reportLoopRun() @@ -1222,7 +1260,7 @@ func TestScopeAvoidReportLoopRunOnClose(t *testing.T) { func TestScopeFlushOnClose(t *testing.T) { r := newTestStatsReporter() - root, closer := NewRootScope(ScopeOptions{Reporter: r, skipInternalMetrics: true}, time.Hour) + root, closer := NewRootScope(ScopeOptions{Reporter: r, MetricsOption: OmitInternalMetrics}, time.Hour) r.cg.Add(1) root.Counter("foo").Inc(1)