Skip to content
Last9
Book demo

gRPC

Instrument gRPC Go applications with the Last9 Go Agent for automatic RPC tracing and metrics

Use the Last9 Go Agent to instrument your gRPC application with automatic tracing and metrics. The agent wraps otelgrpc — full OTel compliance for both unary and streaming RPCs with minimal code changes.

Prerequisites

  • Go 1.22 or higher
  • gRPC (google.golang.org/grpc)
  • Last9 account with OTLP credentials

Installation

  1. Install the Last9 Go Agent

    go get github.com/last9/go-agent
  2. Set Environment Variables

    export OTEL_SERVICE_NAME="your-grpc-service"
    export OTEL_EXPORTER_OTLP_ENDPOINT="$last9_otlp_endpoint"
    export OTEL_EXPORTER_OTLP_HEADERS="Authorization=$last9_otlp_auth_header"
    export OTEL_TRACES_SAMPLER="always_on"
    export OTEL_RESOURCE_ATTRIBUTES="deployment.environment=production"
  3. Instrument your application

    Replace grpc.NewServer() with grpcagent.NewServer() — it returns a *grpc.Server with OpenTelemetry tracing already configured for all unary and streaming RPCs:

    package main
    import (
    "log"
    "net"
    agent "github.com/last9/go-agent"
    grpcagent "github.com/last9/go-agent/instrumentation/grpc"
    pb "your-module/proto"
    )
    func main() {
    if err := agent.Start(); err != nil {
    log.Fatalf("failed to start agent: %v", err)
    }
    defer agent.Shutdown()
    lis, err := net.Listen("tcp", ":50051")
    if err != nil {
    log.Fatalf("failed to listen: %v", err)
    }
    s := grpcagent.NewServer() // drop-in for grpc.NewServer()
    pb.RegisterYourServiceServer(s, &server{})
    s.Serve(lis)
    }

Database Instrumentation

Use the agent’s database integration for automatic SQL query tracing. Supported drivers: PostgreSQL, MySQL, SQLite.

import (
"log"
"os"
"github.com/last9/go-agent/integrations/database"
)
var db *sql.DB
func init() {
var err error
db, err = database.Open(database.Config{
DriverName: "postgres",
DSN: os.Getenv("DATABASE_URL"),
DatabaseName: "mydb",
})
if err != nil {
log.Fatal(err)
}
}
// Pass ctx from the RPC handler to propagate the trace
func (s *server) GetUser(ctx context.Context, req *pb.GetUserRequest) (*pb.GetUserResponse, error) {
rows, err := db.QueryContext(ctx, "SELECT id, name FROM users WHERE id = $1", req.Id)
// ...
}

Redis Instrumentation

import redisagent "github.com/last9/go-agent/integrations/redis"
// Drop-in replacement for redis.NewClient()
rdb := redisagent.NewClient(&redis.Options{
Addr: "localhost:6379",
})
func (s *server) GetFromCache(ctx context.Context, req *pb.CacheRequest) (*pb.CacheResponse, error) {
val, err := rdb.Get(ctx, req.Key).Result()
// ...
}

HTTP Client Instrumentation

For outgoing HTTP requests within RPC handlers with automatic traceparent propagation:

import httpagent "github.com/last9/go-agent/integrations/http"
client := httpagent.NewClient(&http.Client{})
func (s *server) CallUpstream(ctx context.Context, req *pb.UpstreamRequest) (*pb.UpstreamResponse, error) {
httpReq, _ := http.NewRequestWithContext(ctx, "GET", "https://api.example.com/data", nil)
resp, err := client.Do(httpReq)
// ...
}

What Gets Traced Automatically

SignalWhat’s captured
TracesEvery RPC: method, service, status code, latency
TracesStreaming RPCs: message count, stream lifecycle
TracesDatabase queries: SQL statement, db system, server address/port
TracesRedis commands: command name, key
TracesOutbound HTTP: method, URL, status code
MetricsRuntime: memory, GC pause, goroutine count
MetricsDatabase: connection pool usage, idle, wait time

View Traces and Metrics

After running your application, navigate to Trace Explorer and Metrics Explorer in Last9 to view your telemetry data.


Troubleshooting

Please get in touch with us on Discord or Email if you have any questions.