package logger import ( "os" "strconv" "strings" "time" "github.com/gin-gonic/gin" "go.uber.org/zap" ) const ( unKnowHostName = "unkonw" bufferDefaultLen = 4 * 2000 ) func GinLoggerMiddleware(logger *zap.SugaredLogger) gin.HandlerFunc { hostName, err := os.Hostname() if err != nil { hostName = unKnowHostName } return func(c *gin.Context) { info := requestInfo{ Host: hostName, Path: c.Request.URL.Path, Method: c.Request.Method, Start: time.Now(), ClientIP: c.ClientIP(), ClientUserAgent: c.Request.UserAgent(), Referer: c.Request.Referer(), DataLen: c.Writer.Size(), } c.Next() info.End = time.Now() info.Status = c.Writer.Status() if len(c.Errors) > 0 { logger.Error(info.String(c.Errors.Last())) } else { logger.Info(info.String(nil)) } } } type requestInfo struct { ClientIP string Host string Method string Path string Referer string ClientUserAgent string Start time.Time End time.Time Status int DataLen int } func (i *requestInfo) String(err error) string { infoBuffer := strings.Builder{} infoBuffer.Grow(bufferDefaultLen) infoBuffer.WriteString("clientIP:") infoBuffer.WriteString(i.ClientIP) infoBuffer.WriteString("-host:") infoBuffer.WriteString(i.Host) infoBuffer.WriteString(" method:") infoBuffer.WriteString(i.Method) infoBuffer.WriteString(" path:") infoBuffer.WriteString(i.Path) infoBuffer.WriteString(" status:") infoBuffer.WriteString(strconv.Itoa(i.Status)) infoBuffer.WriteString(" start:") infoBuffer.WriteString(i.Start.Format(time.StampMicro)) infoBuffer.WriteString(" end:") infoBuffer.WriteString(i.End.Format(time.StampMicro)) infoBuffer.WriteString(" cost:") infoBuffer.WriteString(strconv.FormatInt(i.End.Sub(i.Start).Microseconds(), 10)) infoBuffer.WriteString("ms ") infoBuffer.WriteString(" dataLen:") infoBuffer.WriteString(strconv.Itoa(i.DataLen)) infoBuffer.WriteString(" referer:") infoBuffer.WriteString(i.Referer) infoBuffer.WriteString(" clientUserAgent:") infoBuffer.WriteString(i.ClientUserAgent) if err != nil { infoBuffer.WriteString(" errMsg:") infoBuffer.WriteString(err.Error()) } return infoBuffer.String() }