Access Log doesn't print Otel MDC (traceId, etc) #43570
Description
Describe the bug
I've installed quarkus-opentelemetry
extension just as in the guide, however I notice that the Otel MDC key (traceId, etc) is null for access logs. This happens for both standard Vertx and Mutiny variant, even though the standard log can show traceId just fine.
Using JAX-RS the access log working correctly.
Expected behavior
The access log should print Otel MDC key for Vertx Web Router endpoint, just like JAX-RS.
2024-09-28 00:47:05,946 INFO traceId=0af7651916cd43dd8448eb211c80319c, parentId=b7ad6b7169203331, spanId=47bc95d506a4d8e7, sampled=true Hello from Quarkus REST
2024-09-28 00:47:05,947 INFO traceId=0af7651916cd43dd8448eb211c80319c, parentId=b7ad6b7169203331, spanId=47bc95d506a4d8e7, sampled=true "GET /hello HTTP/1.1 traceId=0af7651916cd43dd8448eb211c80319c spanId=47bc95d506a4d8e7"
Actual behavior
Using the following properties:
quarkus.log.console.format=%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p traceId=%X{traceId}, parentId=%X{parentId}, spanId=%X{spanId}, sampled=%X{sampled} %s%e%n
quarkus.http.access-log.enabled=true
quarkus.http.access-log.pattern="%r traceId=%{X,traceId} spanId=%{X,spanId}"
quarkus.otel.traces.exporter=none
quarkus.otel.metrics.exporter=none
Standard Vertx
I have defined the following routes:
@ApplicationScoped
public class Routes {
@Inject
Vertx vertx;
@Inject
WebClient client;
public Handler<RoutingContext> handle(String msg) {
return ctx -> {
Log.info(msg);
ctx.response().headers().set(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN);
ctx.end(msg);
};
}
public void sleep(RoutingContext ctx) {
vertx.setTimer(1, v -> ctx.next());
}
public void init(@Observes Router router) {
router.get("/message")
.handler(handle("Message from Vertx"));
router.get("/delayed-message")
.handler(this::sleep)
.handler(handle("Delayed message from Vertx"));
router.get("/pokemon")
.handler(this::sleep)
.handler(ctx -> {
Log.info("Vertx Pokemon");
client.getAbs("https://pokeapi.co/api/v2/ability/1")
.send().onComplete(response -> {
ctx.response().headers().set(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);
ctx.end(response.body());
}, ctx::fail);
});
}
}
Accessing each routes, produce logs:
2024-09-28 00:47:09,749 INFO traceId=fb2e476334dc126a75164d893dca60a0, parentId=, spanId=1221c0a2ee69340a, sampled=true Message from Vertx
2024-09-28 00:47:09,751 INFO traceId=, parentId=, spanId=, sampled= "GET /message HTTP/1.1 traceId=- spanId=-"
2024-09-28 00:47:12,496 INFO traceId=4a0e0d719cd3ada1a25b80a57d51156b, parentId=, spanId=44122ab6d3c23193, sampled=true Delayed message from Vertx
2024-09-28 00:47:12,497 INFO traceId=, parentId=, spanId=, sampled= "GET /delayed-message HTTP/1.1 traceId=- spanId=-"
2024-09-28 00:47:26,807 INFO traceId=f3b88d6586cb1e9c696373a54284ab64, parentId=, spanId=94e34c7a5db63401, sampled=true Vertx Pokemon
2024-09-28 00:47:28,335 INFO traceId=, parentId=, spanId=, sampled= "GET /pokemon HTTP/1.1 traceId=- spanId=-"
The logging from the code works fine, but none of the access logs works
Vertx Mutiny Variant
@ApplicationScoped
public class MutinyRoutes {
@Inject
WebClient client;
public Consumer<RoutingContext> handle(String msg) {
return ctx -> {
Log.info(msg);
ctx.response().headers().set(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN);
ctx.endAndForget(msg);
};
}
public void sleep(RoutingContext ctx) {
Uni.createFrom().voidItem()
.onItem().delayIt().by(Duration.ofMillis(1))
.subscribe().with(v -> ctx.next());
}
public void init(@Observes Router router) {
router.get("/mutiny/message")
.handler(handle("Message from Mutiny Vertx"));
router.get("/mutiny/delayed-message").handler(this::sleep).handler(handle("Delayed message from Mutiny Vertx"));
router.get("/mutiny/pokemon")
.handler(this::sleep)
.handler(ctx -> {
Log.info("Mutiny Vertx Pokemon");
client.getAbs("https://pokeapi.co/api/v2/ability/1")
.send()
.subscribe().with(response -> {
ctx.response().headers().set(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);
ctx.endAndForget(response.body());
}, ctx::fail);
});
}
}
The code is basically the same with standard Vertx, but accessing each endpoints gives me the following result:
2024-09-28 01:22:37,677 INFO traceId=9b8d5773720ed39f5009c9e3270edf9f, parentId=, spanId=8c4b6c4b1f9c60c2, sampled=true Message from Mutiny Vertx
2024-09-28 01:22:37,679 INFO traceId=, parentId=, spanId=, sampled= "GET /mutiny/message HTTP/1.1 traceId=- spanId=-"
2024-09-28 01:22:42,977 INFO traceId=c39dcb22cd3408670b965e8fbf917cb6, parentId=, spanId=7e603a6a1d177b3d, sampled=true Delayed message from Mutiny Vertx
2024-09-28 01:22:42,978 INFO traceId=c39dcb22cd3408670b965e8fbf917cb6, parentId=, spanId=7e603a6a1d177b3d, sampled=true "GET /mutiny/delayed-message HTTP/1.1 traceId=c39dcb22cd3408670b965e8fbf917cb6 spanId=7e603a6a1d177b3d"
2024-09-28 01:22:45,582 INFO traceId=de4c61216c8f0ea56cdee36c21b9bf30, parentId=, spanId=5a68e3bc3466cca3, sampled=true Mutiny Vertx Pokemon
2024-09-28 01:22:45,659 INFO traceId=, parentId=, spanId=, sampled= "GET /mutiny/pokemon HTTP/1.1 traceId=- spanId=-"
Notes that for the /delayed-message
endpoint both standard log and access log are displaying Otel MDC correctly, seems like delaying the execution is working somehow. However the /pokemon
which is also using delay
doesn't print any Otel MDC in the access log.
How to Reproduce?
I made a small project to reproduce this issue:
https://github.com/hendratommy/vertx-otel-accesslog-issue
Output of uname -a
or ver
arwin MacBook-Pro.local 23.6.0 Darwin Kernel Version 23.6.0: Mon Jul 29 21:13:00 PDT 2024; root:xnu-10063.141.2~1/RELEASE_X86_64 x86_64
Output of java -version
openjdk version "21.0.4" 2024-07-16 LTS OpenJDK Runtime Environment Temurin-21.0.4+7 (build 21.0.4+7-LTS) OpenJDK 64-Bit Server VM Temurin-21.0.4+7 (build 21.0.4+7-LTS, mixed mode)
Quarkus version or git rev
3.15.1
Build tool (ie. output of mvnw --version
or gradlew --version
)
ApacheMaven 3.9.8 (36645f6c9b5079805ea5009217e36f2cffd34256)
Additional information
No response
Metadata
Assignees
Labels
Type
Projects
Status
In Progress