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:
- Changed
collector
toagent
andagent
tocollector
. - Checked logs, nothing about
"client"
there - Tried to inject headers (propagation)
- 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.