Skip to content

Commit ed75537

Browse files
committed
Split ArmeriaTelemetry into client and server
1 parent 4af0dd5 commit ed75537

File tree

11 files changed

+579
-52
lines changed

11 files changed

+579
-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,130 @@
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+
}
31+
32+
ArmeriaClientTelemetryBuilder(OpenTelemetry openTelemetry) {
33+
builder = ArmeriaInstrumenterBuilderFactory.getClientBuilder(openTelemetry);
34+
}
35+
36+
/** Sets the status extractor for client spans. */
37+
@CanIgnoreReturnValue
38+
public ArmeriaClientTelemetryBuilder setStatusExtractor(
39+
Function<
40+
SpanStatusExtractor<? super ClientRequestContext, ? super RequestLog>,
41+
? extends SpanStatusExtractor<? super ClientRequestContext, ? super RequestLog>>
42+
statusExtractor) {
43+
builder.setStatusExtractor(statusExtractor);
44+
return this;
45+
}
46+
47+
/**
48+
* Adds an extra client-only {@link AttributesExtractor} to invoke to set attributes to
49+
* instrumented items. The {@link AttributesExtractor} will be executed after all default
50+
* extractors.
51+
*/
52+
@CanIgnoreReturnValue
53+
public ArmeriaClientTelemetryBuilder addAttributeExtractor(
54+
AttributesExtractor<? super ClientRequestContext, ? super RequestLog> attributesExtractor) {
55+
builder.addAttributeExtractor(attributesExtractor);
56+
return this;
57+
}
58+
59+
/**
60+
* Configures the HTTP client request headers that will be captured as span attributes.
61+
*
62+
* @param requestHeaders A list of HTTP header names.
63+
*/
64+
@CanIgnoreReturnValue
65+
public ArmeriaClientTelemetryBuilder setCapturedRequestHeaders(List<String> requestHeaders) {
66+
builder.setCapturedRequestHeaders(requestHeaders);
67+
return this;
68+
}
69+
70+
/**
71+
* Configures the HTTP client response headers that will be captured as span attributes.
72+
*
73+
* @param responseHeaders A list of HTTP header names.
74+
*/
75+
@CanIgnoreReturnValue
76+
public ArmeriaClientTelemetryBuilder setCapturedResponseHeaders(List<String> responseHeaders) {
77+
builder.setCapturedResponseHeaders(responseHeaders);
78+
return this;
79+
}
80+
81+
/**
82+
* Configures the instrumentation to recognize an alternative set of HTTP request methods.
83+
*
84+
* <p>By default, this instrumentation defines "known" methods as the ones listed in <a
85+
* href="https://www.rfc-editor.org/rfc/rfc9110.html#name-methods">RFC9110</a> and the PATCH
86+
* method defined in <a href="https://www.rfc-editor.org/rfc/rfc5789.html">RFC5789</a>.
87+
*
88+
* <p>Note: calling this method <b>overrides</b> the default known method sets completely; it does
89+
* not supplement it.
90+
*
91+
* @param knownMethods A set of recognized HTTP request methods.
92+
* @see HttpClientAttributesExtractorBuilder#setKnownMethods(Set)
93+
*/
94+
@CanIgnoreReturnValue
95+
public ArmeriaClientTelemetryBuilder setKnownMethods(Set<String> knownMethods) {
96+
builder.setKnownMethods(knownMethods);
97+
return this;
98+
}
99+
100+
/** Sets custom client {@link SpanNameExtractor} via transform function. */
101+
@CanIgnoreReturnValue
102+
public ArmeriaClientTelemetryBuilder setSpanNameExtractor(
103+
Function<
104+
SpanNameExtractor<? super ClientRequestContext>,
105+
? extends SpanNameExtractor<? super ClientRequestContext>>
106+
clientSpanNameExtractor) {
107+
builder.setSpanNameExtractor(clientSpanNameExtractor);
108+
return this;
109+
}
110+
111+
/**
112+
* Can be used via the unstable method {@link
113+
* Experimental#setClientPeerService(ArmeriaClientTelemetryBuilder, String)}.
114+
*/
115+
void setPeerService(String peerService) {
116+
builder.setPeerService(peerService);
117+
}
118+
119+
/**
120+
* Can be used via the unstable method {@link
121+
* Experimental#setEmitExperimentalHttpClientMetrics(ArmeriaClientTelemetryBuilder, boolean)}.
122+
*/
123+
void setEmitExperimentalHttpClientMetrics(boolean emitExperimentalHttpClientMetrics) {
124+
builder.setEmitExperimentalHttpClientMetrics(emitExperimentalHttpClientMetrics);
125+
}
126+
127+
public ArmeriaClientTelemetry build() {
128+
return new ArmeriaClientTelemetry(builder.build());
129+
}
130+
}
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,122 @@
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+
}
31+
32+
ArmeriaServerTelemetryBuilder(OpenTelemetry openTelemetry) {
33+
builder = ArmeriaInstrumenterBuilderFactory.getServerBuilder(openTelemetry);
34+
}
35+
36+
/** Sets the status extractor for server spans. */
37+
@CanIgnoreReturnValue
38+
public ArmeriaServerTelemetryBuilder setStatusExtractor(
39+
Function<
40+
SpanStatusExtractor<? super ServiceRequestContext, ? super RequestLog>,
41+
? extends SpanStatusExtractor<? super ServiceRequestContext, ? super RequestLog>>
42+
statusExtractor) {
43+
builder.setStatusExtractor(statusExtractor);
44+
return this;
45+
}
46+
47+
/**
48+
* Adds an extra server-only {@link AttributesExtractor} to invoke to set attributes to
49+
* instrumented items. The {@link AttributesExtractor} will be executed after all default
50+
* extractors.
51+
*/
52+
@CanIgnoreReturnValue
53+
public ArmeriaServerTelemetryBuilder addAttributeExtractor(
54+
AttributesExtractor<? super ServiceRequestContext, ? super RequestLog> attributesExtractor) {
55+
builder.addAttributesExtractor(attributesExtractor);
56+
return this;
57+
}
58+
59+
/**
60+
* Configures the HTTP server request headers that will be captured as span attributes.
61+
*
62+
* @param requestHeaders A list of HTTP header names.
63+
*/
64+
@CanIgnoreReturnValue
65+
public ArmeriaServerTelemetryBuilder setCapturedRequestHeaders(List<String> requestHeaders) {
66+
builder.setCapturedRequestHeaders(requestHeaders);
67+
return this;
68+
}
69+
70+
/**
71+
* Configures the HTTP server response headers that will be captured as span attributes.
72+
*
73+
* @param responseHeaders A list of HTTP header names.
74+
*/
75+
@CanIgnoreReturnValue
76+
public ArmeriaServerTelemetryBuilder setCapturedResponseHeaders(List<String> responseHeaders) {
77+
builder.setCapturedResponseHeaders(responseHeaders);
78+
return this;
79+
}
80+
81+
/**
82+
* Configures the instrumentation to recognize an alternative set of HTTP request methods.
83+
*
84+
* <p>By default, this instrumentation defines "known" methods as the ones listed in <a
85+
* href="https://www.rfc-editor.org/rfc/rfc9110.html#name-methods">RFC9110</a> and the PATCH
86+
* method defined in <a href="https://www.rfc-editor.org/rfc/rfc5789.html">RFC5789</a>.
87+
*
88+
* <p>Note: calling this method <b>overrides</b> the default known method sets completely; it does
89+
* not supplement it.
90+
*
91+
* @param knownMethods A set of recognized HTTP request methods.
92+
* @see HttpServerAttributesExtractorBuilder#setKnownMethods(Set)
93+
*/
94+
@CanIgnoreReturnValue
95+
public ArmeriaServerTelemetryBuilder setKnownMethods(Set<String> knownMethods) {
96+
builder.setKnownMethods(knownMethods);
97+
return this;
98+
}
99+
100+
/** Sets custom server {@link SpanNameExtractor} via transform function. */
101+
@CanIgnoreReturnValue
102+
public ArmeriaServerTelemetryBuilder setSpanNameExtractor(
103+
Function<
104+
SpanNameExtractor<? super ServiceRequestContext>,
105+
? extends SpanNameExtractor<? super ServiceRequestContext>>
106+
serverSpanNameExtractor) {
107+
builder.setSpanNameExtractor(serverSpanNameExtractor);
108+
return this;
109+
}
110+
111+
/**
112+
* Can be used via the unstable method {@link
113+
* Experimental#setEmitExperimentalHttpServerMetrics(ArmeriaServerTelemetryBuilder, boolean)}.
114+
*/
115+
void setEmitExperimentalHttpServerMetrics(boolean emitExperimentalHttpServerMetrics) {
116+
builder.setEmitExperimentalHttpServerMetrics(emitExperimentalHttpServerMetrics);
117+
}
118+
119+
public ArmeriaServerTelemetry build() {
120+
return new ArmeriaServerTelemetry(builder.build());
121+
}
122+
}

0 commit comments

Comments
 (0)