github.com/blend/go-sdk@v1.20220411.3/stats/grpcstats/listeners.go (about) 1 /* 2 3 Copyright (c) 2022 - Present. Blend Labs, Inc. All rights reserved 4 Use of this source code is governed by a MIT license that can be found in the LICENSE file. 5 6 */ 7 8 package grpcstats 9 10 import ( 11 "context" 12 "strconv" 13 14 "google.golang.org/grpc/status" 15 16 "github.com/blend/go-sdk/grpcutil" 17 "github.com/blend/go-sdk/logger" 18 "github.com/blend/go-sdk/stats" 19 "github.com/blend/go-sdk/timeutil" 20 ) 21 22 // AddListeners adds grpc listeners. 23 func AddListeners(log logger.Listenable, collector stats.Collector, opts ...stats.AddListenerOption) { 24 if log == nil || collector == nil { 25 return 26 } 27 28 options := stats.NewAddListenerOptions(opts...) 29 30 log.Listen(grpcutil.FlagRPC, stats.ListenerNameStats, grpcutil.NewRPCEventListener(func(ctx context.Context, re grpcutil.RPCEvent) { 31 var tags []string 32 33 labels := logger.GetLabels(ctx) 34 for key, value := range labels { 35 tags = append(tags, stats.Tag(key, value)) 36 } 37 38 if len(re.Method) > 0 { 39 tags = append(tags, stats.Tag(TagRPCMethod, re.Method)) 40 } else { 41 tags = append(tags, stats.Tag(TagRPCMethod, RPCMethodUnknown)) 42 } 43 44 if re.Engine != "" { 45 tags = append(tags, stats.Tag(TagRPCEngine, re.Engine)) 46 } 47 if re.Peer != "" { 48 tags = append(tags, stats.Tag(TagRPCPeer, re.Peer)) 49 } 50 51 if re.Err != nil { 52 tags = append(tags, getErrorTag(re.Err)) 53 } 54 55 tags = append(tags, options.GetLoggerLabelsAsTags(ctx)...) 56 57 _ = collector.Increment(MetricNameRPC, tags...) 58 _ = collector.Gauge(MetricNameRPCElapsedLast, timeutil.Milliseconds(re.Elapsed), tags...) 59 _ = collector.Histogram(MetricNameRPCElapsed, timeutil.Milliseconds(re.Elapsed), tags...) 60 })) 61 62 log.Listen(grpcutil.FlagRPCStreamMessage, stats.ListenerNameStats, grpcutil.NewRPCStreamMessageEventListener(func(ctx context.Context, re grpcutil.RPCStreamMessageEvent) { 63 var tags []string 64 65 labels := logger.GetLabels(ctx) 66 for key, value := range labels { 67 tags = append(tags, stats.Tag(key, value)) 68 } 69 70 if len(re.Method) > 0 { 71 tags = append(tags, stats.Tag(TagRPCMethod, re.Method)) 72 } else { 73 tags = append(tags, stats.Tag(TagRPCMethod, RPCMethodUnknown)) 74 } 75 76 if re.Engine != "" { 77 tags = append(tags, stats.Tag(TagRPCEngine, re.Engine)) 78 } 79 if re.Peer != "" { 80 tags = append(tags, stats.Tag(TagRPCPeer, re.Peer)) 81 } 82 83 if re.Direction != "" { 84 tags = append(tags, stats.Tag(TagRPCStreamMessageDirection, string(re.Direction))) 85 } 86 if re.Err != nil { 87 tags = append(tags, getErrorTag(re.Err)) 88 } 89 90 tags = append(tags, options.GetLoggerLabelsAsTags(ctx)...) 91 92 _ = collector.Increment(MetricNameRPCStreamMessage, tags...) 93 _ = collector.Gauge(MetricNameRPCStreamMessageElapsedLast, timeutil.Milliseconds(re.Elapsed), tags...) 94 _ = collector.Histogram(MetricNameRPCStreamMessageElapsed, timeutil.Milliseconds(re.Elapsed), tags...) 95 })) 96 } 97 98 func getErrorTag(err error) string { 99 if e, ok := status.FromError(err); ok { 100 code := e.Code() 101 return stats.Tag(stats.TagError, strconv.Itoa(int(code))) 102 } 103 return stats.TagError 104 }