github.com/shuguocloud/go-zero@v1.3.0/zrpc/internal/serverinterceptors/statinterceptor.go (about) 1 package serverinterceptors 2 3 import ( 4 "context" 5 "encoding/json" 6 "time" 7 8 "github.com/shuguocloud/go-zero/core/logx" 9 "github.com/shuguocloud/go-zero/core/stat" 10 "github.com/shuguocloud/go-zero/core/syncx" 11 "github.com/shuguocloud/go-zero/core/timex" 12 "google.golang.org/grpc" 13 "google.golang.org/grpc/peer" 14 ) 15 16 const defaultSlowThreshold = time.Millisecond * 500 17 18 var slowThreshold = syncx.ForAtomicDuration(defaultSlowThreshold) 19 20 // SetSlowThreshold sets the slow threshold. 21 func SetSlowThreshold(threshold time.Duration) { 22 slowThreshold.Set(threshold) 23 } 24 25 // UnaryStatInterceptor returns a func that uses given metrics to report stats. 26 func UnaryStatInterceptor(metrics *stat.Metrics) grpc.UnaryServerInterceptor { 27 return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, 28 handler grpc.UnaryHandler) (resp interface{}, err error) { 29 defer handleCrash(func(r interface{}) { 30 err = toPanicError(r) 31 }) 32 33 startTime := timex.Now() 34 defer func() { 35 duration := timex.Since(startTime) 36 metrics.Add(stat.Task{ 37 Duration: duration, 38 }) 39 logDuration(ctx, info.FullMethod, req, duration) 40 }() 41 42 return handler(ctx, req) 43 } 44 } 45 46 func logDuration(ctx context.Context, method string, req interface{}, duration time.Duration) { 47 var addr string 48 client, ok := peer.FromContext(ctx) 49 if ok { 50 addr = client.Addr.String() 51 } 52 content, err := json.Marshal(req) 53 if err != nil { 54 logx.WithContext(ctx).Errorf("%s - %s", addr, err.Error()) 55 } else if duration > slowThreshold.Load() { 56 logx.WithContext(ctx).WithDuration(duration).Slowf("[RPC] slowcall - %s - %s - %s", 57 addr, method, string(content)) 58 } else { 59 logx.WithContext(ctx).WithDuration(duration).Infof("%s - %s - %s", addr, method, string(content)) 60 } 61 }