Skip to content

Commit

Permalink
updated documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
nr-swilloughby committed Jul 8, 2021
1 parent 1ccdb9d commit 0efa74c
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 38 deletions.
61 changes: 51 additions & 10 deletions v3/integrations/nrgrpc/nrgrpc_doc.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright 2020 New Relic Corporation. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

//
// Package nrgrpc instruments https://github.com/grpc/grpc-go.
//
// This package can be used to instrument gRPC servers and gRPC clients.
Expand All @@ -9,18 +10,58 @@
//
// To instrument a gRPC server, use UnaryServerInterceptor and
// StreamServerInterceptor with your newrelic.Application to create server
// interceptors to pass to grpc.NewServer. Example:
// interceptors to pass to grpc.NewServer.
//
// 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
// code they return.
//
// app, _ := newrelic.NewApplication(
// newrelic.ConfigAppName("gRPC Server"),
// newrelic.ConfigLicense(os.Getenv("NEW_RELIC_LICENSE_KEY")),
// newrelic.ConfigDebugLogger(os.Stdout),
// )
// server := grpc.NewServer(
// grpc.UnaryInterceptor(nrgrpc.UnaryServerInterceptor(app)),
// grpc.StreamInterceptor(nrgrpc.StreamServerInterceptor(app)),
// )
// In the simplest case, simply add interceptors as in the following example:
//
// app, _ := newrelic.NewApplication(
// newrelic.ConfigAppName("gRPC Server"),
// newrelic.ConfigLicense(os.Getenv("NEW_RELIC_LICENSE_KEY")),
// newrelic.ConfigDebugLogger(os.Stdout),
// )
// server := grpc.NewServer(
// grpc.UnaryInterceptor(nrgrpc.UnaryServerInterceptor(app)),
// grpc.StreamInterceptor(nrgrpc.StreamServerInterceptor(app)),
// )
//
// 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:
// OK OK
// Info AlreadyExists, Canceled, InvalidArgument, NotFound,
// Unauthenticated
// Warning Aborted, DeadlineExceeded, FailedPrecondition, OutOfRange,
// PermissionDenied, ResourceExhausted, Unavailable
// Error DataLoss, Internal, Unknown, Unimplemented
//
// 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.
//
// For example, to report DeadlineExceeded as an error and NotFound
// as a warning, for the UnaryInterceptor only:
// server := grpc.NewServer(
// grpc.UnaryInterceptor(nrgrpc.UnaryServerInterceptor(app,
// nrgrpc.WithStatusHandler(codes.DeadlineExceeded, nrgrpc.ErrorInterceptorStatusHandler),
// nrgrpc.WithStatusHandler(codes.NotFound, nrgrpc.WarningInterceptorStatusHandler)),
// grpc.StreamInterceptor(nrgrpc.StreamServerInterceptor(app)),
// )
//
// If you wanted to make those two changes to the overall default behavior, so they
// apply to all subsequently declared interceptors:
// nrgrpc.Configure(
// nrgrpc.WithStatusHandler(codes.DeadlineExceeded, nrgrpc.ErrorInterceptorStatusHandler),
// nrgrpc.WithStatusHandler(codes.NotFound, nrgrpc.WarningInterceptorStatusHandler),
// )
// server := grpc.NewServer(
// grpc.UnaryInterceptor(nrgrpc.UnaryServerInterceptor(app)),
// grpc.StreamInterceptor(nrgrpc.StreamServerInterceptor(app)),
// )
// In this case the new behavior for those two status codes applies to both interceptors.
//
// These interceptors create transactions for inbound calls. The transaction is
// added to the call context and can be accessed in your method handlers
Expand Down
57 changes: 29 additions & 28 deletions v3/integrations/nrgrpc/nrgrpc_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -23,13 +23,14 @@
//
// 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
//

package nrgrpc

import (
Expand Down Expand Up @@ -73,8 +74,8 @@ func startTransaction(ctx context.Context, app *newrelic.Application, fullMethod
}

//
// `ErrorHandler` is the type of a gRPC status handler function.
// Normally the supplied set of `ErrorHandler` functions will suffice, but
// ErrorHandler is the type of a gRPC status handler function.
// Normally the supplied set of ErrorHandler functions will suffice, but
// a custom handler may be crafted by the user and installed as a handler
// if needed.
//
Expand Down Expand Up @@ -113,35 +114,35 @@ var interceptorStatusHandlerRegistry = statusHandlerMap{
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
// The ErrorHandler parameter is generally one of the provided standard
// reporting functions:
// `OKInterceptorStatusHandler` // report the operation as successful
// `ErrorInterceptorStatusHandler` // report the operation as an error
// `WarningInterceptorStatusHandler` // report the operation as a warning
// `InfoInterceptorStatusHandler` // report the operation as an informational message
// OKInterceptorStatusHandler // report the operation as successful
// ErrorInterceptorStatusHandler // report the operation as an error
// WarningInterceptorStatusHandler // report the operation as a warning
// InfoInterceptorStatusHandler // report the operation as an informational message
//
// The following reporting function should only be used if you know for sure
// you want this. It does not report the error in any way at all, but completely
// ignores it.
// `IgnoreInterceptorStatusHandler` // report the operation as successful
// IgnoreInterceptorStatusHandler // report the operation as successful
//
// Finally, if you have a custom reporting need that isn't covered by the standard
// handler functions, you can create your own handler function as
// func myHandler(ctx context.Context, txn *newrelic.Transaction, s *status.Status) {
// ...
// }
// Within the function, do whatever you need to do with the `txn` parameter to report the
// gRPC status passed as `s`. If needed, the context is also passed to your function.
// Within the function, do whatever you need to do with the txn parameter to report the
// gRPC status passed as s. If needed, the context is also passed to your function.
//
// If you wish to use your custom handler for a code such as `codes.NotFound`, you would
// 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 {
return func(m statusHandlerMap) {
Expand All @@ -150,10 +151,10 @@ func WithStatusHandler(c codes.Code, h ErrorHandler) handlerOption {
}

//
// `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) {
Expand Down Expand Up @@ -222,7 +223,7 @@ func InfoInterceptorStatusHandler(ctx context.Context, txn *newrelic.Transaction

//
// Standard handler: DEFAULT
// The `DefaultInterceptorStatusHander` is used for any status code which is not
// The DefaultInterceptorStatusHander is used for any status code which is not
// explicitly assigned a handler.
//
var DefaultInterceptorStatusHandler = InfoInterceptorStatusHandler
Expand Down Expand Up @@ -264,15 +265,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
// any number of `WithStatusHandler(code, handler)` functions as parameters.
// 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 `<type>StreamInterceptor()` call's parameter list,
// WithStatusHandler() calls at the end of the <type>StreamInterceptor() call's parameter list,
// like so:
// grpc.UnaryInterceptor(nrgrpc.UnaryServerInterceptor(app,
// nrgrpc.WithStatusHandler(codes.OutOfRange, nrgrpc.WarningInterceptorStatusHandler),
Expand Down Expand Up @@ -331,7 +332,7 @@ 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 {
if app == nil {
Expand Down

0 comments on commit 0efa74c

Please sign in to comment.