Instrumentations for Go¶
Instrumentations are plugins for popular frameworks and libraries. They use OpenTelemetry API to record important operations such as HTTP requests, DB queries, logs, errors, and more.
HTTP¶
net/http¶
To instrument a handler func:
import (
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
)
// Your app handler.
var handler http.Handler
handler = http.HandlerFunc(userProfileEndpoint)
// Wrap it with OpenTelemetry plugin.
handler = otelhttp.WithRouteTag("/profiles/:username", handler)
handler = otelhttp.NewHandler(handler, "server-name")
// Register handler.
http.Handle("/profiles/", handler)
func userProfileEndpoint(w http.ResponseWriter, req *http.Request) { ... }
gRPC¶
Installation:
go get go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc
Client setup outline:
import (
"google.golang.org/grpc"
"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
)
tracer := otel.Tracer("github.com/my/repo")
otelInterceptor := grpc.WithUnaryInterceptor(otelgrpc.UnaryClientInterceptor(tracer))
conn, err := grpc.Dial("grpc-server:9999", grpc.WithInsecure(), otelInterceptor)
Server setup outline:
import (
"google.golang.org/grpc"
"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
)
tracer := otel.Tracer("github.com/my/repo")
otelInterceptor := grpc.UnaryInterceptor(otelgrpc.UnaryServerInterceptor(tracer))
server := grpc.NewServer(otelInterceptor)
Gin¶
Installation:
go get go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin
To propagate active span through the app, use context.Context
from the http.Request
(not gin.Context
). To measure HTML template rendering, use otelgin.HTML
helper.
import "go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin"
func main() {
router := gin.Default()
router.Use(otelgin.Middleware("service-name"))
router.GET("/profiles/:username", userProfileEndpoint)
}
func userProfileEndpoint(c *gin.Context) {
ctx := c.Request.Context()
// Use request context to propagate active span.
doSomething(ctx)
// Use otelgin to instrument HTML generation.
otelgin.HTML(c, http.StatusOK, "template-name", gin.H{
"foo": "bar",
})
}
Echo¶
Installation:
go get go.opentelemetry.io/contrib/instrumentation/github.com/labstack/echo/otelecho
Setup outline:
import "go.opentelemetry.io/contrib/instrumentation/github.com/labstack/echo/otelecho"
func main() {
r := echo.New()
r.Use(otelecho.Middleware("service-name"))
}
Beego¶
Installation:
go get go.opentelemetry.io/contrib/instrumentation/github.com/astaxie/beego/otelbeego
Setup outline:
import "go.opentelemetry.io/contrib/instrumentation/github.com/astaxie/beego/otelbeego"
func main() {
// To enable tracing on template rendering, disable autorender and
// call otelbeego.Render manually.
beego.BConfig.WebConfig.AutoRender = false
mware := otelbeego.NewOTelBeegoMiddleWare("service-name")
beego.RunWithMiddleWares(":7777", mware)
}
gorilla/mux¶
Installation:
go get go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux
Setup outline:
import "go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux"
func main() {
r := mux.NewRouter()
r.Use(otelmux.Middleware("service-name"))
}
go-restful¶
Installation:
go get go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful
Setup outline:
import "go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful"
func main() {
filter := otelrestful.OTelFilter("service-name")
restful.DefaultContainer.Filter(filter)
}
macaron.v1¶
Installation:
go get go.opentelemetry.io/contrib/instrumentation/gopkg.in/macaron.v1/otelmacaron
Setup outline:
import "go.opentelemetry.io/contrib/instrumentation/gopkg.in/macaron.v1/otelmacaron"
func main() {
m := macaron.Classic()
m.Use(otelmacaron.Middleware("service-name"))
m.Run()
}
Database¶
go-pg¶
Installation:
go get github.com/go-pg/pgext
Setup outline:
db := pg.Connect(&pg.Options{
Addr: "postgresql-server:5432",
User: "postgres",
Database: "example",
})
db.AddQueryHook(pgext.OpenTelemetryHook{})
mongo-driver¶
Installation:
go get go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/mongo/otelmongo
Setup outline:
import (
"go.mongodb.org/mongo-driver/mongo/options"
"go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/mongo/otelmongo"
)
opt := options.Client()
opt.Monitor = otelmongo.NewMonitor("service-name")
go-redis¶
Installation:
go get github.com/go-redis/redisext
Setup outline:
import "github.com/go-redis/redisext"
rdb := redis.NewClient(&redis.Options{
Addr: "redis-server:6379",
})
rdb.AddHook(redisext.OpenTelemetryHook{})
gomemcache¶
Installation:
go get go.opentelemetry.io/contrib/instrumentation/github.com/bradfitz/gomemcache/memcache/otelmemcache
Setup outline:
import "go.opentelemetry.io/contrib/instrumentation/github.com/bradfitz/gomemcache/memcache/otelmemcache"
// Wrap memcache client.
mc := otelmemcache.NewClientWithTracing(
memcache.New("localhost:11211"),
)
func do(ctx context.Context, mc *otelmemcache.Client) {
// Set context.
mc = mc.WithContext(ctx)
}
gocql¶
Installation:
go get go.opentelemetry.io/contrib/instrumentation/github.com/gocql/gocql/otelgocql
Setup outline:
import (
"github.com/gocql/gocql"
"go.opentelemetry.io/contrib/instrumentation/github.com/gocql/gocql/otelgocql"
)
cluster := gocql.NewCluster("localhost")
session, err := otelgocql.NewSessionWithTracing(ctx, cluster)
if err != nil {
panic(err)
}
Logging¶
Logrus¶
Installation:
go get github.com/uptrace/uptrace-go/extra/otellogrus
Logrus instrumentation attaches your logs to the active span as events. You must use logrus.WithContext
to propagate the active span.
import (
"github.com/sirupsen/logrus"
"github.com/uptrace/uptrace-go/extra/otellogrus"
)
func main() {
logrus.AddHook(otellogrus.NewLoggingHook())
// You must use WithContext to propagate the active span.
logrus.WithContext(ctx).
WithError(err).
WithField("foo", "bar").
Error("something failed")
}