'Distributed tracing doesn't work Jaeger+OpenTelemetry

I am trying to implement distributed tracing with basic GO client-server app. Using default Jaeger docker-compose all-in-one.
What was done to fix and doesn't help:

  1. Changed collector to agent and agent to collector.
  2. Checked logs, nothing about "client" there
  3. Tried to inject headers (propagation)
  4. Tried without injecting to headers (propagation)

CLIENT CODE:

import(
...
    tracesdk "go.opentelemetry.io/otel/sdk/trace"
...
)

func main() {
.....
    exporter, err := jaeger.New(
        jaeger.WithAgentEndpoint(
            jaeger.WithAgentHost("localhost"),
            jaeger.WithAgentPort("6831"),
        ),
    )
    if err != nil {
        return err
    }

    tp := tracesdk.NewTracerProvider(
        tracesdk.WithBatcher(exporter),
        tracesdk.WithResource(resource.NewWithAttributes(
            semconv.SchemaURL,
            semconv.ServiceNameKey.String("client"),
            semconv.ServiceVersionKey.String("1.0.0"),
            semconv.DeploymentEnvironmentKey.String("local"),
        )),
    )

    defer func() {
        if err := tp.Shutdown(context.Background()); err != nil {
            log.Fatal(err)
        }
    }()

    otel.SetTracerProvider(tp)
    otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(
        propagation.TraceContext{},
        propagation.Baggage{},
        propagators.Jaeger{},
    ))
    .......
}
....
func fetcherSuccess() error {
    tr := otel.Tracer("clientHTTP")
    ctx, span := tr.Start(context.Background(), "client.fetcherSuccess")
    defer span.End()

    req, err := http.NewRequestWithContext(ctx, http.MethodGet, "http://localhost:8080/success", nil)
    if err != nil {
        AddSpanError(span, err)
        FailSpan(span, "request error")
        return err
    }
    // Try to inject headers to the context using this otel.GetTextMapPropagator().Inject(ctx, h)
    headers := InjectHTTPHeaders(ctx)
    for k, v := range headers {
        req.Header.Add(k, v)
    }

    res, _ := http.DefaultClient.Do(req)

    return nil
}

SERVER CODE:

import(
...
    tracesdk "go.opentelemetry.io/otel/sdk/trace"
...
)

func main() {
.....
    exporter, err := jaeger.New(
        jaeger.WithAgentEndpoint(
            jaeger.WithAgentHost("localhost"),
            jaeger.WithAgentPort("6831"),
        ),
    )
    if err != nil {
        return err
    }

    tp := tracesdk.NewTracerProvider(
        tracesdk.WithBatcher(exporter),
        tracesdk.WithResource(resource.NewWithAttributes(
            semconv.SchemaURL,
            semconv.ServiceNameKey.String("server"),
            semconv.ServiceVersionKey.String("1.0.0"),
            semconv.DeploymentEnvironmentKey.String("local"),
        )),
    )

    defer func() {
        if err := tp.Shutdown(context.Background()); err != nil {
            log.Fatal(err)
        }
    }()

    otel.SetTracerProvider(tp)
    otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(
        propagation.TraceContext{},
        propagation.Baggage{},
        propagators.Jaeger{},
    ))

    if err := handleRequests(); err != nil {
        panic("unable to create handler")
    }
    .......
}

func handleRequests() error {
    router := http.NewServeMux()

    router.HandleFunc("/success", handleSuccess)
    router.HandleFunc("/error", handleError)
    fmt.Println("Server is listening on port: 8080")

    if err := http.ListenAndServe(":8080", router); err != nil {
        return err
    }

    return nil
}
....

func handleSuccess(w http.ResponseWriter, r *http.Request) {
    tr := otel.Tracer("serverHTTP")
    //Extract headers using otel.GetTextMapPropagator().Extract()
    ctx := ExtractHTTPHeaders(r.Context(), r.Header)
    ctx, span := tr.Start(ctx, "server.handleSuccess")

    defer span.End()

    //Add some tags here to help debug.
    AddSpanTags(span, map[string]string{"name": "Ivan"})

    //Add some event.
    AddSpanEvents(span, "testEvent", map[string]string{"eventInfo": "some info"})

    initCall(ctx, false)

    w.WriteHeader(http.StatusOK)
    w.Write([]byte("done"))
}

In Jaeger UI I see only "server" spans but not "client". So what I understand that for some reasons trace from "client" unable to reach the agent/collector(I tried both). Is there any problems with my code? Jaeger init seems equal why one app doesn't send anything is not clear for me.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source