From 316530118d3a14e212a608dd617af07df8c407b2 Mon Sep 17 00:00:00 2001 From: Shivanth MP Date: Tue, 17 Dec 2024 14:00:22 +0100 Subject: [PATCH] Add histogram to telemetrygen (#36322) #### Description Generates simple histograms using telemetrygen #### Link to tracking issue Fixes #### Testing Test with a local otel collector with debug output ``` bin/telemetrygen metrics --metrics 5 --otlp-http --otlp-endpoint "localhost:4318" --metric-type Histogram --otlp-insecure ``` Output from debug Exporter: ``` Resource SchemaURL: https://opentelemetry.io/schemas/1.13.0 ScopeMetrics #0 ScopeMetrics SchemaURL: InstrumentationScope Metric #0 Descriptor: -> Name: gen -> Description: -> Unit: -> DataType: Histogram -> AggregationTemporality: Cumulative HistogramDataPoints #0 StartTimestamp: 2024-11-13 16:22:50.633365 +0000 UTC Timestamp: 2024-11-13 16:22:51.633367 +0000 UTC Count: 0 Sum: 0.000000 ExplicitBounds #0: 0.000000 ExplicitBounds #1: 1.000000 ExplicitBounds #2: 2.000000 ExplicitBounds #3: 3.000000 ExplicitBounds #4: 4.000000 Buckets #0, Count: 0 Buckets #1, Count: 0 Buckets #2, Count: 0 Buckets #3, Count: 0 Buckets #4, Count: 0 ResourceMetrics #1 Resource SchemaURL: https://opentelemetry.io/schemas/1.13.0 ScopeMetrics #0 ScopeMetrics SchemaURL: InstrumentationScope Metric #0 Descriptor: -> Name: gen -> Description: -> Unit: -> DataType: Histogram -> AggregationTemporality: Cumulative HistogramDataPoints #0 StartTimestamp: 2024-11-13 16:22:50.639942 +0000 UTC Timestamp: 2024-11-13 16:22:51.639942 +0000 UTC Count: 1 Sum: 1.000000 ExplicitBounds #0: 0.000000 ExplicitBounds #1: 1.000000 ExplicitBounds #2: 2.000000 ExplicitBounds #3: 3.000000 ExplicitBounds #4: 4.000000 Buckets #0, Count: 0 Buckets #1, Count: 1 Buckets #2, Count: 0 Buckets #3, Count: 0 Buckets #4, Count: 0 ResourceMetrics #2 Resource SchemaURL: https://opentelemetry.io/schemas/1.13.0 ScopeMetrics #0 ScopeMetrics SchemaURL: InstrumentationScope Metric #0 Descriptor: -> Name: gen -> Description: -> Unit: -> DataType: Histogram -> AggregationTemporality: Cumulative HistogramDataPoints #0 StartTimestamp: 2024-11-13 16:22:50.6404 +0000 UTC Timestamp: 2024-11-13 16:22:51.640401 +0000 UTC Count: 2 Sum: 4.000000 ExplicitBounds #0: 0.000000 ExplicitBounds #1: 1.000000 ExplicitBounds #2: 2.000000 ExplicitBounds #3: 3.000000 ExplicitBounds #4: 4.000000 Buckets #0, Count: 0 Buckets #1, Count: 1 Buckets #2, Count: 0 Buckets #3, Count: 1 Buckets #4, Count: 0 ResourceMetrics #3 Resource SchemaURL: https://opentelemetry.io/schemas/1.13.0 ScopeMetrics #0 ScopeMetrics SchemaURL: InstrumentationScope Metric #0 Descriptor: -> Name: gen -> Description: -> Unit: -> DataType: Histogram -> AggregationTemporality: Cumulative HistogramDataPoints #0 StartTimestamp: 2024-11-13 16:22:50.640729 +0000 UTC Timestamp: 2024-11-13 16:22:51.640729 +0000 UTC Count: 3 Sum: 3.000000 ExplicitBounds #0: 0.000000 ExplicitBounds #1: 1.000000 ExplicitBounds #2: 2.000000 ExplicitBounds #3: 3.000000 ExplicitBounds #4: 4.000000 Buckets #0, Count: 1 Buckets #1, Count: 1 Buckets #2, Count: 1 Buckets #3, Count: 0 Buckets #4, Count: 0 ResourceMetrics #4 Resource SchemaURL: https://opentelemetry.io/schemas/1.13.0 ScopeMetrics #0 ScopeMetrics SchemaURL: InstrumentationScope Metric #0 Descriptor: -> Name: gen -> Description: -> Unit: -> DataType: Histogram -> AggregationTemporality: Cumulative HistogramDataPoints #0 StartTimestamp: 2024-11-13 16:22:50.641073 +0000 UTC Timestamp: 2024-11-13 16:22:51.641073 +0000 UTC Count: 4 Sum: 12.000000 ExplicitBounds #0: 0.000000 ExplicitBounds #1: 1.000000 ExplicitBounds #2: 2.000000 ExplicitBounds #3: 3.000000 ExplicitBounds #4: 4.000000 Buckets #0, Count: 0 Buckets #1, Count: 0 Buckets #2, Count: 1 Buckets #3, Count: 2 Buckets #4, Count: 1 {"kind": "exporter", "data_type": "metrics", "name": "debug"} ``` #### Documentation --------- Co-authored-by: Pablo Baeyens --- .chloggen/telemetrygen.yaml | 27 ++++++++ .../internal/metrics/metrics_types.go | 9 +-- cmd/telemetrygen/internal/metrics/worker.go | 69 +++++++++++++++++++ 3 files changed, 101 insertions(+), 4 deletions(-) create mode 100644 .chloggen/telemetrygen.yaml 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") }