diff --git a/Golang/Golang Document.md b/Golang/Golang Document.md index 118d560..937e589 100644 --- a/Golang/Golang Document.md +++ b/Golang/Golang Document.md @@ -51,6 +51,10 @@ - [log messages in log file](#log-messages-in-log-file) - [将日志同时输出到log file和console](#将日志同时输出到log-file和console) - [展示日志输出行数](#展示日志输出行数) + - [logrus hook](#logrus-hook) + - [JSONFormatter](#jsonformatter) + - [设置TimeStampFormat格式](#设置timestampformat格式) + - [自定义Formatter](#自定义formatter) - [syntax](#syntax) - [iota](#iota) @@ -995,7 +999,149 @@ log.SetLevel(log.DebugLevel) {"file":"D:/Workspace/GolangWorkspace/demo/logrus/logrus.go:33","func":"main.main","level":"info","msg":"Ciallo~","time":"2025-01-14T12:59:12+08:00"} ``` +### logrus hook +通过logrus hook,可以在输出日志时执行自定义逻辑。logrus hook需要实现`Hook`接口,该接口包含`Levels`和`Fire`方法: +- `Levels`:触发该hook的log level +- `Fire`:定义当hook被触发时的执行逻辑 +logrus示例如下所示: +```go +package main + +import ( + "encoding/json" + "errors" + "fmt" + "github.com/sirupsen/logrus" + "io" + "os" + "path/filepath" +) + +type UploadESHook struct { + +} + +func (h *UploadESHook) Levels() []logrus.Level { + return []logrus.Level{ + logrus.InfoLevel, + logrus.WarnLevel, + logrus.ErrorLevel, + logrus.FatalLevel, + } +} + +func (h *UploadESHook) Fire(e *logrus.Entry) error { + jStr, err := e.String() + m := map[string]any{} + err = json.Unmarshal([]byte(jStr), &m) + if err!=nil { + return errors.New(err.Error()); + } + fmt.Printf("Uploading entry:\n %s to ES...\n", jStr) + return nil +} + + +func GetLogger(dir string, filename string) (logger *logrus.Logger, file *os.File, err error) { + if err = os.MkdirAll(dir, 0750); err!=nil { + return + } + logfile := filepath.Join(dir, filename) + file, err = os.OpenFile(logfile, os.O_TRUNC|os.O_CREATE, 0640) + if err != nil { + return + } + logger = logrus.New() + logger.SetLevel(logrus.InfoLevel) + logger.SetOutput(io.MultiWriter(file, os.Stdout)) + logger.SetFormatter(&logrus.JSONFormatter{}) + logger.SetReportCaller(true) + logger.AddHook(&UploadESHook{}) + return +} + +func main() { + logger, file, err := GetLogger("./log/", "app.log") + if err!=nil { + panic(any(err)) + } + defer file.Close() + logger.Info("Ciallo~") +} +``` + +### JSONFormatter +`logrus.JSONFormatter`会按照json格式来输出日志,可以通过如下方式进行配置: +```go +logger.SetFormatter(&logrus.JSONFormatter{}) +``` + +#### 设置TimeStampFormat格式 +可以通过如下代码设置日志输出时的TimeFormat格式: +```go +logger.SetFormatter(&logrus.JSONFormatter{TimestampFormat: "2006-01-02 15:04:05.000"}) +``` + +### 自定义Formatter +可以通过如下方式来自定义formatter: +```go +package main + +import ( + "fmt" + "path/filepath" + "runtime" + "strings" + + "github.com/google/uuid" + "github.com/sirupsen/logrus" +) + +type CustomTextFormatter struct { + SessionID string +} + +func (f *CustomTextFormatter) Format(entry *logrus.Entry) ([]byte, error) { + // Get the file and line number where the log was called + _, filename, line, _ := runtime.Caller(7) + + // Get the script name from the full file path + scriptName := filepath.Base(filename) + + // Format the log message + message := fmt.Sprintf("[%s] [%s] [%s] [%s:%d] %s\n", + entry.Time.Format("2006-01-02 15:04:05"), // Date-time + entry.Level.String(), // Log level + f.SessionID, // Unique session ID + scriptName, // Script name + line, // Line number + entry.Message, // Log message + ) + + return []byte(message), nil +} + +// Generate a unique session ID +func generateSessionID() string { + randomUUID := uuid.New() + return strings.Replace(randomUUID.String(), "-", "", -1) +} + +func main() { + // Generate a new unique session ID + sessionID := generateSessionID() + + // Create a new instance of the custom formatter + customFormatter := &CustomTextFormatter{SessionID: sessionID} + + // Set the custom formatter as the formatter for the logger + logrus.SetFormatter(customFormatter) + + // Now, log something + logrus.Info("This is a custom-formatted log") +} +``` ## syntax ### iota