package log import ( "context" "fmt" "log" "runtime" "strings" "sync" "time" "github.com/sirupsen/logrus" ) var dlog *logrus.Logger func init() { dlog = New(0) } func New(skip int) *logrus.Logger { myl := logrus.New() // 配置 Logstash 作为输出 myl.AddHook(NewUTCTimeHook()) jf := &JSONFormatter{ skip: make([]*levelSkip, len(logrus.AllLevels)), diffSkip: skip, } for i := range jf.skip { jf.skip[i] = &levelSkip{} } myl.Formatter = jf myl.SetReportCaller(true) if dlog != nil { myl.SetOutput(dlog.Out) } return myl } type SkipHook struct { autoSkip int Formatter func(*logrus.Hook, *logrus.Entry) error once sync.Once } func (h *SkipHook) Levels() []logrus.Level { return logrus.AllLevels } func (h *SkipHook) Fire(e *logrus.Entry) error { h.once.Do(func() { for i := 4; i < 100; i++ { log.Println(i) if pc, file, line, ok := runtime.Caller(i); ok { funcStruct := runtime.FuncForPC(pc) log.Println(funcStruct.Name(), file, line) if !strings.Contains(funcStruct.Name(), "github.com/sirupsen/logrus.") { h.autoSkip++ if h.autoSkip >= 2 { h.autoSkip = i - 3 break } } } else { break } } }) if _, file, line, ok := runtime.Caller(h.autoSkip); 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 dlog.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 dlog.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 dlog.WithError(err) } // Add a context to the log entry. func WithContext(ctx context.Context) *logrus.Entry { return dlog.WithContext(ctx) } // Overrides the time of the log entry. func WithTime(t time.Time) *logrus.Entry { return dlog.WithTime(t) } func Logf(level logrus.Level, format string, args ...interface{}) { dlog.Logf(level, format, args...) } func Tracef(format string, args ...interface{}) { dlog.Tracef(format, args...) } func Debugf(format string, args ...interface{}) { dlog.Debugf(format, args...) } func Infof(format string, args ...interface{}) { dlog.Infof(format, args...) } func Printf(format string, args ...interface{}) { dlog.Printf(format, args...) } func Warnf(format string, args ...interface{}) { dlog.Warnf(format, args...) } func Warningf(format string, args ...interface{}) { dlog.Warningf(format, args...) } func Errorf(format string, args ...interface{}) { dlog.Errorf(format, args...) } func Fatalf(format string, args ...interface{}) { dlog.Fatalf(format, args...) } func Panicf(format string, args ...interface{}) { dlog.Panicf(format, args...) } func Log(level logrus.Level, args ...interface{}) { dlog.Log(level, args...) } func Trace(args ...interface{}) { dlog.Trace(args...) } func Debug(args ...interface{}) { dlog.Debug(args...) } func Info(args ...interface{}) { dlog.Info(args...) } func Print(args ...interface{}) { dlog.Print(args...) } func Warn(args ...interface{}) { dlog.Warn(args...) } func Warning(args ...interface{}) { dlog.Warning(args...) } func Error(args ...interface{}) { dlog.Error(args...) } func Fatal(args ...interface{}) { dlog.Fatal(args...) } func Panic(args ...interface{}) { dlog.Panic(args...) } func Logln(level logrus.Level, args ...interface{}) { dlog.Logln(level, args...) } func Traceln(args ...interface{}) { dlog.Traceln(args...) } func Debugln(args ...interface{}) { dlog.Debugln(args...) } func Infoln(args ...interface{}) { dlog.Infoln(args...) } func Println(args ...interface{}) { dlog.Println(args...) } func Warnln(args ...interface{}) { dlog.Warnln(args...) } func Warningln(args ...interface{}) { dlog.Warningln(args...) } func Errorln(args ...interface{}) { dlog.Errorln(args...) } func Fatalln(args ...interface{}) { dlog.Fatalln(args...) } func Panicln(args ...interface{}) { dlog.Panicln(args...) } func Exit(code int) { dlog.Exit(code) }