Skip to content

Commit a46eb7b

Browse files
author
Mateusz Rzeszutek
committed
Specify http.(client|server).duration buckets using advice API
1 parent b09bddd commit a46eb7b

File tree

6 files changed

+69
-22
lines changed

6 files changed

+69
-22
lines changed

instrumentation-api-semconv/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ group = "io.opentelemetry.instrumentation"
1313
dependencies {
1414
api("io.opentelemetry:opentelemetry-semconv")
1515
api(project(":instrumentation-api"))
16+
implementation("io.opentelemetry:opentelemetry-extension-incubator")
1617

1718
compileOnly("com.google.auto.value:auto-value-annotations")
1819
annotationProcessor("com.google.auto.value:auto-value")
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.instrumentation.api.instrumenter.http;
7+
8+
import static java.util.Arrays.asList;
9+
import static java.util.Collections.unmodifiableList;
10+
11+
import io.opentelemetry.api.metrics.DoubleHistogramBuilder;
12+
import io.opentelemetry.extension.incubator.metrics.ExtendedDoubleHistogramBuilder;
13+
import java.util.List;
14+
15+
final class HistogramAdviceUtil {
16+
17+
static final List<Double> DURATION_SECONDS_BUCKETS =
18+
unmodifiableList(
19+
asList(
20+
0.0, 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1.0, 2.5, 5.0, 7.5,
21+
10.0));
22+
23+
static void setHttpDurationBuckets(DoubleHistogramBuilder builder) {
24+
if (!(builder instanceof ExtendedDoubleHistogramBuilder)) {
25+
// that shouldn't really happen
26+
return;
27+
}
28+
((ExtendedDoubleHistogramBuilder) builder)
29+
.setAdvice(advice -> advice.setExplicitBucketBoundaries(DURATION_SECONDS_BUCKETS));
30+
}
31+
32+
private HistogramAdviceUtil() {}
33+
}

instrumentation-api-semconv/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/http/HttpClientMetrics.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import io.opentelemetry.api.common.AttributeKey;
1313
import io.opentelemetry.api.common.Attributes;
1414
import io.opentelemetry.api.metrics.DoubleHistogram;
15+
import io.opentelemetry.api.metrics.DoubleHistogramBuilder;
1516
import io.opentelemetry.api.metrics.LongHistogram;
1617
import io.opentelemetry.api.metrics.Meter;
1718
import io.opentelemetry.context.Context;
@@ -30,7 +31,7 @@
3031
*/
3132
public final class HttpClientMetrics implements OperationListener {
3233

33-
private static final double NANOS_PER_MS = TimeUnit.MILLISECONDS.toNanos(1);
34+
private static final double NANOS_PER_S = TimeUnit.SECONDS.toNanos(1);
3435

3536
private static final ContextKey<State> HTTP_CLIENT_REQUEST_METRICS_STATE =
3637
ContextKey.named("http-client-request-metrics-state");
@@ -51,12 +52,13 @@ public static OperationMetrics get() {
5152
private final LongHistogram responseSize;
5253

5354
private HttpClientMetrics(Meter meter) {
54-
duration =
55+
DoubleHistogramBuilder durationBuilder =
5556
meter
5657
.histogramBuilder("http.client.duration")
57-
.setUnit("ms")
58-
.setDescription("The duration of the outbound HTTP request")
59-
.build();
58+
.setUnit("s")
59+
.setDescription("The duration of the outbound HTTP request");
60+
HistogramAdviceUtil.setHttpDurationBuckets(durationBuilder);
61+
duration = durationBuilder.build();
6062
requestSize =
6163
meter
6264
.histogramBuilder("http.client.request.size")
@@ -93,7 +95,7 @@ public void onEnd(Context context, Attributes endAttributes, long endNanos) {
9395
Attributes durationAndSizeAttributes =
9496
applyClientDurationAndSizeView(state.startAttributes(), endAttributes);
9597
duration.record(
96-
(endNanos - state.startTimeNanos()) / NANOS_PER_MS, durationAndSizeAttributes, context);
98+
(endNanos - state.startTimeNanos()) / NANOS_PER_S, durationAndSizeAttributes, context);
9799
Long requestLength =
98100
getAttribute(
99101
SemanticAttributes.HTTP_REQUEST_CONTENT_LENGTH, endAttributes, state.startAttributes());

instrumentation-api-semconv/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/http/HttpServerMetrics.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import io.opentelemetry.api.common.AttributeKey;
1414
import io.opentelemetry.api.common.Attributes;
1515
import io.opentelemetry.api.metrics.DoubleHistogram;
16+
import io.opentelemetry.api.metrics.DoubleHistogramBuilder;
1617
import io.opentelemetry.api.metrics.LongHistogram;
1718
import io.opentelemetry.api.metrics.LongUpDownCounter;
1819
import io.opentelemetry.api.metrics.Meter;
@@ -32,7 +33,7 @@
3233
*/
3334
public final class HttpServerMetrics implements OperationListener {
3435

35-
private static final double NANOS_PER_MS = TimeUnit.MILLISECONDS.toNanos(1);
36+
private static final double NANOS_PER_S = TimeUnit.SECONDS.toNanos(1);
3637

3738
private static final ContextKey<State> HTTP_SERVER_REQUEST_METRICS_STATE =
3839
ContextKey.named("http-server-request-metrics-state");
@@ -61,12 +62,13 @@ private HttpServerMetrics(Meter meter) {
6162
.setDescription("The number of concurrent HTTP requests that are currently in-flight")
6263
.build();
6364

64-
duration =
65+
DoubleHistogramBuilder durationBuilder =
6566
meter
6667
.histogramBuilder("http.server.duration")
67-
.setUnit("ms")
68-
.setDescription("The duration of the inbound HTTP request")
69-
.build();
68+
.setUnit("s")
69+
.setDescription("The duration of the inbound HTTP request");
70+
HistogramAdviceUtil.setHttpDurationBuckets(durationBuilder);
71+
duration = durationBuilder.build();
7072
requestSize =
7173
meter
7274
.histogramBuilder("http.server.request.size")
@@ -108,7 +110,7 @@ public void onEnd(Context context, Attributes endAttributes, long endNanos) {
108110
Attributes durationAndSizeAttributes =
109111
applyServerDurationAndSizeView(state.startAttributes(), endAttributes);
110112
duration.record(
111-
(endNanos - state.startTimeNanos()) / NANOS_PER_MS, durationAndSizeAttributes, context);
113+
(endNanos - state.startTimeNanos()) / NANOS_PER_S, durationAndSizeAttributes, context);
112114
Long requestLength =
113115
getAttribute(
114116
SemanticAttributes.HTTP_REQUEST_CONTENT_LENGTH, endAttributes, state.startAttributes());

instrumentation-api-semconv/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/http/HttpClientMetricsTest.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424

2525
class HttpClientMetricsTest {
2626

27+
static final double[] DURATION_BUCKETS =
28+
HistogramAdviceUtil.DURATION_SECONDS_BUCKETS.stream().mapToDouble(d -> d).toArray();
29+
2730
@Test
2831
void collectsMetrics() {
2932
InMemoryMetricReader metricReader = InMemoryMetricReader.create();
@@ -79,13 +82,13 @@ void collectsMetrics() {
7982
metric ->
8083
assertThat(metric)
8184
.hasName("http.client.duration")
82-
.hasUnit("ms")
85+
.hasUnit("s")
8386
.hasHistogramSatisfying(
8487
histogram ->
8588
histogram.hasPointsSatisfying(
8689
point ->
8790
point
88-
.hasSum(150 /* millis */)
91+
.hasSum(0.15 /* seconds */)
8992
.hasAttributesSatisfying(
9093
equalTo(SemanticAttributes.HTTP_METHOD, "GET"),
9194
equalTo(SemanticAttributes.HTTP_STATUS_CODE, 200),
@@ -99,7 +102,8 @@ void collectsMetrics() {
99102
exemplar ->
100103
exemplar
101104
.hasTraceId("ff01020304050600ff0a0b0c0d0e0f00")
102-
.hasSpanId("090a0b0c0d0e0f00")))),
105+
.hasSpanId("090a0b0c0d0e0f00"))
106+
.hasBucketBoundaries(DURATION_BUCKETS))),
103107
metric ->
104108
assertThat(metric)
105109
.hasName("http.client.request.size")
@@ -158,7 +162,8 @@ void collectsMetrics() {
158162
.hasName("http.client.duration")
159163
.hasHistogramSatisfying(
160164
histogram ->
161-
histogram.hasPointsSatisfying(point -> point.hasSum(300 /* millis */))),
165+
histogram.hasPointsSatisfying(
166+
point -> point.hasSum(0.3 /* seconds */))),
162167
metric ->
163168
assertThat(metric)
164169
.hasName("http.client.request.size")

instrumentation-api-semconv/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/http/HttpServerMetricsTest.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525

2626
class HttpServerMetricsTest {
2727

28+
static final double[] DURATION_BUCKETS =
29+
HistogramAdviceUtil.DURATION_SECONDS_BUCKETS.stream().mapToDouble(d -> d).toArray();
30+
2831
@Test
2932
void collectsMetrics() {
3033
InMemoryMetricReader metricReader = InMemoryMetricReader.create();
@@ -149,13 +152,13 @@ void collectsMetrics() {
149152
metric ->
150153
assertThat(metric)
151154
.hasName("http.server.duration")
152-
.hasUnit("ms")
155+
.hasUnit("s")
153156
.hasHistogramSatisfying(
154157
histogram ->
155158
histogram.hasPointsSatisfying(
156159
point ->
157160
point
158-
.hasSum(150 /* millis */)
161+
.hasSum(0.15 /* seconds */)
159162
.hasAttributesSatisfying(
160163
equalTo(SemanticAttributes.HTTP_METHOD, "GET"),
161164
equalTo(SemanticAttributes.HTTP_STATUS_CODE, 200),
@@ -168,7 +171,8 @@ void collectsMetrics() {
168171
exemplar ->
169172
exemplar
170173
.hasTraceId(spanContext1.getTraceId())
171-
.hasSpanId(spanContext1.getSpanId())))),
174+
.hasSpanId(spanContext1.getSpanId()))
175+
.hasBucketBoundaries(DURATION_BUCKETS))),
172176
metric ->
173177
assertThat(metric)
174178
.hasName("http.server.request.size")
@@ -242,7 +246,7 @@ void collectsMetrics() {
242246
histogram.hasPointsSatisfying(
243247
point ->
244248
point
245-
.hasSum(300 /* millis */)
249+
.hasSum(0.3 /* seconds */)
246250
.hasExemplarsSatisfying(
247251
exemplar ->
248252
exemplar
@@ -304,13 +308,13 @@ void collectsHttpRouteFromEndAttributes() {
304308
metric ->
305309
assertThat(metric)
306310
.hasName("http.server.duration")
307-
.hasUnit("ms")
311+
.hasUnit("s")
308312
.hasHistogramSatisfying(
309313
histogram ->
310314
histogram.hasPointsSatisfying(
311315
point ->
312316
point
313-
.hasSum(100 /* millis */)
317+
.hasSum(0.100 /* seconds */)
314318
.hasAttributesSatisfying(
315319
equalTo(SemanticAttributes.HTTP_SCHEME, "https"),
316320
equalTo(SemanticAttributes.NET_HOST_NAME, "host"),

0 commit comments

Comments
 (0)