package log import ( "context" "fmt" "log" "runtime" "strings" "sync" "time" "github.com/sirupsen/logrus" ) var l *logrus.Logger func init() { l = logrus.New() // 配置 Logstash 作为输出 l.AddHook(NewUTCTimeHook()) jf := &JSONFormatter{ skip: make([]*levelSkip, len(logrus.AllLevels)), } for i := range jf.skip { jf.skip[i] = &levelSkip{} } l.Formatter = jf // l.AddHook(&SkipHook{}) l.SetReportCaller(true) } type SkipHook struct { Formatter func(*logrus.Hook, *logrus.Entry) error once sync.Once } func (h *SkipHook) Levels() []logrus.Level { return logrus.AllLevels } // OpenClose 开闭空间 type OpenClose struct { Open bool Close bool Skip int } func (oc *OpenClose) OpenFunc(opendo func() bool, closedo func()) { if oc.Open && oc.Close { return } if opendo() { if !oc.Open { oc.Open = true return } } else { if oc.Open && !oc.Close { oc.Close = true closedo() } } } func (h *SkipHook) Fire(e *logrus.Entry) error { var skipLogrus, skipBasic OpenClose var skip int for i := 4; i < 25; i++ { log.Println(i) if pc, file, line, ok := runtime.Caller(i); ok { funcStruct := runtime.FuncForPC(pc) log.Println(funcStruct.Name(), file, line) skipLogrus.OpenFunc(func() bool { return strings.Contains(funcStruct.Name(), "github.com/sirupsen/logrus.") }, func() { skip = i + 1 }) skipBasic.OpenFunc(func() bool { return strings.Contains(funcStruct.Name(), "basic.(*Response).") }, func() { skip = i i = 100 }) } } if _, file, line, ok := runtime.Caller(skip); ok { // funcStruct := runtime.FuncForPC(pc) // log.Println(file, line, funcStruct.Name()) // funcName := funcStruct.Name() file := fmt.Sprintf("%s:%d", file, line) e.Data["file"] = file } return nil } // 自定义钩子以设置时间为UTC type UTCTimeHook struct{} func NewUTCTimeHook() *UTCTimeHook { return &UTCTimeHook{} } func (hook *UTCTimeHook) Levels() []logrus.Level { return logrus.AllLevels } func (hook *UTCTimeHook) Fire(entry *logrus.Entry) error { entry.Time = time.Now().UTC() return nil } // WithField allocates a new entry and adds a field to it. // Debug, Print, Info, Warn, Error, Fatal or Panic must be then applied to // this new returned entry. // If you want multiple fields, use `WithFields`. func WithField(key string, value interface{}) *logrus.Entry { return l.WithField(key, value) } // Adds a struct of fields to the log entry. All it does is call `WithField` for // each `Field`. func WithFields(fields logrus.Fields) *logrus.Entry { return l.WithFields(fields) } // Add an error as single field to the log entry. All it does is call // `WithError` for the given `error`. func WithError(err error) *logrus.Entry { return l.WithError(err) } // Add a context to the log entry. func WithContext(ctx context.Context) *logrus.Entry { return l.WithContext(ctx) } // Overrides the time of the log entry. func WithTime(t time.Time) *logrus.Entry { return l.WithTime(t) } func Logf(level logrus.Level, format string, args ...interface{}) { l.Logf(level, format, args...) } func Tracef(format string, args ...interface{}) { l.Tracef(format, args...) } func Debugf(format string, args ...interface{}) { l.Debugf(format, args...) } func Infof(format string, args ...interface{}) { l.Infof(format, args...) } func Printf(format string, args ...interface{}) { l.Printf(format, args...) } func Warnf(format string, args ...interface{}) { l.Warnf(format, args...) } func Warningf(format string, args ...interface{}) { l.Warningf(format, args...) } func Errorf(format string, args ...interface{}) { l.Errorf(format, args...) } func Fatalf(format string, args ...interface{}) { l.Fatalf(format, args...) } func Panicf(format string, args ...interface{}) { l.Panicf(format, args...) } func Log(level logrus.Level, args ...interface{}) { l.Log(level, args...) } func Trace(args ...interface{}) { l.Trace(args...) } func Debug(args ...interface{}) { l.Debug(args...) } func Info(args ...interface{}) { l.Info(args...) } func Print(args ...interface{}) { l.Print(args...) } func Warn(args ...interface{}) { l.Warn(args...) } func Warning(args ...interface{}) { l.Warning(args...) } func Error(args ...interface{}) { l.Error(args...) } func Fatal(args ...interface{}) { l.Fatal(args...) } func Panic(args ...interface{}) { l.Panic(args...) } func Logln(level logrus.Level, args ...interface{}) { l.Logln(level, args...) } func Traceln(args ...interface{}) { l.Traceln(args...) } func Debugln(args ...interface{}) { l.Debugln(args...) } func Infoln(args ...interface{}) { l.Infoln(args...) } func Println(args ...interface{}) { l.Println(args...) } func Warnln(args ...interface{}) { l.Warnln(args...) } func Warningln(args ...interface{}) { l.Warningln(args...) } func Errorln(args ...interface{}) { l.Errorln(args...) } func Fatalln(args ...interface{}) { l.Fatalln(args...) } func Panicln(args ...interface{}) { l.Panicln(args...) } func Exit(code int) { l.Exit(code) }