Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(418)

Side by Side Diff: grpc/grpcmon/server.go

Issue 2945013002: grpc: Interceptor to catch panics and convert them to Internal errors. (Closed)
Patch Set: oops Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | grpc/grpcutil/paniccatcher.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The LUCI Authors. All rights reserved. 1 // Copyright 2016 The LUCI Authors. All rights reserved.
2 // Use of this source code is governed under the Apache License, Version 2.0 2 // Use of this source code is governed under the Apache License, Version 2.0
3 // that can be found in the LICENSE file. 3 // that can be found in the LICENSE file.
4 4
5 package grpcmon 5 package grpcmon
6 6
7 import ( 7 import (
8 "time" 8 "time"
9 9
10 "golang.org/x/net/context" 10 "golang.org/x/net/context"
11 "google.golang.org/grpc" 11 "google.golang.org/grpc"
12 "google.golang.org/grpc/codes"
12 13
13 "github.com/luci/luci-go/common/clock" 14 "github.com/luci/luci-go/common/clock"
14 "github.com/luci/luci-go/common/tsmon/distribution" 15 "github.com/luci/luci-go/common/tsmon/distribution"
15 "github.com/luci/luci-go/common/tsmon/field" 16 "github.com/luci/luci-go/common/tsmon/field"
16 "github.com/luci/luci-go/common/tsmon/metric" 17 "github.com/luci/luci-go/common/tsmon/metric"
17 "github.com/luci/luci-go/common/tsmon/types" 18 "github.com/luci/luci-go/common/tsmon/types"
18 ) 19 )
19 20
20 var ( 21 var (
21 grpcServerCount = metric.NewCounter( 22 grpcServerCount = metric.NewCounter(
(...skipping 15 matching lines...) Expand all
37 // NewUnaryServerInterceptor returns an interceptor that gathers RPC handler 38 // NewUnaryServerInterceptor returns an interceptor that gathers RPC handler
38 // metrics and sends them to tsmon. 39 // metrics and sends them to tsmon.
39 // 40 //
40 // It can be optionally chained with other interceptor. The reported metrics 41 // It can be optionally chained with other interceptor. The reported metrics
41 // include time spent in this other interceptor too. 42 // include time spent in this other interceptor too.
42 // 43 //
43 // It assumes the RPC context has tsmon initialized already. 44 // It assumes the RPC context has tsmon initialized already.
44 func NewUnaryServerInterceptor(next grpc.UnaryServerInterceptor) grpc.UnaryServe rInterceptor { 45 func NewUnaryServerInterceptor(next grpc.UnaryServerInterceptor) grpc.UnaryServe rInterceptor {
45 return func(ctx context.Context, req interface{}, info *grpc.UnaryServer Info, handler grpc.UnaryHandler) (resp interface{}, err error) { 46 return func(ctx context.Context, req interface{}, info *grpc.UnaryServer Info, handler grpc.UnaryHandler) (resp interface{}, err error) {
46 started := clock.Now(ctx) 47 started := clock.Now(ctx)
48 panicing := true
47 defer func() { 49 defer func() {
48 » » » reportServerRPCMetrics(ctx, info.FullMethod, err, clock. Now(ctx).Sub(started)) 50 » » » // We don't want to recover anything, but we want to log Internal error
51 » » » // in case of a panic. We pray here reportServerRPCMetri cs is very
52 » » » // lightweight and it doesn't panic itself.
53 » » » code := codes.OK
54 » » » switch {
55 » » » case err != nil:
56 » » » » code = grpc.Code(err)
57 » » » case panicing:
58 » » » » code = codes.Internal
Vadim Sh. 2017/06/20 04:30:12 I think it used to log it as codes.OK because it s
59 » » » }
60 » » » reportServerRPCMetrics(ctx, info.FullMethod, code, clock .Now(ctx).Sub(started))
49 }() 61 }()
50 if next != nil { 62 if next != nil {
51 » » » return next(ctx, req, info, handler) 63 » » » resp, err = next(ctx, req, info, handler)
64 » » } else {
65 » » » resp, err = handler(ctx, req)
52 } 66 }
53 » » return handler(ctx, req) 67 » » panicing = false // normal exit, no panic happened, disarms defe r
68 » » return
54 } 69 }
55 } 70 }
56 71
57 // reportServerRPCMetrics sends metrics after RPC handler has finished. 72 // reportServerRPCMetrics sends metrics after RPC handler has finished.
58 func reportServerRPCMetrics(ctx context.Context, method string, err error, dur t ime.Duration) { 73 func reportServerRPCMetrics(ctx context.Context, method string, code codes.Code, dur time.Duration) {
59 » code := 0 74 » grpcServerCount.Add(ctx, 1, method, int(code))
60 » if err != nil { 75 » grpcServerDuration.Add(ctx, float64(dur.Nanoseconds()/1e6), method, int( code))
61 » » code = int(grpc.Code(err))
62 » }
63 » grpcServerCount.Add(ctx, 1, method, code)
64 » grpcServerDuration.Add(ctx, float64(dur.Nanoseconds()/1e6), method, code )
65 } 76 }
OLDNEW
« no previous file with comments | « no previous file | grpc/grpcutil/paniccatcher.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698