statinterceptor.go 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. package serverinterceptors
  2. import (
  3. "context"
  4. "encoding/json"
  5. "time"
  6. "git.i2edu.net/i2/go-zero/core/logx"
  7. "git.i2edu.net/i2/go-zero/core/stat"
  8. "git.i2edu.net/i2/go-zero/core/timex"
  9. "google.golang.org/grpc"
  10. "google.golang.org/grpc/peer"
  11. )
  12. const serverSlowThreshold = time.Millisecond * 500
  13. // UnaryStatInterceptor returns a func that uses given metrics to report stats.
  14. func UnaryStatInterceptor(metrics *stat.Metrics) grpc.UnaryServerInterceptor {
  15. return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo,
  16. handler grpc.UnaryHandler) (resp interface{}, err error) {
  17. defer handleCrash(func(r interface{}) {
  18. err = toPanicError(r)
  19. })
  20. startTime := timex.Now()
  21. defer func() {
  22. duration := timex.Since(startTime)
  23. metrics.Add(stat.Task{
  24. Duration: duration,
  25. })
  26. logDuration(ctx, info.FullMethod, req, duration)
  27. }()
  28. return handler(ctx, req)
  29. }
  30. }
  31. func logDuration(ctx context.Context, method string, req interface{}, duration time.Duration) {
  32. var addr string
  33. client, ok := peer.FromContext(ctx)
  34. if ok {
  35. addr = client.Addr.String()
  36. }
  37. content, err := json.Marshal(req)
  38. if err != nil {
  39. logx.WithContext(ctx).Errorf("%s - %s", addr, err.Error())
  40. } else if duration > serverSlowThreshold {
  41. logx.WithContext(ctx).WithDuration(duration).Slowf("[RPC] slowcall - %s - %s - %s",
  42. addr, method, string(content))
  43. } else {
  44. logx.WithContext(ctx).WithDuration(duration).Infof("%s - %s - %s", addr, method, string(content))
  45. }
  46. }