Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion backend/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,19 @@ dependencies {
implementation(mn.jackson.databind)
implementation(mn.jackson.datatype.jsr310)

// Distributed tracing (OpenTelemetry). Spans/export are only active when
// OTEL_TRACES_EXPORTER=otlp is set (prod/Docker) — see application.yml.
implementation(mn.micronaut.tracing.opentelemetry.http)
implementation(mn.micronaut.tracing.opentelemetry.jdbc)
implementation(libs.opentelemetry.exporter.otlp)

// Structured JSON logging for Grafana Loki + trace/log correlation.
// logstash encoder renders JSON; the OTel MDC appender injects trace_id/span_id.
implementation(libs.logstash.logback.encoder)
implementation(libs.opentelemetry.logback.mdc)
// Enables the <if>/<then>/<else> conditional in logback.xml.
runtimeOnly(libs.janino)

testImplementation(mn.micronaut.test.rest.assured)
testImplementation(mn.junit.jupiter.api)
testImplementation(mn.junit.jupiter.params)
Expand Down Expand Up @@ -76,7 +89,9 @@ micronaut {
optimizeClassLoading = true
deduceEnvironment = true
optimizeNetty = true
replaceLogbackXml = true
// Keep logback.xml parsed at runtime so the env-driven JSON/plain switch
// and ${...} substitutions work in the optimized (Docker/prod) jar.
replaceLogbackXml = false
}
}

Expand Down
23 changes: 23 additions & 0 deletions backend/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,29 @@ jpa:
auto: update
show_sql: false

# OpenTelemetry — tracing is disabled unless OTEL_TRACES_EXPORTER=otlp is set
# (do this in the Docker/prod container). Metrics stay on Prometheus/Micrometer.
otel:
service:
name: ${OTEL_SERVICE_NAME:otis}
traces:
exporter: ${OTEL_TRACES_EXPORTER:none}
metrics:
exporter: none
logs:
exporter: none
exporter:
otlp:
protocol: grpc
endpoint: ${OTEL_EXPORTER_OTLP_ENDPOINT:`http://localhost:4317`}
exclusions:
- /health
- /health/.*
- /prometheus
- /swagger
- /swagger/.*
- /swagger-ui/.*

# OpenAPI
router:
static-resources:
Expand Down
34 changes: 29 additions & 5 deletions backend/src/main/resources/logback.xml
Original file line number Diff line number Diff line change
@@ -1,10 +1,34 @@
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
<property name="LOG_JSON" value="${LOG_JSON:-false}"/>

<if condition='"true".equalsIgnoreCase(property("LOG_JSON"))'>
<then>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="net.logstash.logback.encoder.LogstashEncoder">
<fieldNames>
<timestamp>timestamp</timestamp>
<message>message</message>
<logger>logger</logger>
<thread>thread</thread>
<level>level</level>
</fieldNames>
</encoder>
</appender>
</then>
<else>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
</else>
</if>

<appender name="OTEL" class="io.opentelemetry.instrumentation.logback.mdc.v1_0.OpenTelemetryAppender">
<appender-ref ref="STDOUT"/>
</appender>

<root level="INFO">
<appender-ref ref="STDOUT" />
<appender-ref ref="OTEL"/>
</root>
</configuration>
11 changes: 11 additions & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ dependencyResolutionManagement {
version("jackson", "2.22.0")
version("jakarta-annotation", "3.0.0")

version("logstash-logback-encoder", "8.1")
version("opentelemetry-instrumentation-alpha", "2.20.1-alpha")
version("janino", "3.1.12")

library(
"jetbrains.annotations",
"org.jetbrains",
Expand All @@ -39,6 +43,13 @@ dependencyResolutionManagement {
library("jackson-databind-nullable", "org.openapitools", "jackson-databind-nullable").version("0.2.10")
library("jakarta-annotation-api", "jakarta.annotation", "jakarta.annotation-api").versionRef("jakarta-annotation")

// Observability — JSON logging + OpenTelemetry (see backend/build.gradle.kts).
// Version managed by the Micronaut platform BOM (opentelemetry-bom).
library("opentelemetry-exporter-otlp", "io.opentelemetry", "opentelemetry-exporter-otlp").withoutVersion()
library("logstash-logback-encoder", "net.logstash.logback", "logstash-logback-encoder").versionRef("logstash-logback-encoder")
library("opentelemetry-logback-mdc", "io.opentelemetry.instrumentation", "opentelemetry-logback-mdc-1.0").versionRef("opentelemetry-instrumentation-alpha")
library("janino", "org.codehaus.janino", "janino").versionRef("janino")


plugin("micronaut.application", "io.micronaut.application").versionRef("micronaut")
plugin("micronaut.aot", "io.micronaut.aot").versionRef("micronaut")
Expand Down