github.com/weedge/lib@v0.0.0-20230424045628-a36dcc1d90e4/log/access_log_middleware.go (about) 1 package log 2 3 import ( 4 "bytes" 5 "context" 6 "io/ioutil" 7 "strings" 8 "time" 9 10 "github.com/weedge/lib/log/tapper" 11 "github.com/weedge/lib/net" 12 hack "github.com/weedge/lib/strings" 13 14 "github.com/gin-gonic/gin" 15 jsoniter "github.com/json-iterator/go" 16 "go.uber.org/zap" 17 "google.golang.org/grpc" 18 ) 19 20 const ( 21 LOGID = "logId" 22 REFERER = "referer" 23 COOKIE = "cookie" 24 CLIENT_IP = "client_ip" 25 LOCAL_IP = "local_ip" 26 MODULE = "module" 27 UA = "ua" 28 HOST = "host" 29 URI = "uri" 30 TRACE = "trace" 31 NOTICES = "notice" 32 MONITOR = "monitor" 33 RESPONSE = "response" 34 REQUEST = "request" 35 CODE = "code" 36 COST = "cost" 37 METHOD = "method" 38 ERR = "err" 39 ) 40 41 const ( 42 REQUEST_PARAM_CTX = "REQUEST_PARAM_CTX" 43 ) 44 45 var ( 46 LOCALIP = net.GetLocalIPv4() 47 MaxRespLen = 0 48 MaxReqParamLen = 4096 49 IgnoreReqUris = make([]string, 0) 50 ) 51 52 type bodyLogWriter struct { 53 gin.ResponseWriter 54 body *bytes.Buffer 55 } 56 57 func (w bodyLogWriter) WriteString(s string) (int, error) { 58 if w.body != nil { 59 w.body.WriteString(s) 60 } 61 return w.ResponseWriter.WriteString(s) 62 } 63 64 func (w bodyLogWriter) Write(b []byte) (int, error) { 65 if w.body != nil { 66 w.body.Write(b) 67 } 68 return w.ResponseWriter.Write(b) 69 } 70 func SetLogPrintMaxRespLen(maxRespLen int) { 71 MaxRespLen = maxRespLen 72 } 73 func SetLogPrintMaxReqParamLen(maxReqParamLen int) { 74 MaxReqParamLen = maxReqParamLen 75 } 76 func SetLogRequestParam(ctx context.Context, body interface{}) { 77 data := "" 78 switch body := body.(type) { 79 case string: 80 data = body 81 default: 82 if b, e := jsoniter.Marshal(body); e == nil { 83 data = hack.String(b) 84 } 85 } 86 87 switch c := ctx.(type) { 88 case *gin.Context: 89 c.Set(REQUEST_PARAM_CTX, data) 90 case nil: 91 default: 92 } 93 } 94 95 // add ignore request uri 96 func AddIgnoreReqUri(uri ...string) { 97 IgnoreReqUris = append(IgnoreReqUris, uri...) 98 } 99 100 // gin access log 101 func GinLogger() gin.HandlerFunc { 102 // 本地IP 103 // 当前模块名 104 return func(c *gin.Context) { 105 // 开始时间 106 start := time.Now() 107 // 请求url 108 path := c.Request.URL.Path 109 raw := c.Request.URL.RawQuery 110 if raw != "" { 111 path = path + "?" + raw 112 } 113 // 请求报文 114 body, _ := ioutil.ReadAll(c.Request.Body) 115 c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(body)) 116 117 // 获取当前context trace log 118 traceLog, _ := tapper.GetTraceLogFromGinContext(c) 119 120 blw := new(bodyLogWriter) 121 if MaxRespLen <= 0 { 122 blw = &bodyLogWriter{body: nil, ResponseWriter: c.Writer} 123 } else { 124 blw = &bodyLogWriter{body: bytes.NewBufferString(""), ResponseWriter: c.Writer} 125 } 126 c.Writer = blw 127 128 // 处理请求 129 c.Next() 130 131 // 获取响应报文 132 response := "" 133 if blw.body != nil { 134 response = blw.body.String() 135 } 136 137 bodyStr := "" 138 flag := false 139 if v, ok := c.Get(REQUEST_PARAM_CTX); ok { 140 switch v := v.(type) { 141 case string: 142 bodyStr = v 143 flag = true 144 } 145 } 146 if !flag { 147 for _, val := range IgnoreReqUris { 148 if strings.Contains(path, val) { 149 bodyStr = "" 150 flag = true 151 break 152 } 153 } 154 } 155 if !flag { 156 bodyStr = string(body) 157 } 158 159 refer := c.Request.Referer() 160 if len(refer) <= 0 { 161 refer = traceLog.Refer 162 } 163 164 // 结束时间 165 end := time.Now() 166 // 执行时间 单位:微秒 167 latency := end.Sub(start).Nanoseconds() / 1e3 168 169 _, trace := tapper.GetTraceFromContext(c) 170 _, notice := tapper.GetNoticeFromContext(c) 171 _, monitor := tapper.GetMonitorFromContext(c) 172 173 fields := []zap.Field{ 174 zap.String(LOGID, traceLog.LogId), 175 zap.String(URI, path), 176 zap.String(REFERER, refer), 177 zap.Any(COOKIE, c.Request.Cookies()), 178 zap.String(CLIENT_IP, c.ClientIP()), 179 zap.String(LOCAL_IP, LOCALIP), 180 zap.String(MODULE, traceLog.Caller), 181 zap.String("request_param", _trancate(bodyStr, MaxReqParamLen)), 182 zap.String(UA, c.Request.UserAgent()), 183 zap.String(HOST, c.Request.Host), 184 zap.String(TRACE, trace.Marshal()), 185 zap.String(NOTICES, notice.Marshal()), 186 zap.String(MONITOR, monitor.Marshal()), 187 zap.Int(CODE, c.Writer.Status()), 188 zap.String(RESPONSE, _trancate(response, MaxRespLen)), 189 zap.Int64(COST, latency), 190 } 191 192 AccessInfo("", fields...) 193 } 194 } 195 196 // grpc access log 197 func GrpcLogger() grpc.UnaryServerInterceptor { 198 return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { 199 // 开始时间 200 start := time.Now() 201 var traceLog *tapper.TraceLog 202 // 添加context信息 203 ctx, traceLog = tapper.GetTraceLogFromContext(ctx) 204 resp, err := handler(ctx, req) 205 // 结束时间 206 end := time.Now() 207 // 执行时间 单位:微秒 208 latency := end.Sub(start).Nanoseconds() / 1e3 209 AccessInfo("", 210 zap.Any(LOGID, traceLog.LogId), 211 zap.String(METHOD, info.FullMethod), 212 zap.Any(REQUEST, req), 213 zap.String(NOTICES, ""), 214 zap.Any(RESPONSE, resp), 215 zap.Any(ERR, err), 216 zap.Int64(COST, latency)) 217 return resp, err 218 } 219 } 220 221 func _trancate(s string, l int) string { 222 if len(s) > l { 223 return s[:l] 224 } 225 return s 226 }