Skip to content

Instantly share code, notes, and snippets.

@luw2007
Created November 17, 2018 06:04
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save luw2007/f853cb86319504f365fcf075d56d6fb2 to your computer and use it in GitHub Desktop.
Save luw2007/f853cb86319504f365fcf075d56d6fb2 to your computer and use it in GitHub Desktop.
Go logging for human
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