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
-
Install the Last9 Go Agent
go get github.com/last9/go-agent -
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" -
Instrument your application
Replace
grpc.NewServer()withgrpcagent.NewServer()— it returns a*grpc.Serverwith OpenTelemetry tracing already configured for all unary and streaming RPCs:package mainimport ("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)}Pass
grpcagent.NewClientDialOption()when dialing to automatically trace all outgoing RPCs:package mainimport ("log"agent "github.com/last9/go-agent"grpcagent "github.com/last9/go-agent/instrumentation/grpc"pb "your-module/proto""google.golang.org/grpc""google.golang.org/grpc/credentials/insecure")func main() {if err := agent.Start(); err != nil {log.Fatalf("failed to start agent: %v", err)}defer agent.Shutdown()conn, err := grpc.NewClient("localhost:50051",grpc.WithTransportCredentials(insecure.NewCredentials()),grpcagent.NewClientDialOption(), // automatic OTel client tracing)if err != nil {log.Fatalf("did not connect: %v", err)}defer conn.Close()c := pb.NewYourServiceClient(conn)// make RPC calls normally — all are traced}
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 tracefunc (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
| Signal | What’s captured |
|---|---|
| Traces | Every RPC: method, service, status code, latency |
| Traces | Streaming RPCs: message count, stream lifecycle |
| Traces | Database queries: SQL statement, db system, server address/port |
| Traces | Redis commands: command name, key |
| Traces | Outbound HTTP: method, URL, status code |
| Metrics | Runtime: memory, GC pause, goroutine count |
| Metrics | Database: 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.