Skip to content

Commit b67d3c8

Browse files
committed
Support OpenTelemetry to trace flow executions
Hands down one of the coolest things I've ever done
1 parent a14fb3a commit b67d3c8

File tree

51 files changed

+4502
-121
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+4502
-121
lines changed

api/build.gradle.kts

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ dependencies {
1515
implementation(ktor.server.auth.jwt)
1616
api(libraries.bson.kotlinx)
1717
api(database.mongodb)
18+
api(monitoring.opentelemetry.api)
19+
api(monitoring.opentelemetry.context)
1820

1921
implementation(tests.junit.api)
2022
}

api/src/main/kotlin/me/snoty/backend/config/Config.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package me.snoty.backend.config
33
data class Config(
44
val mongodb: MongoConfig,
55
val port: Short = 8080,
6-
val monitoringPort: Short = 9090,
6+
val monitoringPort: Short = 9000,
77
val publicHost: String,
88
val environment: Environment,
99
val authentication: OidcConfig,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package me.snoty.backend.observability
2+
3+
import io.opentelemetry.api.common.AttributeKey
4+
5+
// https://github.com/open-telemetry/semantic-conventions/pull/731
6+
val USER_ID = AttributeKey.stringKey("user.id")
7+
val JOB_ID = AttributeKey.stringKey("job.id")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package me.snoty.backend.observability
2+
3+
import io.opentelemetry.api.OpenTelemetry
4+
import io.opentelemetry.api.common.AttributeKey
5+
import io.opentelemetry.api.trace.Span
6+
import io.opentelemetry.api.trace.SpanBuilder
7+
import io.opentelemetry.api.trace.StatusCode
8+
import io.opentelemetry.api.trace.Tracer
9+
import io.opentelemetry.api.trace.TracerProvider
10+
import io.opentelemetry.context.Context
11+
import org.bson.Document
12+
import java.util.UUID
13+
import kotlin.reflect.KClass
14+
15+
fun OpenTelemetry.getTracer(clazz: KClass<*>): Tracer
16+
= getTracer(clazz.java.`package`.specificationTitle)
17+
18+
fun TracerProvider.getTracer(clazz: KClass<*>): Tracer
19+
= get(clazz.java.`package`.specificationTitle)
20+
21+
context(Tracer)
22+
fun Span.subspan(name: String, builder: SpanBuilder.() -> Unit): Span
23+
= this@Tracer.spanBuilder(name)
24+
.also(builder)
25+
.apply {
26+
setParent(Context.current().with(this@subspan))
27+
}
28+
.startSpan()
29+
30+
31+
fun SpanBuilder.setAttribute(key: String, value: Document) = this.setAttribute(key, value.toJson())
32+
fun SpanBuilder.setAttribute(key: AttributeKey<String>, value: UUID) = this.setAttribute(key, value.toString())
33+
34+
fun Span.setException(e: Throwable) {
35+
this.setStatus(StatusCode.ERROR)
36+
this.recordException(e)
37+
}

build.gradle.kts

+9
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ val isDevelopment: Boolean = project.findProperty("me.snoty.development")?.toStr
2626
allprojects {
2727
repositories {
2828
mavenCentral()
29+
maven("https://maven.simulatan.me/releases")
2930
}
3031

3132
tasks.withType<KotlinCompile>().configureEach {
@@ -85,6 +86,7 @@ testing {
8586
implementation(tests.testcontainers.junit)
8687
implementation(tests.testcontainers.keycloak)
8788
implementation(tests.testcontainers.mongodb)
89+
implementation(monitoring.opentelemetry.testing)
8890
implementation(devSourceSet.output)
8991

9092
runtimeOnly(tests.junit.engine)
@@ -140,6 +142,11 @@ dependencies {
140142
implementation(monitoring.ktor.opentelemetry)
141143
implementation(monitoring.ktor.server.metricsMicrometer)
142144
implementation(monitoring.micrometer.prometheus)
145+
implementation(monitoring.opentelemetry.api)
146+
implementation(monitoring.opentelemetry.context)
147+
implementation(monitoring.opentelemetry.semconv)
148+
implementation(monitoring.opentelemetry.kotlin)
149+
implementation(monitoring.opentelemetry.logback)
143150

144151
// database
145152
implementation(database.mongodb)
@@ -164,6 +171,8 @@ dependencies {
164171

165172
// dev
166173
devImplementation(dev.keycloak.adminClient)
174+
devImplementation(monitoring.opentelemetry.sdk)
175+
devImplementation(monitoring.opentelemetry.exporter.otlp)
167176

168177
moduleImplementation(projects.integrations.api)
169178
// depend on all integrations by default

infra/monitoring/.env

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
COMPOSE_PROJECT_NAME=snoty

0 commit comments

Comments
 (0)