项目开发-日志篇 | Go
Logrus 是 Go 的结构化日志记录库,与标准库中的日志模块完全兼容。
logrus安装
go install github.com/sirupsen/logrus@latest
logrus使用
在使用 logrus 时,鼓励用 log.WithFields(log.Fields{}).Fatal()
这种方式替代 log.Fatalf("Failed to send event %s to topic %s with key %d")
, 以结构化日志输出。
log.WithFields(log.Fields{
"event": event,
"topic": topic,
"key": key,
}).Fatal("Failed to send event")
若想让重复出现的字段始终附加日志语中,可以将其设置为默认字段,通过创建一个 logrus.Entry来实现
requestLogger := log.WithFields(log.Fields{"request_id": request_id, "user_ip": user_ip})
requestLogger.Info("something happened on that request") # will log request_id and user_ip
requestLogger.Warn("something not great happened")
- 日志输出级别
Logrus日志级别共有7类,警告级别从低到高低依次为:Trace, Debug, Info, Warning, Error, Fatal and Panic
log.Trace("Something very low level.")
log.Debug("Useful debugging information.")
log.Info("Something noteworthy happened!")
log.Warn("You should probably take a look at this.")
log.Error("Something failed but I'm not quitting.")
// Calls os.Exit(1) after logging
log.Fatal("Bye.")
// Calls panic() after logging
log.Panic("I'm bailing.")
设置日志输出警告级别
log.SetLevel(log.WarnLevel)
- 日志输出格式
Logrus内置了JSONFormatter 和 TextFormatter,来定义输出的日志格式。实际开发中,也可以自定义输出格式。
设置内置日志输出格式
log.SetFormatter(&log.JSONFormatter{
TimestampFormat: "2006-01-02 15:04:05",
})
//Log as JSON instead of the default ASCII formatter.
log.SetFormatter(&log.JSONFormatter{})
log.SetFormatter(&log.TextFormatter{
TimestampFormat: "2006-01-02 15:04:05",
DisableColors: true,
FullTimestamp: true,
})
//Log as Text instead of the default ASCII formatter.
log.SetFormatter(&log.TextFormatter{})
自定义日志格式
如下所示,可以参考SetFormatter方法中的参数Formatter, 使用该接口自定义日志格式,其包含 Format 方法,方法内有一个struct类型数据 *Entry, Entry.Data 是所有字段集合,Fields 类型为 map[string]interface{}
// SetFormatter sets the logger formatter.
func (logger *Logger) SetFormatter(formatter Formatter) {
logger.mu.Lock()
defer logger.mu.Unlock()
logger.Formatter = formatter
}
type Formatter interface {
Format(*Entry) ([]byte, error)
}
type Entry struct {
Logger *Logger
// Contains all the fields set by the user.
Data Fields
// Time at which the log entry was created
Time time.Time
// Level the log entry was logged at: Trace, Debug, Info, Warn, Error, Fatal or Panic
// This field will be set on entry firing and the value will be equal to the one in Logger struct field.
Level Level
// Calling method, with package name
Caller *runtime.Frame
// Message passed to Trace, Debug, Info, Warn, Error, Fatal or Panic
Message string
// When formatter is called in entry.log(), a Buffer may be set to entry
Buffer *bytes.Buffer
// Contains the context set by the user. Useful for hook processing etc.
Context context.Context
// err may contain a field formatting error
err string
}
自定义日志格式例子
type MyJSONFormatter struct {
}
log.SetFormatter(new(MyJSONFormatter))
func (f *MyJSONFormatter) Format(entry *Entry) ([]byte, error) {
// Note this doesn't include Time, Level and Message which are available on
// the Entry. Consult `godoc` on information about those fields or read the
// source of the official loggers.
serialized, err := json.Marshal(entry.Data)
if err != nil {
return nil, fmt.Errorf("Failed to marshal fields to JSON, %w", err)
}
return append(serialized, '\n'), nil
}
- 日志输出方式
设置日志输出方式
// Output to stdout instead of the default stderr
log.SetOutput(os.Stdout)
// Can be any io.Writer, see below for File example
logfile, err := os.OpenFile("./logrus.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND,0644)
if err == nil {
log.SetOutput(logfile)
} else {
log.Info("Failed to log to file, using default stderr")
}
- 日志输出内容
如果希望将调用方法添加为字段,可以设置
log.SetReportCaller(true)
日志输出
{"animal":"penguin","level":"fatal","method":"github.com/sirupsen/arcticcreatures.migrate","msg":"a penguin swims by",
"time":"2014-03-10 19:57:38.562543129 -0400 EDT"}
版权声明:本博客所有文章除特别声明外,均采用 CC BY 4.0许可协议,转载请注明出处
本文链接:https://blog.redamancy.tech/technique/21