Docs » µAPM Instrumentation Guide » Go Instrumentation

Go Instrumentation 🔗

Note

Go Auto-Instrumentation is currently in beta.

Important

Before you start instrumenting your applications, review the information in Instrumentation Overview.

For Go we provide a tracing library that includes wrappers for popular Go libraries to provide automatic instrumentation by changing your import paths. For custom instrumentation we recommend using the OpenTracing Go API which interoperates with the SignalFx library.

SignalFx Tracing 🔗

Add the dependency github.com/signalfx/signalfx-go-tracing using your dependency manager or with go get. If using go get you will need to remove the directory $GOPATH/src/github.com/signalfx/golib/vendor to prevent conflicting imports.

Here is a basic example of starting tracing and instrumenting a basic HTTP server:

package main

import (
        httptrace "github.com/signalfx/signalfx-go-tracing/contrib/net/http"
        "github.com/signalfx/signalfx-go-tracing/tracing"
        "net/http"
)

func main() {
        tracing.Start()
        defer tracing.Stop()

        mux := httptrace.NewServeMux()
        mux.HandleFunc("/query", func(writer http.ResponseWriter, request *http.Request) {
                writer.WriteHeader(200)
                writer.Write([]byte("Success"))
        })
        err := http.ListenAndServe("localhost:8234", mux)
        if err != nil {
                panic(err)
        }
}

Note the changed path to use net/http from the tracing library but that some functions and structs still come from the original import path.

Configuration can be done using either environment variables or API calls.

Description Environment Variable API
Service Name SIGNALFX_SERVICE_NAME WithServiceName
Endpoint URL SIGNALFX_ENDPOINT_URL WithEndpointURL
Access Token SIGNALFX_ACCESS_TOKEN WithAccessToken

Custom Tracing 🔗

To trace code that’s not autoinstrumented you can use the OpenTracing Go API along with the SignalFx tracing library.

package main

import (
        "github.com/opentracing/opentracing-go"
        "github.com/opentracing/opentracing-go/log"
        httptrace "github.com/signalfx/signalfx-go-tracing/contrib/net/http"
        "github.com/signalfx/signalfx-go-tracing/tracing"
        "math/rand"
        "net/http"
        "time"
)

func slowFunction() {
        time.Sleep(time.Duration(rand.Intn(3)) * time.Second)
}

func main() {
        tracing.Start()
        defer tracing.Stop()

        mux := httptrace.NewServeMux()
        mux.HandleFunc("/query", func(writer http.ResponseWriter, request *http.Request) {
                writer.WriteHeader(200)

                span, _ := opentracing.StartSpanFromContext(request.Context(), "slowFunction1")
                span.SetTag("function", "1")
                span.LogFields(log.String("message", "first function"))
                slowFunction()
                span.Finish()

                span, _ = opentracing.StartSpanFromContext(request.Context(), "slowFunction2")
                span.SetTag("function", "2")
                slowFunction()
                span.Finish()

                writer.Write([]byte("Success"))
        })
        err := http.ListenAndServe("localhost:8234", mux)
        if err != nil {
                panic(err)
        }
}

Auto-instrumentation 🔗

To use the instrumentation wrappers just change the imports. For example instead of net/http use github.com/signalfx/signalfx-go-tracing/contrib/net/http.

Go version 1.12+ is supported.

Currently the following libraries have instrumentation wrappers:

Library Supported Versions
database/sql Supported Go Versions
net/http Supported Go Versions
gin-gonic/gin 1.4+
globalsign/mgo r2018.06.15+
labstack/echo 4.0+
gorilla/mux 1.7+
mongodb/mongo-go-driver 1.0+