diff --git a/v3/integrations/nrgrpc/nrgrpc_server.go b/v3/integrations/nrgrpc/nrgrpc_server.go index afca8033b..fe5954cb2 100644 --- a/v3/integrations/nrgrpc/nrgrpc_server.go +++ b/v3/integrations/nrgrpc/nrgrpc_server.go @@ -3,7 +3,7 @@ // // This integration instruments grpc service calls via -// UnaryServerInterceptor() and StreamServerInterceptor() functions. +// UnaryServerInterceptor and StreamServerInterceptor functions. // // The results of these calls are reported as errors or as informational // messages (of levels OK, Info, Warning, or Error) based on the gRPC status @@ -23,9 +23,9 @@ // // The disposition of each, in terms of how to report each of the various // gRPC status codes, is determined by a built-in set of defaults. These -// may be overridden on a case-by-case basis using WithStatusHandler() -// options to each UnaryServerInterceptor() or StreamServerInterceptor() -// call, or globally via the Configure() function. +// may be overridden on a case-by-case basis using WithStatusHandler +// options to each UnaryServerInterceptor or StreamServerInterceptor +// call, or globally via the Configure function. // // Full example: // https://github.com/newrelic/go-agent/blob/master/v3/integrations/nrgrpc/example/server/server.go @@ -111,13 +111,17 @@ var interceptorStatusHandlerRegistry = statusHandlerMap{ codes.Unauthenticated: InfoInterceptorStatusHandler, } -type handlerOption func(statusHandlerMap) +// +// HandlerOption is the type for options passed to the interceptor +// functions to specify gRPC status handlers. +// +type HandlerOption func(statusHandlerMap) // -// WithStatusHandler() indicates a handler function to be used to +// WithStatusHandler indicates a handler function to be used to // report the indicated gRPC status. Zero or more of these may be -// given to the Configure(), StreamServiceInterceptor(), or -// UnaryServiceInterceptor() functions. +// given to the Configure, StreamServiceInterceptor, or +// UnaryServiceInterceptor functions. // // The ErrorHandler parameter is generally one of the provided standard // reporting functions: @@ -142,45 +146,50 @@ type handlerOption func(statusHandlerMap) // If you wish to use your custom handler for a code such as codes.NotFound, you would // include the parameter // WithStatusHandler(codes.NotFound, myHandler) -// to your Configure(), StreamServiceInterceptor(), or UnaryServiceInterceptor() function. +// to your Configure, StreamServiceInterceptor, or UnaryServiceInterceptor function. // -func WithStatusHandler(c codes.Code, h ErrorHandler) handlerOption { +func WithStatusHandler(c codes.Code, h ErrorHandler) HandlerOption { return func(m statusHandlerMap) { m[c] = h } } // -// Configure() takes a list of WithStatusHandler() options and sets them +// Configure takes a list of WithStatusHandler options and sets them // as the new default handlers for the specified gRPC status codes, in the same -// way as if WithStatusHandler() were given to the StreamServiceInterceptor() -// or UnaryServiceInterceptor() functions (q.v.); however, in this case the new handlers +// way as if WithStatusHandler were given to the StreamServiceInterceptor +// or UnaryServiceInterceptor functions (q.v.); however, in this case the new handlers // become the default for any subsequent interceptors created by the above functions. // -func Configure(options ...handlerOption) { +func Configure(options ...HandlerOption) { for _, option := range options { option(interceptorStatusHandlerRegistry) } } // -// Standard handler: IGNORE -// This does not report anything at all in the context. +// IgnoreInterceptorStatusHandler is our standard handler for +// gRPC statuses which we want to ignore (in terms of any gRPC-specific +// reporting on the transaction). // func IgnoreInterceptorStatusHandler(_ context.Context, _ *newrelic.Transaction, _ *status.Status) {} // -// Standard handler: OK -// Reports only that the RPC call was successful by setting the web response header -// value. +// OKInterceptorStatusHandler is our standard handler for +// gRPC statuses which we want to report as being successful, as with the +// status code OK. +// +// This adds no additional attributes on the transaction other than +// the fact that it was successful. // func OKInterceptorStatusHandler(ctx context.Context, txn *newrelic.Transaction, s *status.Status) { txn.SetWebResponse(nil).WriteHeader(int(codes.OK)) } // -// Standard handler: ERROR -// Reports the transaction as an error, with the relevant error messages and +// ErrorInterceptorStatusHandler is our standard handler for +// gRPC statuses which we want to report as being errors, +// with the relevant error messages and // contextual information gleaned from the error value received from the RPC call. // func ErrorInterceptorStatusHandler(ctx context.Context, txn *newrelic.Transaction, s *status.Status) { @@ -194,11 +203,10 @@ func ErrorInterceptorStatusHandler(ctx context.Context, txn *newrelic.Transactio txn.AddAttribute("GrpcStatusCode", s.Code().String()) } -// examples -// Class "LoginError", Attr: "username": username - // -// Standard handler: WARNING +// WarningInterceptorStatusHandler is our standard handler for +// gRPC statuses which we want to report as warnings. +// // Reports the transaction's status with attributes containing information gleaned // from the error value returned, but does not count this as an error. // @@ -210,7 +218,9 @@ func WarningInterceptorStatusHandler(ctx context.Context, txn *newrelic.Transact } // -// Standard handler: INFO +// InfoInterceptorStatusHandler is our standard handler for +// gRPC statuses which we want to report as informational messages only. +// // Reports the transaction's status with attributes containing information gleaned // from the error value returned, but does not count this as an error. // @@ -222,14 +232,14 @@ func InfoInterceptorStatusHandler(ctx context.Context, txn *newrelic.Transaction } // -// Standard handler: DEFAULT -// The DefaultInterceptorStatusHander is used for any status code which is not +// DefaultInterceptorStatusHandler indicates which of our standard handlers +// will be used for any status code which is not // explicitly assigned a handler. // var DefaultInterceptorStatusHandler = InfoInterceptorStatusHandler // -// Common routine for reporting any kind of interceptor. +// reportInterceptorStatus is the common routine for reporting any kind of interceptor. // func reportInterceptorStatus(ctx context.Context, txn *newrelic.Transaction, handlers statusHandlerMap, err error) { grpcStatus := status.Convert(err) @@ -265,15 +275,15 @@ func reportInterceptorStatus(ctx context.Context, txn *newrelic.Transaction, han // // The nrgrpc integration has a built-in set of handlers for each gRPC status // code encountered. Serious errors are reported as error traces à la the -// newrelic.NoticeError() function, while the others are reported but not +// newrelic.NoticeError function, while the others are reported but not // counted as errors. // // If you wish to change this behavior, you may do so at a global level for -// all intercepted functions by calling the Configure() function, passing +// all intercepted functions by calling the Configure function, passing // any number of WithStatusHandler(code, handler) functions as parameters. // // You can specify a custom set of handlers with each interceptor creation by adding -// WithStatusHandler() calls at the end of the StreamInterceptor() call's parameter list, +// WithStatusHandler calls at the end of the StreamInterceptor call's parameter list, // like so: // grpc.UnaryInterceptor(nrgrpc.UnaryServerInterceptor(app, // nrgrpc.WithStatusHandler(codes.OutOfRange, nrgrpc.WarningInterceptorStatusHandler), @@ -281,7 +291,7 @@ func reportInterceptorStatus(ctx context.Context, txn *newrelic.Transaction, han // In this case, those two handlers are used (along with the current defaults for the other status // codes) only for that interceptor. // -func UnaryServerInterceptor(app *newrelic.Application, options ...handlerOption) grpc.UnaryServerInterceptor { +func UnaryServerInterceptor(app *newrelic.Application, options ...HandlerOption) grpc.UnaryServerInterceptor { if app == nil { return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { return handler(ctx, req) @@ -332,9 +342,9 @@ func newWrappedServerStream(stream grpc.ServerStream, txn *newrelic.Transaction) // UnaryServerInterceptor and StreamServerInterceptor to instrument unary and // streaming calls. // -// See the notes and examples for the UnaryServerInterceptor() function. +// See the notes and examples for the UnaryServerInterceptor function. // -func StreamServerInterceptor(app *newrelic.Application, options ...handlerOption) grpc.StreamServerInterceptor { +func StreamServerInterceptor(app *newrelic.Application, options ...HandlerOption) grpc.StreamServerInterceptor { if app == nil { return func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { return handler(srv, ss) diff --git a/v3/integrations/nrgrpc/nrgrpc_server_test.go b/v3/integrations/nrgrpc/nrgrpc_server_test.go index d77004c0d..f50b16a5e 100644 --- a/v3/integrations/nrgrpc/nrgrpc_server_test.go +++ b/v3/integrations/nrgrpc/nrgrpc_server_test.go @@ -196,7 +196,7 @@ func TestUnaryServerInterceptorError(t *testing.T) { }}) app.ExpectErrorEvents(t, []internal.WantEvent{{ Intrinsics: map[string]interface{}{ - "error.class": "gRPC Error: DataLoss", + "error.class": "gRPC Status: DataLoss", "error.message": "oooooops!", "guid": internal.MatchAnything, "priority": internal.MatchAnything, @@ -606,7 +606,7 @@ func TestStreamServerInterceptorError(t *testing.T) { }}) app.ExpectErrorEvents(t, []internal.WantEvent{{ Intrinsics: map[string]interface{}{ - "error.class": "gRPC Error: DataLoss", + "error.class": "gRPC Status: DataLoss", "error.message": "oooooops!", "guid": internal.MatchAnything, "priority": internal.MatchAnything,