Skip to content

gRPC interceptors #240

Open
Open
@rcmachado

Description

@rcmachado

Summary

Provide gRPC interceptors to automatically capture errors and panics from servers and clients, both for unary and stream requests.

Motivation

gRPC is a high-performance, open source universal RPC framework originally developed by Google. It supports languages/platforms such as Python, Ruby, Kotlin and Go.

Go SDK already has some integrations with standard net/http package and some popular frameworks (like Gin, Martini and others).

Similar to other frameworks, having standard Sentry integration will make it easier for users to integrate Sentry with gRPC.

Additional Context

gRPC has the concept of interceptor (middleware), which could make it easier to implement an official Sentry integration. An interceptor is a function with a specific signature/type:

// Server interceptors (middlewares)
type UnaryServerInterceptor func(ctx context.Context, req interface{}, info *UnaryServerInfo, handler UnaryHandler) (resp interface{}, err error)
type StreamServerInterceptor func(srv interface{}, ss ServerStream, info *StreamServerInfo, handler StreamHandler) error

// Client interceptors (middlewares)
type UnaryClientInterceptor func(ctx context.Context, method string, req, reply interface{}, cc *ClientConn, invoker UnaryInvoker, opts ...CallOption) error
type StreamClientInterceptor func(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, streamer Streamer, opts ...CallOption) (ClientStream, error)

Using an interceptor is also straightforward (pseudo-code):

// Sentry initialization
err := sentry.Init(sentry.ClientOptions{
	// Either set your DSN here or set the SENTRY_DSN environment variable.
	Dsn: "https://[email protected]/1307339",
	// Enable printing of SDK debug messages.
	// Useful when getting started or trying to figure something out.
	Debug: true,
})
if err != nil {
	log.Fatalf("sentry.Init: %s", err)
}
// Flush buffered events before the program terminates.
// Set the timeout to the maximum duration the program can afford to wait.
defer sentry.Flush(2 * time.Second)

// Initialize gRPC server
myServer := grpc.NewServer(
    grpc.StreamInterceptor(
        sentry.StreamServerInterceptor(),
    ),
    grpc.UnaryInterceptor(
        sentry.UnaryServerInterceptor(),
    ),
)

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions