Created
November 17, 2018 06:04
-
-
Save luw2007/f853cb86319504f365fcf075d56d6fb2 to your computer and use it in GitHub Desktop.
Go logging for human
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package log | |
import ( | |
"bytes" | |
"path" | |
"time" | |
"github.com/gin-gonic/gin" | |
"github.com/lestrrat/go-file-rotatelogs" | |
"github.com/pkg/errors" | |
"github.com/rifflock/lfshook" | |
"github.com/sirupsen/logrus" | |
) | |
type bodyLogWriter struct { | |
gin.ResponseWriter | |
body *bytes.Buffer | |
} | |
func (w bodyLogWriter) Write(b []byte) (int, error) { | |
w.body.Write(b) | |
return w.ResponseWriter.Write(b) | |
} | |
type loggerEntryWithFields interface { | |
WithFields(fields logrus.Fields) *logrus.Entry | |
} | |
// Log gin 访问日志 | |
func Log(logger loggerEntryWithFields, timeFormat string, utc bool) gin.HandlerFunc { | |
return func(c *gin.Context) { | |
start := time.Now() | |
blw := &bodyLogWriter{body: bytes.NewBufferString(""), ResponseWriter: c.Writer} | |
c.Writer = blw | |
c.Next() | |
end := time.Now() | |
latency := end.Sub(start) | |
if utc { | |
end = end.UTC() | |
} | |
entry := logger.WithFields(logrus.Fields{ | |
"referer": c.Request.Referer(), | |
"status": c.Writer.Status(), | |
"method": c.Request.Method, | |
"ip": c.ClientIP(), | |
"latency": latency.Nanoseconds() / int64(time.Microsecond), | |
"latency_human": latency.String(), | |
"bytes_in": c.Request.ContentLength, | |
"bytes_out": c.Writer.Size(), | |
"response": blw.body.String(), | |
"request": c.Request.RequestURI, | |
"form": c.Request.PostForm, | |
"user-agent": c.Request.UserAgent(), | |
"time": end.Format(timeFormat), | |
}) | |
if len(c.Errors) > 0 { | |
// Append error field if this is an erroneous request. | |
entry.Error(c.Errors.String()) | |
} else { | |
entry.Info() | |
} | |
} | |
} | |
// NewLogger 日志分割,绑定 | |
func NewLogger(logPath, app string) *logrus.Logger { | |
// 设置日志级别 | |
baseLogPath := path.Join(logPath, app+".log") | |
writer, err := rotatelogs.New( | |
baseLogPath+".%Y%m%d%H%M", | |
rotatelogs.WithLinkName(baseLogPath), // 生成软链,指向最新日志文件 | |
rotatelogs.WithMaxAge(7*24*time.Hour), // 文件最大保存时间 | |
rotatelogs.WithRotationTime(time.Hour), // 日志切割时间间隔 | |
) | |
if err != nil { | |
logrus.Errorf("config local file system logger error. %v", errors.WithStack(err)) | |
} | |
baseLogPath = path.Join(logPath, app+"_error.log") | |
errWriter, err := rotatelogs.New( | |
baseLogPath+".%Y%m%d%H%M", | |
rotatelogs.WithLinkName(baseLogPath), // 生成软链,指向最新日志文件 | |
rotatelogs.WithMaxAge(7*24*time.Hour), // 文件最大保存时间 | |
rotatelogs.WithRotationTime(time.Hour), // 日志切割时间间隔 | |
) | |
if err != nil { | |
logrus.Errorf("config local file system logger error. %v", errors.WithStack(err)) | |
} | |
log := logrus.New() | |
customFormatter := new(logrus.JSONFormatter) | |
customFormatter.TimestampFormat = "2006-01-02 15:04:05.999999" | |
log.Formatter = customFormatter | |
// 为不同级别设置不同的输出目的 | |
log.AddHook(lfshook.NewHook( | |
lfshook.WriterMap{ | |
logrus.DebugLevel: writer, | |
logrus.InfoLevel: writer, | |
logrus.WarnLevel: errWriter, | |
logrus.ErrorLevel: errWriter, | |
logrus.FatalLevel: errWriter, | |
logrus.PanicLevel: errWriter, | |
}, | |
customFormatter, | |
)) | |
return log | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment