Monitoring Golang gRPC with OpenTelemetry

OpenTelemetry gRPC is an OpenTelemetry instrumentation for collecting telemetry data from gRPC applications.

gRPC is a cross-platform open source high performance Remote Procedure Call (RPC) framework for Golang. gRPC is ideal for lightweight microservices where efficiency is critical.

This article explains how you can monitor and optimize gRPC 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: distributed tracingopen in new window and OpenTelemetry metricsopen in new window.

GRPC instrumentation

OpenTelemetry gRPC is easy to use and provides a simple API for instrumenting gRPC applications, making it possible for developers to quickly add observability to their gRPC applications without having to write a lot of code.

To install otelgrpc instrumentation:

go get go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc

Usage

To instrument gRPC client:

import (
	"google.golang.org/grpc"
	"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
)

conn, err := grpc.Dial(target,
	grpc.WithInsecure(),
	grpc.WithUnaryInterceptor(otelgrpc.UnaryClientInterceptor()),
	grpc.WithStreamInterceptor(otelgrpc.StreamClientInterceptor()),
)

To instrument gRPC server:

import (
	"google.golang.org/grpc"
	"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
)

server := grpc.NewServer(
	grpc.UnaryInterceptor(otelgrpc.UnaryServerInterceptor()),
	grpc.StreamInterceptor(otelgrpc.StreamServerInterceptor()),
)

Metadata and baggage

On the client side, you can use gRPC metadata as a baggage:

import "google.golang.org/grpc/metadata"

md := metadata.Pairs(
	"key1", "value1",
	"key2", "value2",
)
ctx := metadata.NewOutgoingContext(context.Background(), md)

On the server side, you can use gRPC metadata from an incoming request:

import "google.golang.org/grpc/metadata"

md, ok := metadata.FromIncomingContext(ctx); ok {
    fmt.Println(md)
}

Or use OpenTelemetry baggage API:

import "go.opentelemetry.io/otel/baggage"

baggage := baggage.FromContext(ctx)

What is Uptrace?

Uptrace is an open source APMopen in new window for OpenTelemetry that helps developers pinpoint failures and find performance bottlenecks. Uptrace can process billions of spans on a single server and allows to monitor your software at 10x lower cost.

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, instrumentopen in new window more operations, for example, database queries, errors, and logs. You can also learn about OpenTelemetry Go Tracing APIopen in new window to create your own instrumentations.

Popular instrumentations:

Last Updated: