Monitor Go net/http performance with OpenTelemetry

Package net/http provides HTTP client and server implementations. It allows you to make and serve HTTP requests in Go.

This article will teach you how to monitor net/http performance using OpenTelemetry observability framework.

What is OpenTelemetry?

OpenTelemetry is a vendor-neutral standard on how to collect telemetry data for applications and their supporting infrastructures. OpenTelemetry was created via the merger of OpenCensus and OpenTracing projects.

OpenTelemetry aims to standardize how you collect and send telemetry data to backend platforms: tracesopen in new window, metricsopen in new window, and logsopen in new window.

Installation

To install net/http OpenTelemetry instrumentation:

go get go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp

Instrumenting http.Server

You can instrument HTTP server by wrapping all your handlers:

handler := http.Handler(http.DefaultServeMux) // or use your router
handler = otelhttp.NewHandler(handler, "")

httpServer := &http.Server{
    Addr:         ":8888",
	ReadTimeout:  5 * time.Second,
	WriteTimeout: 10 * time.Second,
	IdleTimeout:  60 * time.Second,
	Handler:      handler,
}

err := httpServer.ListenAndServe()

Filtering requests

You can exclude some requests from being traced using otelhttp.WithFilteropen in new window:

handler = otelhttp.NewHandler(handler, "", otelhttp.WithFilter(otelReqFilter))

func otelReqFilter(req *http.Request) bool {
	return req.URL.Path != "/ping"
}

Span name

You can customize span name formatting using otelhttp.WithSpanNameFormatteropen in new window:

handler = otelhttp.NewHandler(handler, "", otelhttp.WithSpanNameFormatter(httpSpanName))

func spanName(operation string, req *http.Request) string {
	return operation
}

Route attribute

If you are instrumenting individual handlers (not all handlers at once), you can annotate handler spans with http.route attribute. This can be useful when you can't find an instrumentation for your router.

handler = otelhttp.WithRouteTag("/hello/:username", handler)

Instrumenting http.Client

otelhttp provides a HTTP transport to instrument http.Client:

client := http.Client{
	Transport: otelhttp.NewTransport(http.DefaultTransport),
}

You can also use the following shortcuts to make HTTP requets:

import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"

resp, err := otelhttp.Get(ctx, "https://google.com/")

What is Uptrace?

Need a backend to store telemetry data collected by OpenTelemetry instrumentations?

Uptrace is an open source APM for OpenTelemetry with an intuitive query builder, rich dashboards, automatic alerts, and integrations for most languages and frameworks.

You can get startedopen in new window with Uptrace by downloading a DEB/RPM package or a pre-compiled Go binary.

What's next?

Next, instrument more operations, for example, database queries, errors, and logs. You can also learn about OpenTelemetry Go Tracing API to create your own instrumentations.

Popular instrumentations:

Last Updated: