Skip to content

Commit 1381f16

Browse files
authored
Split ArmeriaTelemetry into client and server (#12851)
1 parent de9c891 commit 1381f16

File tree

13 files changed

+602
-52
lines changed

13 files changed

+602
-52
lines changed

instrumentation/armeria/armeria-1.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/armeria/v1_3/ArmeriaSingletons.java

+20-8
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@
99
import com.linecorp.armeria.server.HttpService;
1010
import io.opentelemetry.api.GlobalOpenTelemetry;
1111
import io.opentelemetry.instrumentation.api.incubator.config.internal.CommonConfig;
12-
import io.opentelemetry.instrumentation.armeria.v1_3.ArmeriaTelemetry;
13-
import io.opentelemetry.instrumentation.armeria.v1_3.ArmeriaTelemetryBuilder;
12+
import io.opentelemetry.instrumentation.armeria.v1_3.ArmeriaClientTelemetry;
13+
import io.opentelemetry.instrumentation.armeria.v1_3.ArmeriaClientTelemetryBuilder;
14+
import io.opentelemetry.instrumentation.armeria.v1_3.ArmeriaServerTelemetry;
15+
import io.opentelemetry.instrumentation.armeria.v1_3.ArmeriaServerTelemetryBuilder;
1416
import io.opentelemetry.instrumentation.armeria.v1_3.internal.ArmeriaInstrumenterBuilderUtil;
1517
import io.opentelemetry.javaagent.bootstrap.internal.AgentCommonConfig;
1618
import java.util.function.Function;
@@ -23,15 +25,25 @@ public final class ArmeriaSingletons {
2325
public static final Function<? super HttpService, ? extends HttpService> SERVER_DECORATOR;
2426

2527
static {
26-
ArmeriaTelemetryBuilder builder = ArmeriaTelemetry.builder(GlobalOpenTelemetry.get());
2728
CommonConfig config = AgentCommonConfig.get();
28-
ArmeriaInstrumenterBuilderUtil.getClientBuilderExtractor().apply(builder).configure(config);
29-
ArmeriaInstrumenterBuilderUtil.getServerBuilderExtractor().apply(builder).configure(config);
30-
ArmeriaTelemetry telemetry = builder.build();
3129

32-
CLIENT_DECORATOR = telemetry.newClientDecorator();
30+
ArmeriaClientTelemetryBuilder clientBuilder =
31+
ArmeriaClientTelemetry.builder(GlobalOpenTelemetry.get());
32+
ArmeriaInstrumenterBuilderUtil.getClientBuilderExtractor()
33+
.apply(clientBuilder)
34+
.configure(config);
35+
ArmeriaClientTelemetry clientTelemetry = clientBuilder.build();
36+
37+
ArmeriaServerTelemetryBuilder serverBuilder =
38+
ArmeriaServerTelemetry.builder(GlobalOpenTelemetry.get());
39+
ArmeriaInstrumenterBuilderUtil.getServerBuilderExtractor()
40+
.apply(serverBuilder)
41+
.configure(config);
42+
ArmeriaServerTelemetry serverTelemetry = serverBuilder.build();
43+
44+
CLIENT_DECORATOR = clientTelemetry.newDecorator();
3345
Function<? super HttpService, ? extends HttpService> libraryDecorator =
34-
telemetry.newServiceDecorator().compose(ResponseCustomizingDecorator::new);
46+
serverTelemetry.newDecorator().compose(ResponseCustomizingDecorator::new);
3547
SERVER_DECORATOR = service -> new ServerDecorator(service, libraryDecorator.apply(service));
3648
}
3749

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.instrumentation.armeria.v1_3;
7+
8+
import com.linecorp.armeria.client.ClientRequestContext;
9+
import com.linecorp.armeria.client.HttpClient;
10+
import com.linecorp.armeria.common.logging.RequestLog;
11+
import io.opentelemetry.api.OpenTelemetry;
12+
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
13+
import java.util.function.Function;
14+
15+
/** Entrypoint for instrumenting Armeria clients. */
16+
public final class ArmeriaClientTelemetry {
17+
18+
/**
19+
* Returns a new {@link ArmeriaClientTelemetry} configured with the given {@link OpenTelemetry}.
20+
*/
21+
public static ArmeriaClientTelemetry create(OpenTelemetry openTelemetry) {
22+
return builder(openTelemetry).build();
23+
}
24+
25+
public static ArmeriaClientTelemetryBuilder builder(OpenTelemetry openTelemetry) {
26+
return new ArmeriaClientTelemetryBuilder(openTelemetry);
27+
}
28+
29+
private final Instrumenter<ClientRequestContext, RequestLog> instrumenter;
30+
31+
ArmeriaClientTelemetry(Instrumenter<ClientRequestContext, RequestLog> instrumenter) {
32+
this.instrumenter = instrumenter;
33+
}
34+
35+
/**
36+
* Returns a new {@link HttpClient} decorator for use with methods like {@link
37+
* com.linecorp.armeria.client.ClientBuilder#decorator(Function)}.
38+
*/
39+
public Function<? super HttpClient, ? extends HttpClient> newDecorator() {
40+
return client -> new OpenTelemetryClient(client, instrumenter);
41+
}
42+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.instrumentation.armeria.v1_3;
7+
8+
import com.google.errorprone.annotations.CanIgnoreReturnValue;
9+
import com.linecorp.armeria.client.ClientRequestContext;
10+
import com.linecorp.armeria.common.logging.RequestLog;
11+
import io.opentelemetry.api.OpenTelemetry;
12+
import io.opentelemetry.instrumentation.api.incubator.builder.internal.DefaultHttpClientInstrumenterBuilder;
13+
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
14+
import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor;
15+
import io.opentelemetry.instrumentation.api.instrumenter.SpanStatusExtractor;
16+
import io.opentelemetry.instrumentation.api.semconv.http.HttpClientAttributesExtractorBuilder;
17+
import io.opentelemetry.instrumentation.armeria.v1_3.internal.ArmeriaInstrumenterBuilderFactory;
18+
import io.opentelemetry.instrumentation.armeria.v1_3.internal.ArmeriaInstrumenterBuilderUtil;
19+
import io.opentelemetry.instrumentation.armeria.v1_3.internal.Experimental;
20+
import java.util.List;
21+
import java.util.Set;
22+
import java.util.function.Function;
23+
24+
public final class ArmeriaClientTelemetryBuilder {
25+
26+
private final DefaultHttpClientInstrumenterBuilder<ClientRequestContext, RequestLog> builder;
27+
28+
static {
29+
ArmeriaInstrumenterBuilderUtil.setClientBuilderExtractor(builder -> builder.builder);
30+
Experimental.setSetEmitExperimentalClientTelemetry(
31+
(builder, emit) -> builder.builder.setEmitExperimentalHttpClientMetrics(emit));
32+
Experimental.setSetClientPeerService(
33+
(builder, peerService) -> builder.builder.setPeerService(peerService));
34+
}
35+
36+
ArmeriaClientTelemetryBuilder(OpenTelemetry openTelemetry) {
37+
builder = ArmeriaInstrumenterBuilderFactory.getClientBuilder(openTelemetry);
38+
}
39+
40+
/** Sets the status extractor for client spans. */
41+
@CanIgnoreReturnValue
42+
public ArmeriaClientTelemetryBuilder setStatusExtractor(
43+
Function<
44+
SpanStatusExtractor<? super ClientRequestContext, ? super RequestLog>,
45+
? extends SpanStatusExtractor<? super ClientRequestContext, ? super RequestLog>>
46+
statusExtractor) {
47+
builder.setStatusExtractor(statusExtractor);
48+
return this;
49+
}
50+
51+
/**
52+
* Adds an extra {@link AttributesExtractor} to invoke to set attributes to instrumented items.
53+
* The {@link AttributesExtractor} will be executed after all default extractors.
54+
*/
55+
@CanIgnoreReturnValue
56+
public ArmeriaClientTelemetryBuilder addAttributesExtractor(
57+
AttributesExtractor<? super ClientRequestContext, ? super RequestLog> attributesExtractor) {
58+
builder.addAttributesExtractor(attributesExtractor);
59+
return this;
60+
}
61+
62+
/**
63+
* Configures the HTTP client request headers that will be captured as span attributes.
64+
*
65+
* @param requestHeaders A list of HTTP header names.
66+
*/
67+
@CanIgnoreReturnValue
68+
public ArmeriaClientTelemetryBuilder setCapturedRequestHeaders(List<String> requestHeaders) {
69+
builder.setCapturedRequestHeaders(requestHeaders);
70+
return this;
71+
}
72+
73+
/**
74+
* Configures the HTTP client response headers that will be captured as span attributes.
75+
*
76+
* @param responseHeaders A list of HTTP header names.
77+
*/
78+
@CanIgnoreReturnValue
79+
public ArmeriaClientTelemetryBuilder setCapturedResponseHeaders(List<String> responseHeaders) {
80+
builder.setCapturedResponseHeaders(responseHeaders);
81+
return this;
82+
}
83+
84+
/**
85+
* Configures the instrumentation to recognize an alternative set of HTTP request methods.
86+
*
87+
* <p>By default, this instrumentation defines "known" methods as the ones listed in <a
88+
* href="https://www.rfc-editor.org/rfc/rfc9110.html#name-methods">RFC9110</a> and the PATCH
89+
* method defined in <a href="https://www.rfc-editor.org/rfc/rfc5789.html">RFC5789</a>.
90+
*
91+
* <p>Note: calling this method <b>overrides</b> the default known method sets completely; it does
92+
* not supplement it.
93+
*
94+
* @param knownMethods A set of recognized HTTP request methods.
95+
* @see HttpClientAttributesExtractorBuilder#setKnownMethods(Set)
96+
*/
97+
@CanIgnoreReturnValue
98+
public ArmeriaClientTelemetryBuilder setKnownMethods(Set<String> knownMethods) {
99+
builder.setKnownMethods(knownMethods);
100+
return this;
101+
}
102+
103+
/** Sets custom client {@link SpanNameExtractor} via transform function. */
104+
@CanIgnoreReturnValue
105+
public ArmeriaClientTelemetryBuilder setSpanNameExtractor(
106+
Function<
107+
SpanNameExtractor<? super ClientRequestContext>,
108+
? extends SpanNameExtractor<? super ClientRequestContext>>
109+
clientSpanNameExtractor) {
110+
builder.setSpanNameExtractor(clientSpanNameExtractor);
111+
return this;
112+
}
113+
114+
public ArmeriaClientTelemetry build() {
115+
return new ArmeriaClientTelemetry(builder.build());
116+
}
117+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.instrumentation.armeria.v1_3;
7+
8+
import com.linecorp.armeria.common.logging.RequestLog;
9+
import com.linecorp.armeria.server.HttpService;
10+
import com.linecorp.armeria.server.ServiceRequestContext;
11+
import io.opentelemetry.api.OpenTelemetry;
12+
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
13+
import java.util.function.Function;
14+
15+
/** Entrypoint for instrumenting Armeria services. */
16+
public final class ArmeriaServerTelemetry {
17+
18+
/**
19+
* Returns a new {@link ArmeriaServerTelemetry} configured with the given {@link OpenTelemetry}.
20+
*/
21+
public static ArmeriaServerTelemetry create(OpenTelemetry openTelemetry) {
22+
return builder(openTelemetry).build();
23+
}
24+
25+
public static ArmeriaServerTelemetryBuilder builder(OpenTelemetry openTelemetry) {
26+
return new ArmeriaServerTelemetryBuilder(openTelemetry);
27+
}
28+
29+
private final Instrumenter<ServiceRequestContext, RequestLog> instrumenter;
30+
31+
ArmeriaServerTelemetry(Instrumenter<ServiceRequestContext, RequestLog> instrumenter) {
32+
this.instrumenter = instrumenter;
33+
}
34+
35+
/**
36+
* Returns a new {@link HttpService} decorator for use with methods like {@link
37+
* HttpService#decorate(Function)}.
38+
*/
39+
public Function<? super HttpService, ? extends HttpService> newDecorator() {
40+
return service -> new OpenTelemetryService(service, instrumenter);
41+
}
42+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.instrumentation.armeria.v1_3;
7+
8+
import com.google.errorprone.annotations.CanIgnoreReturnValue;
9+
import com.linecorp.armeria.common.logging.RequestLog;
10+
import com.linecorp.armeria.server.ServiceRequestContext;
11+
import io.opentelemetry.api.OpenTelemetry;
12+
import io.opentelemetry.instrumentation.api.incubator.builder.internal.DefaultHttpServerInstrumenterBuilder;
13+
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
14+
import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor;
15+
import io.opentelemetry.instrumentation.api.instrumenter.SpanStatusExtractor;
16+
import io.opentelemetry.instrumentation.api.semconv.http.HttpServerAttributesExtractorBuilder;
17+
import io.opentelemetry.instrumentation.armeria.v1_3.internal.ArmeriaInstrumenterBuilderFactory;
18+
import io.opentelemetry.instrumentation.armeria.v1_3.internal.ArmeriaInstrumenterBuilderUtil;
19+
import io.opentelemetry.instrumentation.armeria.v1_3.internal.Experimental;
20+
import java.util.List;
21+
import java.util.Set;
22+
import java.util.function.Function;
23+
24+
public final class ArmeriaServerTelemetryBuilder {
25+
26+
private final DefaultHttpServerInstrumenterBuilder<ServiceRequestContext, RequestLog> builder;
27+
28+
static {
29+
ArmeriaInstrumenterBuilderUtil.setServerBuilderExtractor(builder -> builder.builder);
30+
Experimental.setSetEmitExperimentalServerTelemetry(
31+
(builder, emit) -> builder.builder.setEmitExperimentalHttpServerMetrics(emit));
32+
}
33+
34+
ArmeriaServerTelemetryBuilder(OpenTelemetry openTelemetry) {
35+
builder = ArmeriaInstrumenterBuilderFactory.getServerBuilder(openTelemetry);
36+
}
37+
38+
/** Sets the status extractor for server spans. */
39+
@CanIgnoreReturnValue
40+
public ArmeriaServerTelemetryBuilder setStatusExtractor(
41+
Function<
42+
SpanStatusExtractor<? super ServiceRequestContext, ? super RequestLog>,
43+
? extends SpanStatusExtractor<? super ServiceRequestContext, ? super RequestLog>>
44+
statusExtractor) {
45+
builder.setStatusExtractor(statusExtractor);
46+
return this;
47+
}
48+
49+
/**
50+
* Adds an extra {@link AttributesExtractor} to invoke to set attributes to instrumented items.
51+
* The {@link AttributesExtractor} will be executed after all default extractors.
52+
*/
53+
@CanIgnoreReturnValue
54+
public ArmeriaServerTelemetryBuilder addAttributesExtractor(
55+
AttributesExtractor<? super ServiceRequestContext, ? super RequestLog> attributesExtractor) {
56+
builder.addAttributesExtractor(attributesExtractor);
57+
return this;
58+
}
59+
60+
/**
61+
* Configures the HTTP server request headers that will be captured as span attributes.
62+
*
63+
* @param requestHeaders A list of HTTP header names.
64+
*/
65+
@CanIgnoreReturnValue
66+
public ArmeriaServerTelemetryBuilder setCapturedRequestHeaders(List<String> requestHeaders) {
67+
builder.setCapturedRequestHeaders(requestHeaders);
68+
return this;
69+
}
70+
71+
/**
72+
* Configures the HTTP server response headers that will be captured as span attributes.
73+
*
74+
* @param responseHeaders A list of HTTP header names.
75+
*/
76+
@CanIgnoreReturnValue
77+
public ArmeriaServerTelemetryBuilder setCapturedResponseHeaders(List<String> responseHeaders) {
78+
builder.setCapturedResponseHeaders(responseHeaders);
79+
return this;
80+
}
81+
82+
/**
83+
* Configures the instrumentation to recognize an alternative set of HTTP request methods.
84+
*
85+
* <p>By default, this instrumentation defines "known" methods as the ones listed in <a
86+
* href="https://www.rfc-editor.org/rfc/rfc9110.html#name-methods">RFC9110</a> and the PATCH
87+
* method defined in <a href="https://www.rfc-editor.org/rfc/rfc5789.html">RFC5789</a>.
88+
*
89+
* <p>Note: calling this method <b>overrides</b> the default known method sets completely; it does
90+
* not supplement it.
91+
*
92+
* @param knownMethods A set of recognized HTTP request methods.
93+
* @see HttpServerAttributesExtractorBuilder#setKnownMethods(Set)
94+
*/
95+
@CanIgnoreReturnValue
96+
public ArmeriaServerTelemetryBuilder setKnownMethods(Set<String> knownMethods) {
97+
builder.setKnownMethods(knownMethods);
98+
return this;
99+
}
100+
101+
/** Sets custom server {@link SpanNameExtractor} via transform function. */
102+
@CanIgnoreReturnValue
103+
public ArmeriaServerTelemetryBuilder setSpanNameExtractor(
104+
Function<
105+
SpanNameExtractor<? super ServiceRequestContext>,
106+
? extends SpanNameExtractor<? super ServiceRequestContext>>
107+
serverSpanNameExtractor) {
108+
builder.setSpanNameExtractor(serverSpanNameExtractor);
109+
return this;
110+
}
111+
112+
public ArmeriaServerTelemetry build() {
113+
return new ArmeriaServerTelemetry(builder.build());
114+
}
115+
}

0 commit comments

Comments
 (0)