From 5ad1b1bf8adf28902cd37dc4c0ef598cc7793ba2 Mon Sep 17 00:00:00 2001 From: Giannis Gkiortzis <58184179+giortzisg@users.noreply.github.com> Date: Fri, 17 Apr 2026 10:44:46 +0200 Subject: [PATCH] docs(go): Add gRPC integration guide Add a new guide for the sentry-go/grpc package, covering server-side and client-side interceptor setup, ServerOptions configuration, and hub usage within handlers. Also add a gRPC section to the auto-instrumentation page so users browsing tracing docs can discover it. Co-Authored-By: Claude --- .../instrumentation/auto-instrumentation.mdx | 22 ++- docs/platforms/go/guides/grpc/index.mdx | 155 ++++++++++++++++++ 2 files changed, 168 insertions(+), 9 deletions(-) create mode 100644 docs/platforms/go/guides/grpc/index.mdx diff --git a/docs/platforms/go/common/tracing/instrumentation/auto-instrumentation.mdx b/docs/platforms/go/common/tracing/instrumentation/auto-instrumentation.mdx index 4cfa34f2ac350..d608ce19e5fe5 100644 --- a/docs/platforms/go/common/tracing/instrumentation/auto-instrumentation.mdx +++ b/docs/platforms/go/common/tracing/instrumentation/auto-instrumentation.mdx @@ -14,18 +14,22 @@ If you're using one of Sentry's HTTP framework middlewares, transactions are cre Sentry provides middleware for the following Go HTTP frameworks: -| Framework | Package | Guide | -|-----------|---------|-------| -| Gin | `sentry-go/gin` | [Gin guide](/platforms/go/guides/gin/) | -| Echo | `sentry-go/echo` | [Echo guide](/platforms/go/guides/echo/) | -| Fiber | `sentry-go/fiber` | [Fiber guide](/platforms/go/guides/fiber/) | -| net/http | `sentry-go/http` | [net/http guide](/platforms/go/guides/http/) | -| Iris | `sentry-go/iris` | [Iris guide](/platforms/go/guides/iris/) | -| FastHTTP | `sentry-go/fasthttp` | [FastHTTP guide](/platforms/go/guides/fasthttp/) | -| Negroni | `sentry-go/negroni` | [Negroni guide](/platforms/go/guides/negroni/) | +| Framework | Package | Guide | +| --------- | -------------------- | ------------------------------------------------ | +| Gin | `sentry-go/gin` | [Gin guide](/platforms/go/guides/gin/) | +| Echo | `sentry-go/echo` | [Echo guide](/platforms/go/guides/echo/) | +| Fiber | `sentry-go/fiber` | [Fiber guide](/platforms/go/guides/fiber/) | +| net/http | `sentry-go/http` | [net/http guide](/platforms/go/guides/http/) | +| Iris | `sentry-go/iris` | [Iris guide](/platforms/go/guides/iris/) | +| FastHTTP | `sentry-go/fasthttp` | [FastHTTP guide](/platforms/go/guides/fasthttp/) | +| Negroni | `sentry-go/negroni` | [Negroni guide](/platforms/go/guides/negroni/) | Each middleware is installed and configured as part of the framework setup. See the individual guide pages for installation instructions. +## gRPC + +The `sentry-go/grpc` package provides unary and stream interceptors that automatically create transactions for incoming RPC calls on the server side, and child spans for outgoing RPC calls on the client side. Distributed traces are continued from upstream clients via `sentry-trace` and `baggage` gRPC metadata. See the [gRPC guide](/platforms/go/guides/grpc/) for setup instructions. + ## HTTP Client Spans For outbound HTTP requests, use the `sentryhttpclient` package to automatically create spans for client requests. See the HTTP Requests documentation for details. diff --git a/docs/platforms/go/guides/grpc/index.mdx b/docs/platforms/go/guides/grpc/index.mdx new file mode 100644 index 0000000000000..ad2cb4ab01f25 --- /dev/null +++ b/docs/platforms/go/guides/grpc/index.mdx @@ -0,0 +1,155 @@ +--- +title: gRPC +description: "Learn how to add Sentry to a Go gRPC server or client using interceptors." +--- + +For a quick reference, there is a [complete example](https://github.com/getsentry/sentry-go/tree/master/_examples/grpc) at the Go SDK source code repository. + +[Go Dev-style API documentation](https://pkg.go.dev/github.com/getsentry/sentry-go/grpc) is also available. + +## Install + +```bash +go get github.com/getsentry/sentry-go +go get github.com/getsentry/sentry-go/grpc +``` + + + +## Configure + +### Initialize the Sentry SDK + + + +### Server Options + +`sentrygrpc` accepts a struct of `ServerOptions` that allows you to configure how the server interceptors behave. + +```go +// Whether Sentry should repanic after recovery. In most cases it should be set to true, +// so that your own recovery middleware or gRPC's default handling can respond to the client. +Repanic bool +// Whether you want to block the request before moving forward with the response. +// Useful when you want to restart the process after it panics. +WaitForDelivery bool +// Timeout for the event delivery requests. +Timeout time.Duration +``` + +## Server-Side Usage + +Attach the unary and stream interceptors when creating your gRPC server: + +```go +import ( + "fmt" + "net" + + "google.golang.org/grpc" + + "github.com/getsentry/sentry-go" + sentrygrpc "github.com/getsentry/sentry-go/grpc" +) + +func main() { + if err := sentry.Init(sentry.ClientOptions{ + Dsn: "___PUBLIC_DSN___", + TracesSampleRate: 1.0, + }); err != nil { + fmt.Printf("Sentry initialization failed: %v\n", err) + } + defer sentry.Flush(2 * time.Second) + + server := grpc.NewServer( + grpc.UnaryInterceptor(sentrygrpc.UnaryServerInterceptor(sentrygrpc.ServerOptions{ + Repanic: true, + })), + grpc.StreamInterceptor(sentrygrpc.StreamServerInterceptor(sentrygrpc.ServerOptions{ + Repanic: true, + })), + ) + + listener, err := net.Listen("tcp", ":50051") + if err != nil { + sentry.CaptureException(err) + return + } + + if err := server.Serve(listener); err != nil { + sentry.CaptureException(err) + } +} +``` + +The server interceptors automatically: + +- Create a transaction for each unary or streaming RPC call. +- Recover from panics in handlers and report them to Sentry. +- Continue distributed traces from upstream clients via `sentry-trace` and `baggage` metadata. +- Attach an isolated `*sentry.Hub` to the handler's context. + +## Client-Side Usage + +Attach the unary and stream interceptors when creating your gRPC client: + +```go +import ( + "context" + "fmt" + + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" + + "github.com/getsentry/sentry-go" + sentrygrpc "github.com/getsentry/sentry-go/grpc" +) + +func main() { + if err := sentry.Init(sentry.ClientOptions{ + Dsn: "___PUBLIC_DSN___", + TracesSampleRate: 1.0, + }); err != nil { + fmt.Printf("Sentry initialization failed: %v\n", err) + } + defer sentry.Flush(2 * time.Second) + + conn, err := grpc.NewClient( + "localhost:50051", + grpc.WithTransportCredentials(insecure.NewCredentials()), + grpc.WithUnaryInterceptor(sentrygrpc.UnaryClientInterceptor()), + grpc.WithStreamInterceptor(sentrygrpc.StreamClientInterceptor()), + ) + if err != nil { + sentry.CaptureException(err) + return + } + defer conn.Close() +} +``` + +The client interceptors automatically: + +- Create a child span for each outgoing RPC call. +- Inject `sentry-trace` and `baggage` headers into gRPC metadata for distributed tracing. +- Set the span status based on the returned gRPC status code. + +## Usage + +Both interceptors make a `*sentry.Hub` available on the request context, which you can retrieve using `sentry.GetHubFromContext()` in your handlers. Use this hub-bound API instead of the global `sentry.CaptureMessage` or `sentry.CaptureException` calls to keep data separated between concurrent requests. + +```go +func (s *server) YourMethod(ctx context.Context, req *pb.YourRequest) (*pb.YourResponse, error) { + if hub := sentry.GetHubFromContext(ctx); hub != nil { + hub.WithScope(func(scope *sentry.Scope) { + scope.SetTag("request_id", req.GetId()) + hub.CaptureMessage("Handling request") + }) + } + return &pb.YourResponse{}, nil +} +``` + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup