-
Notifications
You must be signed in to change notification settings - Fork 2.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
OpenTelemetry support for Panache #40326
Comments
/cc @FroMage (panache), @brunobat (opentelemetry), @loicmathieu (panache), @radcortez (opentelemetry) |
@tarric1 this will soon be natif to MongoDB with Panache, see #40191 There also exist an instrumentation for JDBC: https://quarkus.io/guides/opentelemetry#jdbc So there is everything needed to instrument Panache method. |
@loicmathieu thanks for your feedback but the problem with #40191 (that is my 1st idea) is that you cannot set the right parent span because it is a listener and it hasn't che context. |
Panache is a utility lib, pretty much like Mutiny is and we don't instrument it with OTel. |
Hello @brunobat, thanks for your feedback! For me it's ok to instrument the client or the driver, my problem is that currently I see a detached span when I use the following solution: package io.tarric1.quickndirty;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import com.mongodb.MongoClientSettings;.CommandFailedEvent;
import com.mongodb.event.CommandListener;
import com.mongodb.event.CommandStartedEvent;
import com.mongodb.event.CommandSucceededEvent;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.context.Context;
import io.quarkus.arc.lookup.LookupIfProperty;
import io.quarkus.logging.Log;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.context.RequestScoped;
import jakarta.inject.Inject;
@ApplicationScoped
@LookupIfProperty(name = "mongo-tracing.enabled", stringValue = "true")
public class MongoDbTracing implements CommandListener {
private Tracer tracer;
private final Map<Integer, Span> requestMap;
@Inject
MongoDbTracing(Tracer tracer) {
this.tracer = tracer;
requestMap = new ConcurrentHashMap<>();
}
@Override
public void commandStarted(CommandStartedEvent event) {
Log.debug("COMMAND STARTED");
String name = null;
Span span = tracer.spanBuilder(name)
.setParent(Context.current().with(Span.current()))
.setSpanKind(SpanKind.CLIENT)
.setAttribute("db.system", "mongodb")
.setAttribute("db.name", event.getDatabaseName())
.setAttribute("db.operation", event.getCommandName())
.setAttribute("db.mongodb.connection-id", event.getConnectionDescription().getConnectionId().toString())
.setAttribute("db.mongodb.server-address", event.getConnectionDescription().getServerAddress().toString())
.setAttribute("db.mongodb.server-type", event.getConnectionDescription().getServerType().toString())
.setAttribute("db.mongodb.request-id", event.getRequestId())
.setAttribute("db.mongodb.operation-id", event.getOperationId())
.setAttribute("db.mongodb.command", event.getCommand().toJson())
.startSpan();
requestMap.put(event.getRequestId(), span);
}
@Override
public void commandSucceeded(CommandSucceededEvent event) {
Log.debug("COMMAND SUCCEEDED");
Span span = requestMap.get(event.getRequestId());
if (span != null) {
span.setAttribute("db.mongodb.elapsed-time", event.getElapsedTime(TimeUnit.MILLISECONDS))
.setAttribute("db.mongodb.response", event.getResponse().toJson())
.end();
}
}
@Override
public void commandFailed(CommandFailedEvent event) {
Log.debug("COMMAND FAILED");
Span span = requestMap.get(event.getRequestId());
if (span != null) {
span.setAttribute("db.mongodb.elapsed-time", event.getElapsedTime(TimeUnit.MILLISECONDS))
.setAttribute("db.mongodb.throwable", event.getThrowable().toString())
.end();
}
}
} Is there another way that I don't know or is there a bug in my implementation? To avoid this problem, currently I'm using the following solution: I use Thanks a lot! |
You are using the low level API to create spans. You need to start a scope, make the span current and make sure it is ended in a finally block. |
I'm sorry @brunobat but I didn't understand. The command listener is executed on a thread which doesn't belong to the same otel context that is generated (automatically) when a REST invocation is done to my controller (that invokes my Mongo repository), so, in my opinion, with this approch there is no chance to include the span that traces the operations on Mongo to the parent span. I tried also with this: and the result is the same I see a detached span for Mongo operations. What I'm doing wrong? |
Description
Quarkus has the ambition of being a cloud native application framework, so full observability support is a must. From this perspective, I believe that a serious lack of Quarkus is the support for OpenTelemetry for accesses made to the DB (SQL and NoSQL, reactive and not) via Panache.
Implementation ideas
My ideas are related to my use case: access to MongoDB using reactive repository pattern.
1st: MongoDB command listener
The problem with this solution is that I was unable to retrieve the parent span.
2nd: Interceptor for repository class
The problem with this solution (that is a draft) is that I was unable to retrieve the statement.
The following annotation is used on repository class to intercept invocations:
The interceptor:
The text was updated successfully, but these errors were encountered: