From 3853e468e7f358d7ba551e661c4cc8f51c74197e Mon Sep 17 00:00:00 2001 From: shaan420 Date: Fri, 6 Oct 2023 07:54:00 -0700 Subject: [PATCH] Prepare v3.5.6 (#232) * Set default reporting interval (#226) * Enforce minimum reporting interval * Add new RootScope constructor with default interval * Test with go >= 1.18 (#228) * add custom tags to internal metrics (#231) * add custom tags to internal metrics * make unit test stricter, update version * update version to v3.5.6 --------- Co-authored-by: Vytenis Darulis --- .travis.yml | 10 +++----- m3/config.go | 5 ++++ m3/config_test.go | 1 + m3/reporter.go | 6 +++++ m3/reporter_test.go | 59 +++++++++++++++++++++++++++++++++++++++++++++ scope.go | 9 ++++++- scope_test.go | 20 +++++++++++++++ version.go | 2 +- 8 files changed, 104 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 990e93bd..c43d4211 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,12 +1,10 @@ language: go sudo: false go: - - 1.14.x - - 1.15.x - - 1.16.x -env: - global: - - GO15VENDOREXPERIMENT=1 + - 1.18.x + - 1.19.x + - 1.20.x + - 1.21.x cache: directories: - vendor diff --git a/m3/config.go b/m3/config.go index cbeb4b6f..ccfb51ce 100644 --- a/m3/config.go +++ b/m3/config.go @@ -49,6 +49,10 @@ type Configuration struct { // HistogramBucketTagPrecision is precision to use when formatting the metric tag // with the histogram bucket bound values. HistogramBucketTagPrecision uint `yaml:"histogramBucketTagPrecision"` + + // CommonTagsInternal are tags that should be added to all internal metrics + // emitted by the reporter. + CommonTagsInternal map[string]string `yaml:"commonTagsInternal"` } // NewReporter creates a new M3 reporter from this configuration. @@ -66,5 +70,6 @@ func (c Configuration) NewReporter() (Reporter, error) { MaxPacketSizeBytes: c.PacketSize, IncludeHost: c.IncludeHost, HistogramBucketTagPrecision: c.HistogramBucketTagPrecision, + InternalTags: c.CommonTagsInternal, }) } diff --git a/m3/config_test.go b/m3/config_test.go index 7266c9e9..1eb7726a 100644 --- a/m3/config_test.go +++ b/m3/config_test.go @@ -43,6 +43,7 @@ func TestConfigSimple(t *testing.T) { assert.True(t, ok) assert.True(t, tagEquals(reporter.commonTags, "service", "my-service")) assert.True(t, tagEquals(reporter.commonTags, "env", "test")) + assert.Equal(t, 0, len(c.CommonTagsInternal)) } func TestConfigMulti(t *testing.T) { diff --git a/m3/reporter.go b/m3/reporter.go index 72d0fd02..6ba69308 100644 --- a/m3/reporter.go +++ b/m3/reporter.go @@ -149,6 +149,7 @@ type Options struct { HistogramBucketIDName string HistogramBucketName string HistogramBucketTagPrecision uint + InternalTags map[string]string } // NewReporter creates a new M3 reporter. @@ -288,6 +289,11 @@ func NewReporter(opts Options) (Reporter, error) { internalTags := map[string]string{ "version": tally.Version, } + + for k, v := range opts.InternalTags { + internalTags[k] = v + } + r.batchSizeHistogram = r.AllocateHistogram("tally.internal.batch-size", internalTags, buckets) r.numBatchesCounter = r.AllocateCounter("tally.internal.num-batches", internalTags) r.numMetricsCounter = r.AllocateCounter("tally.internal.num-metrics", internalTags) diff --git a/m3/reporter_test.go b/m3/reporter_test.go index ea7b4f9f..98c87936 100644 --- a/m3/reporter_test.go +++ b/m3/reporter_test.go @@ -559,6 +559,58 @@ func TestReporterResetTagsAfterReturnToPool(t *testing.T) { require.Equal(t, 0, len(filtered[1].GetTags())) } +func TestReporterCommmonTagsInternal(t *testing.T) { + var wg sync.WaitGroup + server := newFakeM3Server(t, &wg, false, Compact) + go server.Serve() + defer server.Close() + + internalTags := map[string]string{ + "internal1": "test1", + "internal2": "test2", + } + + r, err := NewReporter(Options{ + HostPorts: []string{server.Addr}, + Service: "test-service", + CommonTags: defaultCommonTags, + MaxQueueSize: queueSize, + IncludeHost: true, + MaxPacketSizeBytes: maxPacketSize, + InternalTags: internalTags, + }) + require.NoError(t, err) + defer r.Close() + + c := r.AllocateCounter("testCounter1", nil) + c.ReportCount(1) + wg.Add(internalMetrics + 1) + r.Flush() + wg.Wait() + + numInternalMetricsActual := 0 + metrics := server.Service.getMetrics() + require.Equal(t, internalMetrics+1, len(metrics)) + for _, metric := range metrics { + if strings.HasPrefix(metric.Name, "tally.internal") { + numInternalMetricsActual++ + for k, v := range internalTags { + require.True(t, tagEquals(metric.Tags, k, v)) + } + } else { + require.Equal(t, "testCounter1", metric.Name) + require.False(t, tagIncluded(metric.Tags, "internal1")) + require.False(t, tagIncluded(metric.Tags, "internal2")) + } + // The following tags should not be present as part of the individual metrics + // as they are common tags. + require.False(t, tagIncluded(metric.Tags, "host")) + require.False(t, tagIncluded(metric.Tags, "instance")) + require.False(t, tagIncluded(metric.Tags, "service")) + } + require.Equal(t, internalMetrics, numInternalMetricsActual) +} + func TestReporterHasReportingAndTaggingCapability(t *testing.T) { r, err := NewReporter(Options{ HostPorts: []string{"127.0.0.1:9052"}, @@ -587,6 +639,13 @@ type fakeM3ServerPackets struct { values [][]byte } +// newFakeM3Server creates a new fake M3 server that listens on a random port +// and returns the server. +// The server will wait for the given wait group to be done before returning. +// If countBatches is true, the server will wait consider the wg.Add()s to be +// representing batches and will do a eg.Done() for each encountered batch. +// But if countBatches is false, the server will do the same thing but for individual +// metrics instead of batches. func newFakeM3Server(t *testing.T, wg *sync.WaitGroup, countBatches bool, protocol Protocol) *fakeM3Server { service := newFakeM3Service(wg, countBatches) processor := m3thrift.NewM3Processor(service) diff --git a/scope.go b/scope.go index 0a540758..7a645bfd 100644 --- a/scope.go +++ b/scope.go @@ -39,7 +39,8 @@ const ( // OmitInternalMetrics turns off internal metrics submission. OmitInternalMetrics - _defaultInitialSliceSize = 16 + _defaultInitialSliceSize = 16 + _defaultReportingInterval = 2 * time.Second ) var ( @@ -127,6 +128,12 @@ func NewRootScope(opts ScopeOptions, interval time.Duration) (Scope, io.Closer) return s, s } +// NewRootScopeWithDefaultInterval invokes NewRootScope with the default +// reporting interval of 2s. +func NewRootScopeWithDefaultInterval(opts ScopeOptions) (Scope, io.Closer) { + return NewRootScope(opts, _defaultReportingInterval) +} + // NewTestScope creates a new Scope without a stats reporter with the // given prefix and adds the ability to take snapshots of metrics emitted // to it. diff --git a/scope_test.go b/scope_test.go index 2f67e5f4..0e6820a4 100644 --- a/scope_test.go +++ b/scope_test.go @@ -397,6 +397,26 @@ func TestWriteReportLoop(t *testing.T) { r.WaitAll() } +func TestWriteReportLoopDefaultInterval(t *testing.T) { + r := newTestStatsReporter() + s, closer := NewRootScopeWithDefaultInterval( + ScopeOptions{Reporter: r, MetricsOption: OmitInternalMetrics}, + ) + defer closer.Close() + + r.cg.Add(1) + s.Counter("bar").Inc(1) + r.gg.Add(1) + s.Gauge("zed").Update(1) + r.tg.Add(1) + s.Timer("ticky").Record(time.Millisecond * 175) + r.hg.Add(1) + s.Histogram("baz", MustMakeLinearValueBuckets(0, 10, 10)). + RecordValue(42.42) + + r.WaitAll() +} + func TestCachedReportLoop(t *testing.T) { r := newTestStatsReporter() s, closer := NewRootScope(ScopeOptions{CachedReporter: r, MetricsOption: OmitInternalMetrics}, 10) diff --git a/version.go b/version.go index 7da0e1b6..1320eb7f 100644 --- a/version.go +++ b/version.go @@ -21,4 +21,4 @@ package tally // Version is the current version of the library. -const Version = "3.5.5" +const Version = "3.5.6"