From 438df692ce3529d28cef58ea1bbfd9f0d8071097 Mon Sep 17 00:00:00 2001 From: Mike Dame Date: Tue, 16 Jul 2024 04:42:25 -0400 Subject: [PATCH] [cmd/telemetrygen]: Allow float values for rate (#33984) **Description:** Fixes https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/33982 Switch `--rate` flag in telemetrygen to support Float64 values **Link to tracking Issue:** https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/33982 **Testing:** Added unit tests for float value cases **Documentation:** N/A --------- Co-authored-by: Antoine Toulme Co-authored-by: Alex Boten <223565+codeboten@users.noreply.github.com> --- .chloggen/telemetrygen-float-rate.yaml | 27 +++++++++++++++++++++ cmd/telemetrygen/internal/common/config.go | 4 +-- cmd/telemetrygen/internal/logs/worker.go | 7 +++--- cmd/telemetrygen/internal/metrics/worker.go | 7 +++--- cmd/telemetrygen/internal/traces/worker.go | 12 ++++++--- 5 files changed, 45 insertions(+), 12 deletions(-) create mode 100644 .chloggen/telemetrygen-float-rate.yaml diff --git a/.chloggen/telemetrygen-float-rate.yaml b/.chloggen/telemetrygen-float-rate.yaml new file mode 100644 index 000000000000..ffc27d6549d8 --- /dev/null +++ b/.chloggen/telemetrygen-float-rate.yaml @@ -0,0 +1,27 @@ +# Use this changelog template to create an entry for release notes. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver) +component: telemetrygen + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: "telemetrygen `--rate` flag changed from Int64 to Float64" + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [33984] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: + +# If your change doesn't affect end users or the exported elements of any package, +# you should instead start your pull request title with [chore] or use the "Skip Changelog" label. +# Optional: The change log or logs in which this entry should be included. +# e.g. '[user]' or '[user, api]' +# Include 'user' if the change is relevant to end users. +# Include 'api' if there is a change to a library API. +# Default: '[user]' +change_logs: [] diff --git a/cmd/telemetrygen/internal/common/config.go b/cmd/telemetrygen/internal/common/config.go index cfe9a432e90a..76f7effb4597 100644 --- a/cmd/telemetrygen/internal/common/config.go +++ b/cmd/telemetrygen/internal/common/config.go @@ -50,7 +50,7 @@ func (v *KeyValue) Type() string { type Config struct { WorkerCount int - Rate int64 + Rate float64 TotalDuration time.Duration ReportingInterval time.Duration SkipSettingGRPCLogger bool @@ -115,7 +115,7 @@ func (c *Config) GetTelemetryAttributes() []attribute.KeyValue { // CommonFlags registers common config flags. func (c *Config) CommonFlags(fs *pflag.FlagSet) { fs.IntVar(&c.WorkerCount, "workers", 1, "Number of workers (goroutines) to run") - fs.Int64Var(&c.Rate, "rate", 0, "Approximately how many metrics per second each worker should generate. Zero means no throttling.") + fs.Float64Var(&c.Rate, "rate", 0, "Approximately how many metrics/spans/logs per second each worker should generate. Zero means no throttling.") fs.DurationVar(&c.TotalDuration, "duration", 0, "For how long to run the test") fs.DurationVar(&c.ReportingInterval, "interval", 1*time.Second, "Reporting interval") diff --git a/cmd/telemetrygen/internal/logs/worker.go b/cmd/telemetrygen/internal/logs/worker.go index 118a4784f443..93841d82792c 100644 --- a/cmd/telemetrygen/internal/logs/worker.go +++ b/cmd/telemetrygen/internal/logs/worker.go @@ -77,13 +77,14 @@ func (w worker) simulateLogs(res *resource.Resource, exporter exporter, telemetr lattrs.PutStr(string(attr.Key), telemetryAttributes[i].Value.AsString()) } - if err := exporter.export(logs); err != nil { - w.logger.Fatal("exporter failed", zap.Error(err)) - } if err := limiter.Wait(context.Background()); err != nil { w.logger.Fatal("limiter wait failed, retry", zap.Error(err)) } + if err := exporter.export(logs); err != nil { + w.logger.Fatal("exporter failed", zap.Error(err)) + } + i++ if w.numLogs != 0 && i >= int64(w.numLogs) { break diff --git a/cmd/telemetrygen/internal/metrics/worker.go b/cmd/telemetrygen/internal/metrics/worker.go index da3abf140aa1..17978fb9bdf6 100644 --- a/cmd/telemetrygen/internal/metrics/worker.go +++ b/cmd/telemetrygen/internal/metrics/worker.go @@ -91,13 +91,14 @@ func (w worker) simulateMetrics(res *resource.Resource, exporterFunc func() (sdk ScopeMetrics: []metricdata.ScopeMetrics{{Metrics: metrics}}, } - if err := exporter.Export(context.Background(), &rm); err != nil { - w.logger.Fatal("exporter failed", zap.Error(err)) - } if err := limiter.Wait(context.Background()); err != nil { w.logger.Fatal("limiter wait failed, retry", zap.Error(err)) } + if err := exporter.Export(context.Background(), &rm); err != nil { + w.logger.Fatal("exporter failed", zap.Error(err)) + } + i++ if w.numMetrics != 0 && i >= int64(w.numMetrics) { break diff --git a/cmd/telemetrygen/internal/traces/worker.go b/cmd/telemetrygen/internal/traces/worker.go index cb71e2917e66..c3cc86d747ff 100644 --- a/cmd/telemetrygen/internal/traces/worker.go +++ b/cmd/telemetrygen/internal/traces/worker.go @@ -50,6 +50,10 @@ func (w worker) simulateTraces(telemetryAttributes []attribute.KeyValue) { spanStart := time.Now() spanEnd := spanStart.Add(w.spanDuration) + if err := limiter.Wait(context.Background()); err != nil { + w.logger.Fatal("limiter waited failed, retry", zap.Error(err)) + } + ctx, sp := tracer.Start(context.Background(), "lets-go", trace.WithAttributes( semconv.NetPeerIPKey.String(fakeIP), semconv.PeerServiceKey.String("telemetrygen-server"), @@ -74,6 +78,10 @@ func (w worker) simulateTraces(telemetryAttributes []attribute.KeyValue) { var endTimestamp trace.SpanEventOption for j := 0; j < w.numChildSpans; j++ { + if err := limiter.Wait(context.Background()); err != nil { + w.logger.Fatal("limiter waited failed, retry", zap.Error(err)) + } + _, child := tracer.Start(childCtx, "okey-dokey-"+strconv.Itoa(j), trace.WithAttributes( semconv.NetPeerIPKey.String(fakeIP), semconv.PeerServiceKey.String("telemetrygen-client"), @@ -83,10 +91,6 @@ func (w worker) simulateTraces(telemetryAttributes []attribute.KeyValue) { ) child.SetAttributes(telemetryAttributes...) - if err := limiter.Wait(context.Background()); err != nil { - w.logger.Fatal("limiter waited failed, retry", zap.Error(err)) - } - endTimestamp = trace.WithTimestamp(spanEnd) child.SetStatus(w.statusCode, "") child.End(endTimestamp)