diff --git a/.chloggen/telemetrygen.yaml b/.chloggen/telemetrygen.yaml new file mode 100644 index 000000000000..7f08aef5a9bd --- /dev/null +++ b/.chloggen/telemetrygen.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: cmd/telemetrygen + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Introduce support for generating histograms in telemetrygen + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [36322] + +# (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: [user] diff --git a/cmd/telemetrygen/internal/metrics/metrics_types.go b/cmd/telemetrygen/internal/metrics/metrics_types.go index 84318afc4fab..e07b26720acb 100644 --- a/cmd/telemetrygen/internal/metrics/metrics_types.go +++ b/cmd/telemetrygen/internal/metrics/metrics_types.go @@ -10,8 +10,9 @@ import ( type metricType string const ( - metricTypeGauge = "Gauge" - metricTypeSum = "Sum" + metricTypeGauge = "Gauge" + metricTypeSum = "Sum" + metricTypeHistogram = "Histogram" ) // String is used both by fmt.Print and by Cobra in help text @@ -22,11 +23,11 @@ func (e *metricType) String() string { // Set must have pointer receiver so it doesn't change the value of a copy func (e *metricType) Set(v string) error { switch v { - case "Gauge", "Sum": + case "Gauge", "Sum", "Histogram": *e = metricType(v) return nil default: - return errors.New(`must be one of "Gauge" or "Sum"`) + return errors.New(`must be one of "Gauge", "Sum", "Histogram"`) } } diff --git a/cmd/telemetrygen/internal/metrics/worker.go b/cmd/telemetrygen/internal/metrics/worker.go index 17978fb9bdf6..02a0c7ded490 100644 --- a/cmd/telemetrygen/internal/metrics/worker.go +++ b/cmd/telemetrygen/internal/metrics/worker.go @@ -30,6 +30,52 @@ type worker struct { index int // worker index } +var histogramBucketSamples = []struct { + bucketCounts []uint64 + sum int64 +}{ + { + []uint64{0, 0, 1, 0, 0, 0, 3, 4, 1, 1, 0, 0, 0, 0, 0}, + 3940, + }, + { + []uint64{0, 0, 0, 0, 0, 0, 2, 4, 4, 0, 0, 0, 0, 0, 0}, + 4455, + }, + { + []uint64{0, 0, 0, 0, 0, 0, 1, 4, 3, 2, 0, 0, 0, 0, 0}, + 5337, + }, + { + []uint64{0, 0, 1, 0, 1, 0, 2, 2, 1, 3, 0, 0, 0, 0, 0}, + 4477, + }, + { + []uint64{0, 0, 0, 0, 0, 1, 3, 2, 2, 2, 0, 0, 0, 0, 0}, + 4670, + }, + { + []uint64{0, 0, 0, 1, 1, 0, 1, 1, 1, 5, 0, 0, 0, 0, 0}, + 5670, + }, + { + []uint64{0, 0, 0, 0, 0, 2, 1, 1, 4, 2, 0, 0, 0, 0, 0}, + 5091, + }, + { + []uint64{0, 0, 2, 0, 0, 0, 2, 4, 1, 1, 0, 0, 0, 0, 0}, + 3420, + }, + { + []uint64{0, 0, 0, 0, 0, 0, 1, 3, 2, 4, 0, 0, 0, 0, 0}, + 5917, + }, + { + []uint64{0, 0, 1, 0, 1, 0, 0, 4, 4, 0, 0, 0, 0, 0, 0}, + 3988, + }, +} + func (w worker) simulateMetrics(res *resource.Resource, exporterFunc func() (sdkmetric.Exporter, error), signalAttrs []attribute.KeyValue) { limiter := rate.NewLimiter(w.limitPerSecond, 1) @@ -82,6 +128,29 @@ func (w worker) simulateMetrics(res *resource.Resource, exporterFunc func() (sdk }, }, }) + case metricTypeHistogram: + iteration := uint64(i) % 10 + sum := histogramBucketSamples[iteration].sum + bucketCounts := histogramBucketSamples[iteration].bucketCounts + metrics = append(metrics, metricdata.Metrics{ + Name: w.metricName, + Data: metricdata.Histogram[int64]{ + Temporality: metricdata.CumulativeTemporality, + DataPoints: []metricdata.HistogramDataPoint[int64]{ + { + StartTime: time.Now().Add(-1 * time.Second), + Time: time.Now(), + Attributes: attribute.NewSet(signalAttrs...), + Exemplars: w.exemplars, + Count: iteration, + Sum: sum, + // Bounds from https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#explicit-bucket-histogram-aggregation + Bounds: []float64{0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000}, + BucketCounts: bucketCounts, + }, + }, + }, + }) default: w.logger.Fatal("unknown metric type") }