Search code examples
traceopencensus

opencensus - explicit context management


I am implementing an opencensus tracing in my (asynchronous) JVM app.

However I don't understand how is the context passed. Sometimes it seems to work fine, sometimes traces from different requests appear nested for no reason.

I also have this warning appearing in the logs along with a stacktrace: SEVERE: Context was not attached when detaching

How do I explicitly create a root span, and how can I explicitly pass a parent/context to the child spans?


Solution

  • In OpenCensus we have a concept of context independent of the "Span" or "Tags". It represents a Map that is propagated with the request (it is implemented as a thread-local so in sync calls automatically gets propagated). For callbacks/async calls just for propagation (we are using io.grpc.Context as the implementation of the context) use the wrap functions defined here https://github.com/grpc/grpc-java/blob/master/context/src/main/java/io/grpc/Context.java#L589. This will ensure just the context propagation, so entries in the context map will be propagated between different threads.

    If you want to start a Span in one thread and end it in a different thread, use the withSpan methods from the tracer https://www.javadoc.io/doc/io.opencensus/opencensus-api/0.17.0 :

    class MyClass {
      private static Tracer tracer = Tracing.getTracer();
      void handleRequest(Executor executor) {
        Span span = tracer.spanBuilder("MyRunnableSpan").startSpan();
        // do some work before scheduling the async
        executor.execute(Context.wrap(tracer.withSpan(span, new Runnable() {
          @Override      
          public void run() {
            try {
              sendResult();
            } finally {
              span.end();
            }
          }
        })));
      }
    }
    

    A bit more information about this here https://github.com/census-instrumentation/opencensus-specs/blob/master/trace/Span.md#span-creation