func TestTracer(t *testing.T) { log.SetFlags(0) var tracer ot.Tracer tracer = &Tracer{} ot.InitGlobalTracer(tracer) ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { serverSpan, err := tracer.Join( "serverSpan", ot.TextMap, ot.HTTPHeaderTextMapCarrier(r.Header)) if err != nil { panic(err) } time.Sleep(time.Second * 1) serverSpan.Finish() fmt.Fprintln(w, "Hello, client") })) defer ts.Close() span, nctx := ot.StartSpanFromContext(context.TODO(), "main_test") defer span.Finish() foo(nctx, "bar", 0) httpClient := &http.Client{} httpReq, _ := http.NewRequest("GET", ts.URL, nil) // Transmit the span's TraceContext as HTTP headers on our // outbound request. tracer.Inject( span, ot.TextMap, ot.HTTPHeaderTextMapCarrier(httpReq.Header)) if _, err := httpClient.Do(httpReq); err != nil { panic(err) } }
// Endpoint is an example API endpoint. In a real application, the backend of // your service would be contacting several external and internal API endpoints // which may be the bottleneck of your application. // // For example purposes we just sleep for 200ms before responding to simulate a // slow API endpoint as the bottleneck of your application. func Endpoint(w http.ResponseWriter, r *http.Request) { // Extract the trace from the headers and join it with a new child span. carrier := opentracing.HTTPHeaderTextMapCarrier(r.Header) span, err := opentracing.GlobalTracer().Join(r.URL.Path, opentracing.TextMap, carrier) if err != nil { return } defer span.Finish() span.SetTag("Request.Host", r.Host) span.SetTag("Request.Method", r.Method) addHeaderTags(span, r.Header) time.Sleep(200 * time.Millisecond) fmt.Fprintf(w, "Slept for 200ms!") }
// Home is the homepage handler for our app. func Home(w http.ResponseWriter, r *http.Request) { // Start a new root Span and therefore a new trace. span := opentracing.StartSpan(r.URL.Path) defer span.Finish() // OpenTracing allows for arbritary tags to be added to a Span. span.SetTag("Request.Host", r.Host) span.SetTag("Request.Address", r.RemoteAddr) addHeaderTags(span, r.Header) // Baggage Items are similar to tags, however they are propagated to all // children spans, so this will show up in the API calls. span.SetBaggageItem("User", os.Getenv("USER")) // We're going to make some API request, so we use the default HTTP client // to send HTTP requests with trace information placed inside the headers. httpClient := http.DefaultClient // Make three API requests using our HTTP client. for i := 0; i < 3; i++ { req, err := http.NewRequest("GET", "http://localhost:8699/endpoint", nil) if err != nil { log.Println("/endpoint:", err) continue } // We inject the span into the request headers before making the request. carrier := opentracing.HTTPHeaderTextMapCarrier(req.Header) span.Tracer().Inject(span, opentracing.TextMap, carrier) resp, err := httpClient.Do(req) if err != nil { log.Println("/endpoint:", err) // Log the error to the span. span.LogEvent(err.Error()) continue } span.SetTag("Response.Status", resp.Status) resp.Body.Close() } // Render the page. fmt.Fprintf(w, `<p>Three API requests have been made!</p>`) fmt.Fprintf(w, `<p><a href="http://localhost:8700/traces" target="_">View the trace</a></p>`) }