Skip to content

Commit 577999a

Browse files
committed
update internal metrics impl
1 parent 8686c7d commit 577999a

9 files changed

+189
-118
lines changed

m3/example/m3_main.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2021 Uber Technologies, Inc.
1+
// Copyright (c) 2024 Uber Technologies, Inc.
22
//
33
// Permission is hereby granted, free of charge, to any person obtaining a copy
44
// of this software and associated documentation files (the "Software"), to deal
@@ -87,7 +87,8 @@ func main() {
8787
}
8888

8989
scope, closer := tally.NewRootScope(tally.ScopeOptions{
90-
CachedReporter: r,
90+
CachedReporter: r,
91+
CardinalityMetricsTags: cfg.M3.InternalTags,
9192
}, 1*time.Second)
9293

9394
defer closer.Close()

m3/reporter.go

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2021 Uber Technologies, Inc.
1+
// Copyright (c) 2024 Uber Technologies, Inc.
22
//
33
// Permission is hereby granted, free of charge, to any person obtaining a copy
44
// of this software and associated documentation files (the "Software"), to deal
@@ -66,8 +66,6 @@ const (
6666
DefaultHistogramBucketIDName = "bucketid"
6767
// DefaultHistogramBucketName is the default histogram bucket name tag name
6868
DefaultHistogramBucketName = "bucket"
69-
// DefaultTagRedactValue is the default tag value to use when redacting
70-
DefaultTagRedactValue = "global"
7169
// DefaultHistogramBucketTagPrecision is the default
7270
// precision to use when formatting the metric tag
7371
// with the histogram bucket bound values.
@@ -290,8 +288,8 @@ func NewReporter(opts Options) (Reporter, error) {
290288

291289
internalTags := map[string]string{
292290
"version": tally.Version,
293-
"host": DefaultTagRedactValue,
294-
"instance": DefaultTagRedactValue,
291+
"host": tally.DefaultTagRedactValue,
292+
"instance": tally.DefaultTagRedactValue,
295293
}
296294

297295
for k, v := range opts.InternalTags {

m3/reporter_integration_test.go

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ func main() {
5555
5656
scope, closer := tally.NewRootScope(tally.ScopeOptions{
5757
CachedReporter: r,
58+
CardinalityMetricsOption: tally.OmitCardinalityMetrics,
5859
}, 5 * time.Second)
5960
defer closer.Close()
6061

m3/reporter_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ var (
5757
var protocols = []Protocol{Compact, Binary}
5858

5959
const internalMetrics = 5 // Additional metrics the reporter sends in a batch - use this, not a magic number.
60-
const cardinalityMetrics = 3 // Additional metrics emitted by the scope registry.
60+
const cardinalityMetrics = 4 // Additional metrics emitted by the scope registry.
6161

6262
// TestReporter tests the reporter works as expected with both compact and binary protocols
6363
func TestReporter(t *testing.T) {
@@ -601,8 +601,8 @@ func TestReporterCommmonTagsInternal(t *testing.T) {
601601
}
602602

603603
// The following tags should be redacted.
604-
require.True(t, tagEquals(metric.Tags, "host", DefaultTagRedactValue))
605-
require.True(t, tagEquals(metric.Tags, "instance", DefaultTagRedactValue))
604+
require.True(t, tagEquals(metric.Tags, "host", tally.DefaultTagRedactValue))
605+
require.True(t, tagEquals(metric.Tags, "instance", tally.DefaultTagRedactValue))
606606
} else {
607607
require.Equal(t, "testCounter1", metric.Name)
608608
require.False(t, tagIncluded(metric.Tags, "internal1"))

m3/scope_test.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,10 @@ func newTestReporterScope(
5050
require.NoError(t, err)
5151

5252
scope, closer := tally.NewRootScope(tally.ScopeOptions{
53-
Prefix: scopePrefix,
54-
Tags: scopeTags,
55-
CachedReporter: r,
56-
MetricsOption: tally.SendInternalMetrics,
53+
Prefix: scopePrefix,
54+
Tags: scopeTags,
55+
CachedReporter: r,
56+
CardinalityMetricsOption: tally.SendCardinalityMetrics,
5757
}, shortInterval)
5858

5959
return r, scope, func() {

scope.go

+20-19
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2023 Uber Technologies, Inc.
1+
// Copyright (c) 2024 Uber Technologies, Inc.
22
//
33
// Permission is hereby granted, free of charge, to any person obtaining a copy
44
// of this software and associated documentation files (the "Software"), to deal
@@ -28,16 +28,16 @@ import (
2828
"go.uber.org/atomic"
2929
)
3030

31-
// InternalMetricOption is used to configure internal metrics.
32-
type InternalMetricOption int
31+
// CardinalityMetricsOption is used to configure internal metrics.
32+
type CardinalityMetricsOption int
3333

3434
const (
35-
// Unset is the "no-op" config, which turns off internal metrics.
36-
Unset InternalMetricOption = iota
37-
// SendInternalMetrics turns on internal metrics submission.
38-
SendInternalMetrics
39-
// OmitInternalMetrics turns off internal metrics submission.
40-
OmitInternalMetrics
35+
// Unset is the "no-op" config, cardinality is sent by default.
36+
Unset CardinalityMetricsOption = iota
37+
// SendCardinalityMetrics turns on internal metrics submission.
38+
SendCardinalityMetrics
39+
// OmitCardinalityMetrics turns off internal metrics submission.
40+
OmitCardinalityMetrics
4141

4242
_defaultInitialSliceSize = 16
4343
_defaultReportingInterval = 2 * time.Second
@@ -106,15 +106,16 @@ type scope struct {
106106

107107
// ScopeOptions is a set of options to construct a scope.
108108
type ScopeOptions struct {
109-
Tags map[string]string
110-
Prefix string
111-
Reporter StatsReporter
112-
CachedReporter CachedStatsReporter
113-
Separator string
114-
DefaultBuckets Buckets
115-
SanitizeOptions *SanitizeOptions
116-
registryShardCount uint
117-
MetricsOption InternalMetricOption
109+
Tags map[string]string
110+
Prefix string
111+
Reporter StatsReporter
112+
CachedReporter CachedStatsReporter
113+
Separator string
114+
DefaultBuckets Buckets
115+
SanitizeOptions *SanitizeOptions
116+
registryShardCount uint
117+
CardinalityMetricsOption CardinalityMetricsOption
118+
CardinalityMetricsTags map[string]string
118119
}
119120

120121
// NewRootScope creates a new root Scope with a set of options and
@@ -190,7 +191,7 @@ func newRootScope(opts ScopeOptions, interval time.Duration) *scope {
190191
s.tags = s.copyAndSanitizeMap(opts.Tags)
191192

192193
// Register the root scope
193-
s.registry = newScopeRegistryWithShardCount(s, opts.registryShardCount, opts.MetricsOption)
194+
s.registry = newScopeRegistryWithShardCount(s, opts.registryShardCount, opts.CardinalityMetricsOption, opts.CardinalityMetricsTags)
194195

195196
if interval > 0 {
196197
s.wg.Add(1)

scope_registry.go

+49-20
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2023 Uber Technologies, Inc.
1+
// Copyright (c) 2024 Uber Technologies, Inc.
22
//
33
// Permission is hereby granted, free of charge, to any person obtaining a copy
44
// of this software and associated documentation files (the "Software"), to deal
@@ -33,10 +33,15 @@ var (
3333
scopeRegistryKey = keyForPrefixedStringMaps
3434

3535
// Metrics related.
36-
internalTags = map[string]string{"version": Version}
37-
counterCardinalityName = "tally_internal_counter_cardinality"
38-
gaugeCardinalityName = "tally_internal_gauge_cardinality"
39-
histogramCardinalityName = "tally_internal_histogram_cardinality"
36+
counterCardinalityName = "tally.internal.counter_cardinality"
37+
gaugeCardinalityName = "tally.internal.gauge_cardinality"
38+
histogramCardinalityName = "tally.internal.histogram_cardinality"
39+
scopeCardinalityName = "tally.internal.scope_cardinality"
40+
)
41+
42+
const (
43+
// DefaultTagRedactValue is the default tag value to use when redacting
44+
DefaultTagRedactValue = "global"
4045
)
4146

4247
type scopeRegistry struct {
@@ -45,10 +50,16 @@ type scopeRegistry struct {
4550
// We need a subscope per GOPROC so that we can take advantage of all the cpu available to the application.
4651
subscopes []*scopeBucket
4752
// Internal metrics related.
48-
internalMetricsOption InternalMetricOption
53+
cardinalityMetricsOption CardinalityMetricsOption
54+
cardinalityMetricsTags map[string]string
4955
sanitizedCounterCardinalityName string
5056
sanitizedGaugeCardinalityName string
5157
sanitizedHistogramCardinalityName string
58+
sanitizedScopeCardinalityName string
59+
cachedCounterCardinalityGauge CachedGauge
60+
cachedGaugeCardinalityGauge CachedGauge
61+
cachedHistogramCardinalityGauge CachedGauge
62+
cachedScopeCardinalityGauge CachedGauge
5263
}
5364

5465
type scopeBucket struct {
@@ -59,7 +70,8 @@ type scopeBucket struct {
5970
func newScopeRegistryWithShardCount(
6071
root *scope,
6172
shardCount uint,
62-
internalMetricsOption InternalMetricOption,
73+
cardinalityMetricsOption CardinalityMetricsOption,
74+
cardinalityMetricsTags map[string]string,
6375
) *scopeRegistry {
6476
if shardCount == 0 {
6577
shardCount = uint(runtime.GOMAXPROCS(-1))
@@ -69,17 +81,34 @@ func newScopeRegistryWithShardCount(
6981
root: root,
7082
subscopes: make([]*scopeBucket, shardCount),
7183
seed: maphash.MakeSeed(),
72-
internalMetricsOption: internalMetricsOption,
84+
cardinalityMetricsOption: cardinalityMetricsOption,
7385
sanitizedCounterCardinalityName: root.sanitizer.Name(counterCardinalityName),
7486
sanitizedGaugeCardinalityName: root.sanitizer.Name(gaugeCardinalityName),
7587
sanitizedHistogramCardinalityName: root.sanitizer.Name(histogramCardinalityName),
88+
sanitizedScopeCardinalityName: root.sanitizer.Name(scopeCardinalityName),
89+
cardinalityMetricsTags: map[string]string{
90+
"version": Version,
91+
"host": DefaultTagRedactValue,
92+
"instance": DefaultTagRedactValue,
93+
},
94+
}
95+
96+
for k, v := range cardinalityMetricsTags {
97+
r.cardinalityMetricsTags[root.sanitizer.Key(k)] = root.sanitizer.Value(v)
7698
}
99+
77100
for i := uint(0); i < shardCount; i++ {
78101
r.subscopes[i] = &scopeBucket{
79102
s: make(map[string]*scope),
80103
}
81104
r.subscopes[i].s[scopeRegistryKey(root.prefix, root.tags)] = root
82105
}
106+
if r.root.cachedReporter != nil {
107+
r.cachedCounterCardinalityGauge = r.root.cachedReporter.AllocateGauge(r.sanitizedCounterCardinalityName, r.cardinalityMetricsTags)
108+
r.cachedGaugeCardinalityGauge = r.root.cachedReporter.AllocateGauge(r.sanitizedGaugeCardinalityName, r.cardinalityMetricsTags)
109+
r.cachedHistogramCardinalityGauge = r.root.cachedReporter.AllocateGauge(r.sanitizedHistogramCardinalityName, r.cardinalityMetricsTags)
110+
r.cachedScopeCardinalityGauge = r.root.cachedReporter.AllocateGauge(r.sanitizedScopeCardinalityName, r.cardinalityMetricsTags)
111+
}
83112
return r
84113
}
85114

@@ -237,12 +266,13 @@ func (r *scopeRegistry) removeWithRLock(subscopeBucket *scopeBucket, key string)
237266

238267
// Records internal Metrics' cardinalities.
239268
func (r *scopeRegistry) reportInternalMetrics() {
240-
if r.internalMetricsOption != SendInternalMetrics {
269+
if r.cardinalityMetricsOption == OmitCardinalityMetrics {
241270
return
242271
}
243272

244-
counters, gauges, histograms := atomic.Int64{}, atomic.Int64{}, atomic.Int64{}
273+
counters, gauges, histograms, scopes := atomic.Int64{}, atomic.Int64{}, atomic.Int64{}, atomic.Int64{}
245274
rootCounters, rootGauges, rootHistograms := atomic.Int64{}, atomic.Int64{}, atomic.Int64{}
275+
scopes.Inc() // Account for root scope.
246276
r.ForEachScope(
247277
func(ss *scope) {
248278
counterSliceLen, gaugeSliceLen, histogramSliceLen := int64(len(ss.countersSlice)), int64(len(ss.gaugesSlice)), int64(len(ss.histogramsSlice))
@@ -255,25 +285,24 @@ func (r *scopeRegistry) reportInternalMetrics() {
255285
counters.Add(counterSliceLen)
256286
gauges.Add(gaugeSliceLen)
257287
histograms.Add(histogramSliceLen)
288+
scopes.Inc()
258289
},
259290
)
260291

261292
counters.Add(rootCounters.Load())
262293
gauges.Add(rootGauges.Load())
263294
histograms.Add(rootHistograms.Load())
264-
265295
if r.root.reporter != nil {
266-
r.root.reporter.ReportCounter(r.sanitizedCounterCardinalityName, internalTags, counters.Load())
267-
r.root.reporter.ReportCounter(r.sanitizedGaugeCardinalityName, internalTags, gauges.Load())
268-
r.root.reporter.ReportCounter(r.sanitizedHistogramCardinalityName, internalTags, histograms.Load())
296+
r.root.reporter.ReportGauge(r.sanitizedCounterCardinalityName, r.cardinalityMetricsTags, float64(counters.Load()))
297+
r.root.reporter.ReportGauge(r.sanitizedGaugeCardinalityName, r.cardinalityMetricsTags, float64(gauges.Load()))
298+
r.root.reporter.ReportGauge(r.sanitizedHistogramCardinalityName, r.cardinalityMetricsTags, float64(histograms.Load()))
299+
r.root.reporter.ReportGauge(r.sanitizedScopeCardinalityName, r.cardinalityMetricsTags, float64(scopes.Load()))
269300
}
270301

271302
if r.root.cachedReporter != nil {
272-
numCounters := r.root.cachedReporter.AllocateCounter(r.sanitizedCounterCardinalityName, internalTags)
273-
numGauges := r.root.cachedReporter.AllocateCounter(r.sanitizedGaugeCardinalityName, internalTags)
274-
numHistograms := r.root.cachedReporter.AllocateCounter(r.sanitizedHistogramCardinalityName, internalTags)
275-
numCounters.ReportCount(counters.Load())
276-
numGauges.ReportCount(gauges.Load())
277-
numHistograms.ReportCount(histograms.Load())
303+
r.cachedCounterCardinalityGauge.ReportGauge(float64(counters.Load()))
304+
r.cachedGaugeCardinalityGauge.ReportGauge(float64(gauges.Load()))
305+
r.cachedHistogramCardinalityGauge.ReportGauge(float64(histograms.Load()))
306+
r.cachedScopeCardinalityGauge.ReportGauge(float64(scopes.Load()))
278307
}
279308
}

0 commit comments

Comments
 (0)