[processor/transform] Create extract percentile transform function#45518
Conversation
|
/rerun |
atoulme
left a comment
There was a problem hiding this comment.
some nits, LGTM - needs a codeowner review.
|
/rerun |
|
/rerun |
|
This PR was marked stale due to lack of activity. It will be closed in 14 days. |
|
This PR was marked stale due to lack of activity. It will be closed in 14 days. |
Co-authored-by: Edmo Vamerlatti Costa <11836452+edmocosta@users.noreply.github.com>
1b646e3 to
cf8766e
Compare
…r easier understanding
4262fdd to
f33a54c
Compare
|
@evan-bradley @TylerHelmuth @bogdandrutu I'm planning to merge it by Friday, please let me know if you want to review it, or if you need more time for that. Thank you! |
|
Thank you for your contribution @alexcams! 🎉 We would like to hear from you about your experience contributing to OpenTelemetry by taking a few minutes to fill out this survey. If you are getting started contributing, you can also join the CNCF Slack channel #opentelemetry-new-contributors to ask for guidance and get help. |
…pen-telemetry#45518) <!--Ex. Fixing a bug - Describe the bug and how this fixes the issue. Ex. Adding a feature - Explain what this achieves.--> #### Description The `extract_percentile_metric` function creates a new Gauge metric from a Histogram or ExponentialHistogram by calculating the specified percentile value from the bucket counts. A metric will only be created if there is at least one data point. `percentile` is a float64 value between 0 and 100 representing the desired percentile to extract (e.g., 50 for median, 95 for p95, 99 for p99). `suffix` is an optional string that defines the suffix for the metric name. By default, it is set to `_p{percentile}` (e.g., `_p50`, `_p95`, `_p99`). <!-- Issue number (e.g. open-telemetry#1234) or full URL to issue, if applicable. --> #### Link to tracking issue Closes open-telemetry#44316 <!--Describe what testing was performed and which tests were added.--> #### Testing Included unit tests and tested manually with this configuration: ``` yaml receivers: otlp: protocols: grpc: endpoint: 0.0.0.0:4317 http: endpoint: 0.0.0.0:4318 exporters: debug: verbosity: detailed sampling_initial: 10000 sampling_thereafter: 10000 processors: transform: error_mode: ignore metric_statements: - context: metric statements: - extract_percentile_metric(50.0) - extract_percentile_metric(95.0) - extract_percentile_metric(99.0, "_p99_custom") service: telemetry: metrics: level: none pipelines: metrics: receivers: [otlp] processors: [transform] exporters: - debug ``` tested with `telemetrygen` tool with params to generate regular histogram metrics: ``` ./bin/telemetrygen_darwin_arm64 metrics \ ok | 14:34:29 --otlp-insecure \ --otlp-endpoint localhost:4317 \ --metrics 1 \ --otlp-attributes 'service.name="histogram-service"' \ --metric-type Histogram \ --otlp-metric-name "http.server.duration" ``` Obtained output: ``` Metric open-telemetry#1 Descriptor: -> Name: http.server.duration_p50 -> Description: (p50) -> Unit: -> DataType: Gauge NumberDataPoints #0 StartTimestamp: 2026-01-20 13:34:29.409727 +0000 UTC Timestamp: 2026-01-20 13:34:29.409727 +0000 UTC Value: 137.500000 Metric open-telemetry#2 Descriptor: -> Name: http.server.duration_p95 -> Description: (p95) -> Unit: -> DataType: Gauge NumberDataPoints #0 StartTimestamp: 2026-01-20 13:34:29.409727 +0000 UTC Timestamp: 2026-01-20 13:34:29.409727 +0000 UTC Value: 750.000000 Metric open-telemetry#3 Descriptor: -> Name: http.server.duration_p99_custom -> Description: (p99) -> Unit: -> DataType: Gauge NumberDataPoints #0 StartTimestamp: 2026-01-20 13:34:29.409727 +0000 UTC Timestamp: 2026-01-20 13:34:29.409727 +0000 UTC Value: 750.000000 # p99 is placed in last bucket which is [bucket_lower_bound, + Inf ]. Cannot interpolate with Inf values so it is necessary to use lowerbound (750) ``` Tested with Exponential histogram as well: ``` ./bin/telemetrygen_darwin_arm64 metrics \ ok | 14:42:11 --otlp-insecure \ --otlp-endpoint localhost:4317 \ --metrics 1 \ --otlp-attributes 'service.name="histogram-service"' \ --metric-type ExponentialHistogram \ --otlp-metric-name "http.server.duration" ``` and got the output: ``` Metric open-telemetry#1 Descriptor: -> Name: http.server.duration_p50 -> Description: (p50) -> Unit: -> DataType: Gauge NumberDataPoints #0 StartTimestamp: 2026-01-20 13:42:11.599314 +0000 UTC Timestamp: 2026-01-20 13:42:11.599315 +0000 UTC Value: 545.301038 Metric open-telemetry#2 Descriptor: -> Name: http.server.duration_p95 -> Description: (p95) -> Unit: -> DataType: Gauge NumberDataPoints #0 StartTimestamp: 2026-01-20 13:42:11.599314 +0000 UTC Timestamp: 2026-01-20 13:42:11.599315 +0000 UTC Value: 961.465253 Metric open-telemetry#3 Descriptor: -> Name: http.server.duration_p99_custom -> Description: (p99) -> Unit: -> DataType: Gauge NumberDataPoints #0 StartTimestamp: 2026-01-20 13:42:11.599314 +0000 UTC Timestamp: 2026-01-20 13:42:11.599315 +0000 UTC Value: 1024.000000 ``` <!--Describe the documentation added.--> #### Documentation Added proper documentation to transform processor `README.md`. <!--Please delete paragraphs that you did not use before submitting.--> --------- Co-authored-by: Edmo Vamerlatti Costa <11836452+edmocosta@users.noreply.github.com>
…pen-telemetry#45518) <!--Ex. Fixing a bug - Describe the bug and how this fixes the issue. Ex. Adding a feature - Explain what this achieves.--> #### Description The `extract_percentile_metric` function creates a new Gauge metric from a Histogram or ExponentialHistogram by calculating the specified percentile value from the bucket counts. A metric will only be created if there is at least one data point. `percentile` is a float64 value between 0 and 100 representing the desired percentile to extract (e.g., 50 for median, 95 for p95, 99 for p99). `suffix` is an optional string that defines the suffix for the metric name. By default, it is set to `_p{percentile}` (e.g., `_p50`, `_p95`, `_p99`). <!-- Issue number (e.g. open-telemetry#1234) or full URL to issue, if applicable. --> #### Link to tracking issue Closes open-telemetry#44316 <!--Describe what testing was performed and which tests were added.--> #### Testing Included unit tests and tested manually with this configuration: ``` yaml receivers: otlp: protocols: grpc: endpoint: 0.0.0.0:4317 http: endpoint: 0.0.0.0:4318 exporters: debug: verbosity: detailed sampling_initial: 10000 sampling_thereafter: 10000 processors: transform: error_mode: ignore metric_statements: - context: metric statements: - extract_percentile_metric(50.0) - extract_percentile_metric(95.0) - extract_percentile_metric(99.0, "_p99_custom") service: telemetry: metrics: level: none pipelines: metrics: receivers: [otlp] processors: [transform] exporters: - debug ``` tested with `telemetrygen` tool with params to generate regular histogram metrics: ``` ./bin/telemetrygen_darwin_arm64 metrics \ ok | 14:34:29 --otlp-insecure \ --otlp-endpoint localhost:4317 \ --metrics 1 \ --otlp-attributes 'service.name="histogram-service"' \ --metric-type Histogram \ --otlp-metric-name "http.server.duration" ``` Obtained output: ``` Metric open-telemetry#1 Descriptor: -> Name: http.server.duration_p50 -> Description: (p50) -> Unit: -> DataType: Gauge NumberDataPoints #0 StartTimestamp: 2026-01-20 13:34:29.409727 +0000 UTC Timestamp: 2026-01-20 13:34:29.409727 +0000 UTC Value: 137.500000 Metric open-telemetry#2 Descriptor: -> Name: http.server.duration_p95 -> Description: (p95) -> Unit: -> DataType: Gauge NumberDataPoints #0 StartTimestamp: 2026-01-20 13:34:29.409727 +0000 UTC Timestamp: 2026-01-20 13:34:29.409727 +0000 UTC Value: 750.000000 Metric open-telemetry#3 Descriptor: -> Name: http.server.duration_p99_custom -> Description: (p99) -> Unit: -> DataType: Gauge NumberDataPoints #0 StartTimestamp: 2026-01-20 13:34:29.409727 +0000 UTC Timestamp: 2026-01-20 13:34:29.409727 +0000 UTC Value: 750.000000 # p99 is placed in last bucket which is [bucket_lower_bound, + Inf ]. Cannot interpolate with Inf values so it is necessary to use lowerbound (750) ``` Tested with Exponential histogram as well: ``` ./bin/telemetrygen_darwin_arm64 metrics \ ok | 14:42:11 --otlp-insecure \ --otlp-endpoint localhost:4317 \ --metrics 1 \ --otlp-attributes 'service.name="histogram-service"' \ --metric-type ExponentialHistogram \ --otlp-metric-name "http.server.duration" ``` and got the output: ``` Metric open-telemetry#1 Descriptor: -> Name: http.server.duration_p50 -> Description: (p50) -> Unit: -> DataType: Gauge NumberDataPoints #0 StartTimestamp: 2026-01-20 13:42:11.599314 +0000 UTC Timestamp: 2026-01-20 13:42:11.599315 +0000 UTC Value: 545.301038 Metric open-telemetry#2 Descriptor: -> Name: http.server.duration_p95 -> Description: (p95) -> Unit: -> DataType: Gauge NumberDataPoints #0 StartTimestamp: 2026-01-20 13:42:11.599314 +0000 UTC Timestamp: 2026-01-20 13:42:11.599315 +0000 UTC Value: 961.465253 Metric open-telemetry#3 Descriptor: -> Name: http.server.duration_p99_custom -> Description: (p99) -> Unit: -> DataType: Gauge NumberDataPoints #0 StartTimestamp: 2026-01-20 13:42:11.599314 +0000 UTC Timestamp: 2026-01-20 13:42:11.599315 +0000 UTC Value: 1024.000000 ``` <!--Describe the documentation added.--> #### Documentation Added proper documentation to transform processor `README.md`. <!--Please delete paragraphs that you did not use before submitting.--> --------- Co-authored-by: Edmo Vamerlatti Costa <11836452+edmocosta@users.noreply.github.com>
Description
The
extract_percentile_metricfunction creates a new Gauge metric from a Histogram or ExponentialHistogram by calculating the specified percentile value from the bucket counts. A metric will only be created if there is at least one data point.percentileis a float64 value between 0 and 100 representing the desired percentile to extract (e.g., 50 for median, 95 for p95, 99 for p99).suffixis an optional string that defines the suffix for the metric name. By default, it is set to_p{percentile}(e.g.,_p50,_p95,_p99).Link to tracking issue
Closes #44316
Testing
Included unit tests and tested manually with this configuration:
tested with
telemetrygentool with params to generate regular histogram metrics:Obtained output:
Tested with Exponential histogram as well:
and got the output:
Documentation
Added proper documentation to transform processor
README.md.