K6 Percentile Metric to Open Telemetry

Is there a way to include the http_req_duration percentile (e.g., 95pct) metric to an Open Telemetry collector using the xk6-output-opentelemetry?

I’m using the otel/opentelemetry-collector-contrib docker image to observe the k6 metrics.

Here are the OTEL logs for http_req_duration:

Metric #1
Descriptor:
     -> Name: xk6_http_req_duration
     -> Description: 
     -> Unit: ms
     -> DataType: Histogram
     -> AggregationTemporality: Cumulative
HistogramDataPoints #0
Data point attributes:
     -> expected_response: Str(true)
     -> method: Str(GET)
     -> name: Str(https://test-api.k6.io/public/crocodiles/)
     -> proto: Str(HTTP/1.1)
     -> scenario: Str(default)
     -> status: Str(200)
     -> tls_version: Str(tls1.3)
     -> url: Str(https://test-api.k6.io/public/crocodiles/)
StartTimestamp: 2024-10-24 21:26:52.6301498 +0000 UTC
Timestamp: 2024-10-24 21:27:04.9982745 +0000 UTC
Count: 10
Sum: 3281.936400
Min: 231.867900
Max: 617.501800
ExplicitBounds #0: 0.000000
ExplicitBounds #1: 5.000000
ExplicitBounds #2: 10.000000
ExplicitBounds #3: 25.000000
ExplicitBounds #4: 50.000000
ExplicitBounds #5: 75.000000
ExplicitBounds #6: 100.000000
ExplicitBounds #7: 250.000000
ExplicitBounds #8: 500.000000
ExplicitBounds #9: 750.000000
ExplicitBounds #10: 1000.000000
ExplicitBounds #11: 2500.000000
ExplicitBounds #12: 5000.000000
ExplicitBounds #13: 7500.000000
ExplicitBounds #14: 10000.000000
Buckets #0, Count: 0
Buckets #1, Count: 0
Buckets #2, Count: 0
Buckets #3, Count: 0
Buckets #4, Count: 0
Buckets #5, Count: 0
Buckets #6, Count: 0
Buckets #7, Count: 4
Buckets #8, Count: 4
Buckets #9, Count: 2
Buckets #10, Count: 0
Buckets #11, Count: 0
Buckets #12, Count: 0
Buckets #13, Count: 0
Buckets #14, Count: 0
Buckets #15, Count: 0



Metric #1
Descriptor:
     -> Name: xk6_http_req_duration
     -> Description: 
     -> Unit: ms
     -> DataType: Histogram
     -> AggregationTemporality: Cumulative
HistogramDataPoints #0
Data point attributes:
     -> expected_response: Str(true)
     -> method: Str(GET)
     -> name: Str(https://test-api.k6.io/public/crocodiles/)
     -> proto: Str(HTTP/1.1)
     -> scenario: Str(default)
     -> status: Str(200)
     -> tls_version: Str(tls1.3)
     -> url: Str(https://test-api.k6.io/public/crocodiles/)
StartTimestamp: 2024-10-24 21:26:52.6301498 +0000 UTC
Timestamp: 2024-10-24 21:27:01.6303461 +0000 UTC
Count: 7
Sum: 2422.021100
Min: 236.269500
Max: 617.501800
ExplicitBounds #0: 0.000000
ExplicitBounds #1: 5.000000
ExplicitBounds #2: 10.000000
ExplicitBounds #3: 25.000000
ExplicitBounds #4: 50.000000
ExplicitBounds #5: 75.000000
ExplicitBounds #6: 100.000000
ExplicitBounds #7: 250.000000
ExplicitBounds #8: 500.000000
ExplicitBounds #9: 750.000000
ExplicitBounds #10: 1000.000000
ExplicitBounds #11: 2500.000000
ExplicitBounds #12: 5000.000000
ExplicitBounds #13: 7500.000000
ExplicitBounds #14: 10000.000000
Buckets #0, Count: 0
Buckets #1, Count: 0
Buckets #2, Count: 0
Buckets #3, Count: 0
Buckets #4, Count: 0
Buckets #5, Count: 0
Buckets #6, Count: 0
Buckets #7, Count: 2
Buckets #8, Count: 3
Buckets #9, Count: 2
Buckets #10, Count: 0
Buckets #11, Count: 0
Buckets #12, Count: 0
Buckets #13, Count: 0
Buckets #14, Count: 0
Buckets #15, Count: 0

k6 script:

import http from 'k6/http';
import { sleep } from 'k6';

export const options = {
  summaryTrendStats: ["min", "max", "p(95)"],

  thresholds: {
    http_req_duration: ["p(95)<1000"],
  },
};

export default function () {
    http.get('https://test-api.k6.io/public/crocodiles/');
    sleep(1);
}

Run OTEL collector:

docker run --rm -p 4317:4317 -d otel/opentelemetry-collector-contrib

k6 command

./k6 run -e K6_OTEL_METRIC_PREFIX=xk6_ -e K6_OTEL_GRPC_EXPORTER_INSECURE=true -e K6_OTEL_GRPC_EXPORTER_ENDPOINT=0.0.0.0:4317 .\test.js -o experimental-opentelemetry --vus 1 --iterations 10

Hi @kiksplx !

When you use the k6’s open telemetry output, the http_req_duration sends this metric as the histogram, and to get percentile, like 95th you have to apply some aggregation function depending on the metrics backend that you’re using.

For instance, in the xk6-output-opentelemetry repository is the docker-compose example based on the Prometheus, where you see how it’s done there.

Let me know if that answers.

Cheers!

1 Like