/
logger.go
114 lines (100 loc) · 3.27 KB
/
logger.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
package grpc
import (
"context"
"encoding/json"
"fmt"
"strconv"
"time"
"github.com/aluka-7/metacode"
"github.com/rs/zerolog/log"
"google.golang.org/grpc"
"google.golang.org/grpc/peer"
)
// 客户端日志
func (c *Client) clientLogging() grpc.UnaryClientInterceptor {
return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
startTime := time.Now()
var peerInfo peer.Peer
opts = append(opts, grpc.Peer(&peerInfo))
// 调用者请求
err := invoker(ctx, method, req, reply, cc, opts...)
// 请求完成后
cause := metacode.Cause(err)
dt := time.Since(startTime)
// 监控
metricClientReqDur.Observe(int64(dt/time.Millisecond), method)
metricClientReqCodeTotal.Inc(method, strconv.Itoa(cause.Code()))
// 组装客户端日志
if c.conf.EnableLog {
var stack string
if err != nil {
stack = fmt.Sprintf("%+v", err)
}
cl := newClientLogging(method, peerInfo.Addr.String(), req.(fmt.Stringer).String(), reply.(fmt.Stringer).String(), stack, cause.Code(), dt.Seconds())
v, _ := json.Marshal(cl)
log.Info().Msg(string(v))
}
return err
}
}
// 服务器日志记录
func (s *Server) serverLogging() grpc.UnaryServerInterceptor {
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
startTime := time.Now()
caller := metacode.ToString(ctx, metacode.Caller)
if caller == "" {
caller = "no_user"
}
var ip string
if peerInfo, ok := peer.FromContext(ctx); ok {
ip = peerInfo.Addr.String()
}
var quota float64
if deadline, ok := ctx.Deadline(); ok {
quota = time.Until(deadline).Seconds()
}
// 调用服务器处理程序
resp, err := handler(ctx, req)
// 服务器响应后
cause := metacode.Cause(err)
dt := time.Since(startTime)
// 监控
metricServerReqDur.Observe(int64(dt/time.Millisecond), info.FullMethod, caller)
metricServerReqCodeTotal.Inc(info.FullMethod, caller, strconv.Itoa(cause.Code()))
if s.conf.EnableLog && dt > 500*time.Millisecond {
var stack string
if err != nil {
stack = fmt.Sprintf("%+v", err)
}
sl := newServiceLogging(caller, ip, info.FullMethod, req.(fmt.Stringer).String(), stack, cause.Code(), dt.Seconds(), quota)
v, _ := json.Marshal(sl)
log.Info().Msg(string(v))
}
return resp, err
}
}
type serviceLogging struct {
User string `json:"user"`
Ip string `json:"ip"`
Path string `json:"path"`
Ret int `json:"ret"`
Ts float64 `json:"ts"`
TimeoutQuota float64 `json:"timeoutQuota"`
Req string `json:"req"`
Stack string `json:"stack,omitempty"`
}
func newServiceLogging(user, ip, path, req, stack string, ret int, ts, timeoutQuota float64) serviceLogging {
return serviceLogging{user, ip, path, ret, ts, timeoutQuota, req, stack}
}
type clientLogging struct {
Path string `json:"path"`
Ip string `json:"ip"`
Ret int `json:"ret"`
Ts float64 `json:"ts"`
Args string `json:"args"`
Reply string `json:"reply"`
Stack string `json:"stack,omitempty"`
}
func newClientLogging(path, ip, args, reply, stack string, ret int, ts float64) clientLogging {
return clientLogging{path, ip, ret, ts, args, reply, stack}
}