Skip to content

Commit 386ac17

Browse files
committed
add http builder for ktor
1 parent 81fb2d7 commit 386ac17

File tree

4 files changed

+50
-94
lines changed

4 files changed

+50
-94
lines changed

instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/builder/internal/DefaultHttpServerTelemetryBuilder.java

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,17 @@ public Instrumenter<REQUEST, RESPONSE> instrumenter() {
147147
public Instrumenter<REQUEST, RESPONSE> instrumenter(
148148
Consumer<InstrumenterBuilder<REQUEST, RESPONSE>> instrumenterBuilderConsumer) {
149149

150+
InstrumenterBuilder<REQUEST, RESPONSE> builder = instrumenterBuilder(
151+
instrumenterBuilderConsumer);
152+
153+
if (headerSetter.isPresent()) {
154+
return builder.buildServerInstrumenter(headerSetter.get());
155+
}
156+
return builder.buildInstrumenter(SpanKindExtractor.alwaysServer());
157+
}
158+
159+
public InstrumenterBuilder<REQUEST, RESPONSE> instrumenterBuilder(
160+
Consumer<InstrumenterBuilder<REQUEST, RESPONSE>> instrumenterBuilderConsumer) {
150161
SpanNameExtractor<? super REQUEST> spanNameExtractor =
151162
spanNameExtractorTransformer.apply(httpSpanNameExtractorBuilder.build());
152163

@@ -164,12 +175,8 @@ public Instrumenter<REQUEST, RESPONSE> instrumenter(
164175
.addOperationMetrics(HttpServerExperimentalMetrics.get());
165176
}
166177

167-
instrumenterBuilderConsumer.accept(builder);
168-
169-
if (headerSetter.isPresent()) {
170-
return builder.buildServerInstrumenter(headerSetter.get());
171-
}
172-
return builder.buildInstrumenter(SpanKindExtractor.alwaysServer());
178+
instrumenterBuilderConsumer.accept(builder);
179+
return builder;
173180
}
174181

175182
public OpenTelemetry getOpenTelemetry() {

instrumentation/ktor/ktor-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/ktor/v2_0/ServerInstrumentation.java

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
import io.ktor.server.application.Application;
1212
import io.ktor.server.application.ApplicationPluginKt;
1313
import io.opentelemetry.api.GlobalOpenTelemetry;
14-
import io.opentelemetry.api.OpenTelemetry;
14+
import io.opentelemetry.instrumentation.api.incubator.builder.internal.HttpServerInstrumenterBuilder;
1515
import io.opentelemetry.instrumentation.ktor.v2_0.server.KtorServerTracing;
16-
import io.opentelemetry.javaagent.bootstrap.internal.AgentCommonConfig;
16+
import io.opentelemetry.javaagent.bootstrap.internal.CommonConfig;
1717
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
1818
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
1919
import kotlin.Unit;
@@ -48,12 +48,8 @@ public static class SetupFunction
4848

4949
@Override
5050
public Unit invoke(KtorServerTracing.Configuration configuration) {
51-
OpenTelemetry openTelemetry = GlobalOpenTelemetry.get();
52-
configuration.setOpenTelemetry(openTelemetry);
53-
configuration.capturedRequestHeaders(AgentCommonConfig.get().getServerRequestHeaders());
54-
configuration.capturedResponseHeaders(AgentCommonConfig.get().getServerResponseHeaders());
55-
configuration.knownMethods(AgentCommonConfig.get().getKnownHttpRequestMethods());
56-
51+
configuration.setOpenTelemetry(GlobalOpenTelemetry.get());
52+
HttpServerInstrumenterBuilder.configure(CommonConfig.get(), configuration);
5753
return kotlin.Unit.INSTANCE;
5854
}
5955
}

instrumentation/ktor/ktor-2.0/library/src/main/kotlin/io/opentelemetry/instrumentation/ktor/v2_0/client/KtorClientTracingBuilder.kt

Lines changed: 18 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -11,27 +11,22 @@ import io.ktor.http.*
1111
import io.opentelemetry.api.OpenTelemetry
1212
import io.opentelemetry.api.common.AttributesBuilder
1313
import io.opentelemetry.context.Context
14-
import io.opentelemetry.instrumentation.api.incubator.semconv.http.HttpClientExperimentalMetrics
15-
import io.opentelemetry.instrumentation.api.incubator.semconv.http.HttpExperimentalAttributesExtractor
14+
import io.opentelemetry.instrumentation.api.incubator.builder.internal.DefaultHttpClientTelemetryBuilder
1615
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor
17-
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter
18-
import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor.alwaysClient
19-
import io.opentelemetry.instrumentation.api.semconv.http.HttpClientAttributesExtractor
20-
import io.opentelemetry.instrumentation.api.semconv.http.HttpClientMetrics
21-
import io.opentelemetry.instrumentation.api.semconv.http.HttpSpanNameExtractor
22-
import io.opentelemetry.instrumentation.api.semconv.http.HttpSpanStatusExtractor
2316
import io.opentelemetry.instrumentation.ktor.v2_0.InstrumentationProperties.INSTRUMENTATION_NAME
17+
import java.util.*
2418

2519
class KtorClientTracingBuilder {
2620

27-
private var openTelemetry: OpenTelemetry? = null
28-
private val additionalExtractors = mutableListOf<AttributesExtractor<in HttpRequestData, in HttpResponse>>()
29-
private val httpAttributesExtractorBuilder = HttpClientAttributesExtractor.builder(KtorHttpClientAttributesGetter)
30-
private val httpSpanNameExtractorBuilder = HttpSpanNameExtractor.builder(KtorHttpClientAttributesGetter)
31-
private var emitExperimentalHttpClientMetrics = false
21+
private lateinit var builder: DefaultHttpClientTelemetryBuilder<HttpRequestData, HttpResponse>
3222

3323
fun setOpenTelemetry(openTelemetry: OpenTelemetry) {
34-
this.openTelemetry = openTelemetry
24+
this.builder = DefaultHttpClientTelemetryBuilder(
25+
INSTRUMENTATION_NAME,
26+
openTelemetry,
27+
KtorHttpClientAttributesGetter,
28+
Optional.empty()
29+
)
3530
}
3631

3732
@Deprecated(
@@ -49,7 +44,7 @@ class KtorClientTracingBuilder {
4944
fun capturedRequestHeaders(vararg headers: String) = capturedRequestHeaders(headers.asIterable())
5045

5146
fun capturedRequestHeaders(headers: Iterable<String>) {
52-
httpAttributesExtractorBuilder.setCapturedRequestHeaders(headers.toList())
47+
builder.setCapturedRequestHeaders(headers.toList())
5348
}
5449

5550
@Deprecated(
@@ -67,7 +62,7 @@ class KtorClientTracingBuilder {
6762
fun capturedResponseHeaders(vararg headers: String) = capturedResponseHeaders(headers.asIterable())
6863

6964
fun capturedResponseHeaders(headers: Iterable<String>) {
70-
httpAttributesExtractorBuilder.setCapturedResponseHeaders(headers.toList())
65+
builder.setCapturedResponseHeaders(headers.toList())
7166
}
7267

7368
@Deprecated(
@@ -84,10 +79,7 @@ class KtorClientTracingBuilder {
8479
fun knownMethods(methods: Iterable<HttpMethod>) = knownMethods(methods.map { it.value })
8580

8681
fun knownMethods(methods: Iterable<String>) {
87-
methods.toSet().apply {
88-
httpAttributesExtractorBuilder.setKnownMethods(this)
89-
httpSpanNameExtractorBuilder.setKnownMethods(this)
90-
}
82+
builder.setKnownMethods(methods.toSet())
9183
}
9284

9385
@Deprecated("Please use method `attributeExtractor`")
@@ -105,7 +97,7 @@ class KtorClientTracingBuilder {
10597

10698
fun attributeExtractor(extractorBuilder: ExtractorBuilder.() -> Unit = {}) {
10799
val builder = ExtractorBuilder().apply(extractorBuilder).build()
108-
additionalExtractors.add(
100+
this.builder.addAttributeExtractor(
109101
object : AttributesExtractor<HttpRequestData, HttpResponse> {
110102
override fun onStart(attributes: AttributesBuilder, parentContext: Context, request: HttpRequestData) {
111103
builder.onStart(OnStartData(attributes, parentContext, request))
@@ -164,35 +156,11 @@ class KtorClientTracingBuilder {
164156
}
165157

166158
fun emitExperimentalHttpClientMetrics() {
167-
emitExperimentalHttpClientMetrics = true
159+
builder.setEmitExperimentalHttpClientMetrics(true)
168160
}
169161

170-
internal fun build(): KtorClientTracing {
171-
val initializedOpenTelemetry = openTelemetry
172-
?: throw IllegalArgumentException("OpenTelemetry must be set")
173-
174-
val instrumenterBuilder = Instrumenter.builder<HttpRequestData, HttpResponse>(
175-
initializedOpenTelemetry,
176-
INSTRUMENTATION_NAME,
177-
httpSpanNameExtractorBuilder.build()
178-
)
179-
.setSpanStatusExtractor(HttpSpanStatusExtractor.create(KtorHttpClientAttributesGetter))
180-
.addAttributesExtractor(httpAttributesExtractorBuilder.build())
181-
.addAttributesExtractors(additionalExtractors)
182-
.addOperationMetrics(HttpClientMetrics.get())
183-
184-
if (emitExperimentalHttpClientMetrics) {
185-
instrumenterBuilder
186-
.addAttributesExtractor(HttpExperimentalAttributesExtractor.create(KtorHttpClientAttributesGetter))
187-
.addOperationMetrics(HttpClientExperimentalMetrics.get())
188-
}
189-
190-
val instrumenter = instrumenterBuilder
191-
.buildInstrumenter(alwaysClient())
192-
193-
return KtorClientTracing(
194-
instrumenter = instrumenter,
195-
propagators = initializedOpenTelemetry.propagators,
196-
)
197-
}
162+
internal fun build(): KtorClientTracing = KtorClientTracing(
163+
instrumenter = builder.instrumenter(),
164+
propagators = builder.openTelemetry.propagators,
165+
)
198166
}

instrumentation/ktor/ktor-2.0/library/src/main/kotlin/io/opentelemetry/instrumentation/ktor/v2_0/server/KtorServerTracing.kt

Lines changed: 15 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -17,35 +17,26 @@ import io.opentelemetry.api.common.AttributesBuilder
1717
import io.opentelemetry.api.trace.SpanKind
1818
import io.opentelemetry.context.Context
1919
import io.opentelemetry.extension.kotlin.asContextElement
20+
import io.opentelemetry.instrumentation.api.incubator.builder.internal.DefaultHttpServerTelemetryBuilder
2021
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor
2122
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter
2223
import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor
2324
import io.opentelemetry.instrumentation.api.instrumenter.SpanStatusBuilder
2425
import io.opentelemetry.instrumentation.api.instrumenter.SpanStatusExtractor
2526
import io.opentelemetry.instrumentation.api.internal.InstrumenterUtil
26-
import io.opentelemetry.instrumentation.api.semconv.http.HttpServerAttributesExtractor
27-
import io.opentelemetry.instrumentation.api.semconv.http.HttpServerMetrics
2827
import io.opentelemetry.instrumentation.api.semconv.http.HttpServerRoute
2928
import io.opentelemetry.instrumentation.api.semconv.http.HttpServerRouteSource
30-
import io.opentelemetry.instrumentation.api.semconv.http.HttpSpanNameExtractor
3129
import io.opentelemetry.instrumentation.api.semconv.http.HttpSpanStatusExtractor
3230
import io.opentelemetry.instrumentation.ktor.v2_0.InstrumentationProperties.INSTRUMENTATION_NAME
3331
import kotlinx.coroutines.withContext
32+
import java.util.*
3433

3534
class KtorServerTracing private constructor(
3635
private val instrumenter: Instrumenter<ApplicationRequest, ApplicationResponse>,
3736
) {
3837

3938
class Configuration {
40-
internal lateinit var openTelemetry: OpenTelemetry
41-
42-
internal val additionalExtractors = mutableListOf<AttributesExtractor<in ApplicationRequest, in ApplicationResponse>>()
43-
44-
internal val httpAttributesExtractorBuilder = HttpServerAttributesExtractor.builder(KtorHttpServerAttributesGetter.INSTANCE)
45-
46-
internal val httpSpanNameExtractorBuilder = HttpSpanNameExtractor.builder(KtorHttpServerAttributesGetter.INSTANCE)
47-
48-
internal val httpServerRouteBuilder = HttpServerRoute.builder(KtorHttpServerAttributesGetter.INSTANCE)
39+
internal lateinit var serverBuilder: DefaultHttpServerTelemetryBuilder<ApplicationRequest, ApplicationResponse>
4940

5041
internal var statusExtractor:
5142
(SpanStatusExtractor<ApplicationRequest, ApplicationResponse>) -> SpanStatusExtractor<in ApplicationRequest, in ApplicationResponse> = { a -> a }
@@ -54,7 +45,12 @@ class KtorServerTracing private constructor(
5445
(SpanKindExtractor<ApplicationRequest>) -> SpanKindExtractor<ApplicationRequest> = { a -> a }
5546

5647
fun setOpenTelemetry(openTelemetry: OpenTelemetry) {
57-
this.openTelemetry = openTelemetry
48+
this.serverBuilder = DefaultHttpServerTelemetryBuilder(
49+
INSTRUMENTATION_NAME,
50+
openTelemetry,
51+
KtorHttpServerAttributesGetter.INSTANCE,
52+
Optional.empty()
53+
)
5854
}
5955

6056
@Deprecated("Please use method `spanStatusExtractor`")
@@ -113,7 +109,7 @@ class KtorServerTracing private constructor(
113109

114110
fun attributeExtractor(extractorBuilder: ExtractorBuilder.() -> Unit = {}) {
115111
val builder = ExtractorBuilder().apply(extractorBuilder).build()
116-
additionalExtractors.add(
112+
serverBuilder.addAttributesExtractor(
117113
object : AttributesExtractor<ApplicationRequest, ApplicationResponse> {
118114
override fun onStart(attributes: AttributesBuilder, parentContext: Context, request: ApplicationRequest) {
119115
builder.onStart(OnStartData(attributes, parentContext, request))
@@ -168,7 +164,7 @@ class KtorServerTracing private constructor(
168164
fun capturedRequestHeaders(vararg headers: String) = capturedRequestHeaders(headers.asIterable())
169165

170166
fun capturedRequestHeaders(headers: Iterable<String>) {
171-
httpAttributesExtractorBuilder.setCapturedRequestHeaders(headers.toList())
167+
serverBuilder.setCapturedRequestHeaders(headers.toList())
172168
}
173169

174170
@Deprecated(
@@ -180,7 +176,7 @@ class KtorServerTracing private constructor(
180176
fun capturedResponseHeaders(vararg headers: String) = capturedResponseHeaders(headers.asIterable())
181177

182178
fun capturedResponseHeaders(headers: Iterable<String>) {
183-
httpAttributesExtractorBuilder.setCapturedResponseHeaders(headers.toList())
179+
serverBuilder.setCapturedResponseHeaders(headers.toList())
184180
}
185181

186182
@Deprecated(
@@ -198,13 +194,11 @@ class KtorServerTracing private constructor(
198194

199195
fun knownMethods(methods: Iterable<String>) {
200196
methods.toSet().apply {
201-
httpAttributesExtractorBuilder.setKnownMethods(this)
202-
httpSpanNameExtractorBuilder.setKnownMethods(this)
203-
httpServerRouteBuilder.setKnownMethods(this)
197+
serverBuilder.setKnownMethods(this)
204198
}
205199
}
206200

207-
internal fun isOpenTelemetryInitialized(): Boolean = this::openTelemetry.isInitialized
201+
internal fun isOpenTelemetryInitialized(): Boolean = this::serverBuilder.isInitialized
208202
}
209203

210204
private fun start(call: ApplicationCall): Context? {
@@ -234,19 +228,10 @@ class KtorServerTracing private constructor(
234228

235229
val httpAttributesGetter = KtorHttpServerAttributesGetter.INSTANCE
236230

237-
val instrumenterBuilder = Instrumenter.builder<ApplicationRequest, ApplicationResponse>(
238-
configuration.openTelemetry,
239-
INSTRUMENTATION_NAME,
240-
configuration.httpSpanNameExtractorBuilder.build()
241-
)
242-
243-
configuration.additionalExtractors.forEach { instrumenterBuilder.addAttributesExtractor(it) }
231+
val instrumenterBuilder = configuration.serverBuilder.instrumenterBuilder { }
244232

245233
with(instrumenterBuilder) {
246234
setSpanStatusExtractor(configuration.statusExtractor(HttpSpanStatusExtractor.create(httpAttributesGetter)))
247-
addAttributesExtractor(configuration.httpAttributesExtractorBuilder.build())
248-
addOperationMetrics(HttpServerMetrics.get())
249-
addContextCustomizer(configuration.httpServerRouteBuilder.build())
250235
}
251236

252237
val instrumenter = InstrumenterUtil.buildUpstreamInstrumenter(

0 commit comments

Comments
 (0)