Search code examples
goinstrumentationopentracingjaeger

Tracer sending a span


I am trying to use instrumentation in Go with Jaeger.

I am running the Jaeger backend with docker like this (as explained in https://www.jaegertracing.io/docs/1.15/getting-started/):

docker run -d --name jaeger \
  -e COLLECTOR_ZIPKIN_HTTP_PORT=9411 \
  -p 5775:5775/udp \
  -p 6831:6831/udp \
  -p 6832:6832/udp \
  -p 5778:5778 \
  -p 16686:16686 \
  -p 14268:14268 \
  -p 9411:9411 \
  jaegertracing/all-in-one:1.15

However, after running the following Go code, I am not able to see spans in the Jaeger UI at http://localhost:16686 and I am not sure what's wrong with this code? I started from a similar piece of Python code and that is able to publish spans on the Jaeger UI.

package main

import (
    "fmt"
    "io"

    opentracing "github.com/opentracing/opentracing-go"
    jaeger "github.com/uber/jaeger-client-go"
    jaegercfg "github.com/uber/jaeger-client-go/config"
)

func initJaeger(service string) (opentracing.Tracer, io.Closer) {
    agentIP := "localhost"
    agentPort := "5775"
    so := jaeger.SamplerOptionsFactory{}
    logger := jaeger.StdLogger
    logger.Infof("Sending Traces to %s %s", agentIP, agentPort)
    cfg := &jaegercfg.Configuration{
        Sampler: &jaegercfg.SamplerConfig{
            Type:    "const",
            Param:   1,
            Options: []jaeger.SamplerOption{so.Logger(logger)},
        },
        ServiceName: service,
        Reporter: &jaegercfg.ReporterConfig{
            LogSpans:           true,
            LocalAgentHostPort: agentIP + ":" + agentPort,
        },
    }
    tracer, closer, err := cfg.NewTracer(jaegercfg.Logger(logger))
    if err != nil {
        panic(fmt.Sprintf("ERROR: cannot init Jaeger: %v\n", err))
    }

    opentracing.SetGlobalTracer(tracer)
    return opentracing.GlobalTracer(), closer
}

func main() {

    tracer, closer := initJaeger("foo-go-service")

    span := tracer.StartSpan("GoTestSpan")
    var myMap = make(map[string]interface{})
    myMap["foo"] = 42
    myMap["bar"] = "42"
    span.LogKV(myMap)

    childSpanRef := opentracing.ChildOf(span.Context())
    childSpan := tracer.StartSpan("GoChildSpan", childSpanRef)
    var myMap2 = make(map[string]interface{})
    myMap2["foo2"] = 42
    myMap2["bar2"] = "42"
    childSpan.LogKV(myMap2)

    closer.Close()
}

I am digging in the docs here https://godoc.org/github.com/uber/jaeger-client-go and the ones for the open tracing project here https://godoc.org/github.com/opentracing/opentracing-go but I am a bit confused by the jargon and the library functions/methods.

  • I would like to publish "generic" events to the Jaeger backend and seeing these events in the Jaeger UI.
  • I would also like to publish "HTTP requests" events using some sort of automatic wrapper for a request struct, but even simple/generic events would be good for now.

Solution

  • I was able to publish some spans so I could see them on http://localhost:16686

    • We should SetOperationName on the Span so we can identify it with a human readable name on the UI
    • We should also defer the span.Finish() call, it seems this is why I was not able to see anything on the UI

    This is the updated main function:

    func main() {
    
        tracer, closer := initJaeger("foo-go-service")
        defer closer.Close()
    
        span := tracer.StartSpan("GoTestSpan")
        defer span.Finish()
        span.SetOperationName("opNameGoTestSpan")
        var myMap = make(map[string]interface{})
        myMap["foo"] = 42
        myMap["bar"] = "42"
        span.LogKV(myMap)
    
        // time.Sleep(2 * time.Second)
    
        childSpanRef := opentracing.ChildOf(span.Context())
        childSpan := tracer.StartSpan("GoChildSpan", childSpanRef)
        defer childSpan.Finish()
        childSpan.SetOperationName("opNameGoChildSpan")
        var myMap2 = make(map[string]interface{})
        myMap2["foo2"] = 42
        myMap2["bar2"] = "42"
        childSpan.LogKV(myMap2)
    }