open-telemetry / open-telemetry/opentelemetry-java

Able to see traces with Java, but no trace with Scala (same code)

Open
#7,333 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Bug
Dominant language
Java
Stars
2.5k
Forks
1k
Avg merge
3d 17h
Merged PRs (30d)
58

Description

Describe the bug
A clear and concise description of what the bug is.

=> I am able to send traces with below Java code, I can even see the traces in our tracing back-ends.

However, what seems to be the same code (can be discussed) in Scala will yield no trace at all.

Both are using the same OpenTelemetry API, SDK and exporter OTLP

Steps to reproduce
If possible, provide a recipe for reproducing the error.

Here is the java code.
I hope it is as minimal and as descriptive as possible.

import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.trace.*;
import io.opentelemetry.context.Context;
import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.trace.SdkTracerProvider;
import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor;

public class AAA {

    public String call(String traceParent) throws Exception {
        //String traceParent = "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"; //for testing

        OtlpGrpcSpanExporter spanExporter = OtlpGrpcSpanExporter.builder()
                .setEndpoint("https://tempo-prod-04-prod-us-east-0.grafana.net:443")
                .addHeader("Authorization", "Basic ODEwNzcxOmdsY19leUp2SWpvaU1[...]luQnliMlF0ZFhNdFpXRnpkQzB3SW4xOQ==")
                .build();
        Resource myResource = Resource.create(Attributes.of(AttributeKey.stringKey("service.name"), "javaservice"));
        SdkTracerProvider tracerProvider = SdkTracerProvider.builder().addSpanProcessor(SimpleSpanProcessor.create(spanExporter)).build();
        OpenTelemetry openTelemetry = OpenTelemetrySdk.builder().setTracerProvider(tracerProvider).build();
        String[] traceSplit = traceParent.split("-");
        SpanContext remoteContext = SpanContext.createFromRemoteParent(traceSplit[1], traceSplit[2], TraceFlags.getSampled(), TraceState.getDefault());
        Tracer tracer = openTelemetry.getTracer("from-java");
        SpanBuilder sb= tracer.spanBuilder("java-name").setSpanKind(SpanKind.CONSUMER);
        sb.setParent(Context.current().with(Span.wrap(remoteContext)));
        sb.setAttribute("testattributejava", "testattributejava");
        Span serverSpan = sb.startSpan();
        try {
            Thread.sleep(100); // mock our operation
            System.out.println("This is an example operation." + traceSplit[1] + traceSplit[2] + serverSpan + serverSpan.isRecording() + remoteContext);
            return serverSpan + " " + remoteContext;
        } finally {
            serverSpan.end();
        }
    }
    
}

And here is the Scala counterpart, not working.

import io.opentelemetry.api.common.Attributes
import io.opentelemetry.api.trace._
import io.opentelemetry.context.Context
import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter
import io.opentelemetry.sdk.OpenTelemetrySdk
import io.opentelemetry.sdk.resources.Resource
import io.opentelemetry.sdk.trace.SdkTracerProvider
import io.opentelemetry.sdk.trace.`export`.SimpleSpanProcessor
import org.apache.spark.sql.Row

class Issue {

  def call(traceParent: (String, String)): String = {
    val spanExporter = OtlpGrpcSpanExporter.builder().setEndpoint("https://tempo-prod-04-prod-us-east-0.grafana.net:443").addHeader("Authorization", "Basic ODEwNzcxOmdsY19leUp2SWpvaU1UQTFOVFV4T1NJc0ltNGlPaUp6ZEdGamF5MDROVGcyTnpJdG[...]npkQzB3SW4xOQ==").build()
    val myResource = Resource.create(Attributes.builder().put("service.name", "scalaservice").build())
    val tracerProvider = SdkTracerProvider.builder().addSpanProcessor(SimpleSpanProcessor.create(spanExporter)).build()
    val openTelemetry = OpenTelemetrySdk.builder().setTracerProvider(tracerProvider).build()
    val remoteContext = SpanContext.createFromRemoteParent(traceParent._1, traceParent._2, TraceFlags.getSampled, TraceState.getDefault)
    val tracer = openTelemetry.getTracer("from-scala")
    val spanBuilder = tracer.spanBuilder("scala-name").setSpanKind(SpanKind.CONSUMER)
    spanBuilder.setParent(Context.current().`with`(Span.wrap(remoteContext)))
    spanBuilder.setAttribute("testAttributeScala1", "testAttributeScala2")
    val mySpan = spanBuilder.startSpan()
    try {
      Thread.sleep(400) //mock our work
      println(traceParent._1 + traceParent._2 + mySpan.toString + mySpan.isRecording + remoteContext)
      mySpan.toString
    } finally {
      mySpan.end()
    }
  }

What did you expect to see?
A clear and concise description of what you expected to see.

=> For both Java and Scala, I was hoping to see the trace in our tracing back ends. (Tested with Tempo, Lightstep, Datadog, Elastic APM)

What did you see instead?

=> We see the trace being sent for the Java code, but not for the Scala counterpart.

What version and what artifacts are you using?
Artifacts: => opentelemetry-api, opentelemetry-sdk, 1.49.0 which exporters => OTLP
Version: => 1.49.0
How did you reference these artifacts? (excerpt from your build.gradle, pom.xml, etc)

=> Here is the part from SBT

  "io.opentelemetry" % "opentelemetry-api" % "1.49.0",
  "io.opentelemetry" % "opentelemetry-sdk" % "1.49.0",
  "io.opentelemetry" % "opentelemetry-exporter-otlp" % "1.49.0",

Environment
Compiler: GraalVM 24, but we are not building native image
OS: The latest Noble

Additional context

Hello team,

This is my first issue in this repo.

If not anything else, just wanted to say thanks for the work.

Just wanted to reach out with a small issue.

We have a Java Spark Structured Streaming pipeline with kafka, where we would like to trace calls between Kafka producers (from different sources and languages) to our Spark job.

The above Java code is one step of the map reduce from Spark.

It is working. We can see traces in the different tracing backend.

However, a similar Spark Streaming job in Scala, with the similar map function (tracing) will not work.

No matter what, we cannot see the trace in any of the back end systems.

Could you please help on this issue?

Good day!

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the Issue.call entry point and compare the Java and Scala snippets, including the trace-parent values, span setup, and exporter configuration. Reproduce with OpenTelemetry 1.49.0 and verify whether the Scala path exports a span that appears in the listed tracing back ends; done means the Scala streaming path produces a visible trace.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, kafka, scala, spark
Domain
observability, stream-processing
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.