как расширить лог API с новой функцией - PullRequest
0 голосов
/ 06 октября 2019

Я использую следующий код с logrus, и я хочу расширить его, то есть при каждом использовании этого журнала logrus он будет по умолчанию добавлять function и file, но он не работает как

Я получил

{
  "level": "info",
  "msg": "info",
  "time": "2019-10-06 17:14:25"
}

Я хочу

{
  "file": “myfile.go",
  "func": “myfunc:95",
  "level": "info",
  "msg": "info",
  "time": "2019-10-06 17:17:53"
}

Я не говорю об использовании ReportCaller: правда, я простохочу расширить регистратор с моей функцией

Как я могу это сделать?

Это то, что я пытаюсь

package main

import (
   "os"
   "runtime"
   "strconv"
   "strings"
   "github.com/sirupsen/logrus"
)

func main() {
   lgr().Log(logrus.InfoLevel,"info")
}

func lgr() *logrus.Logger {


   loggerImpl := &logrus.Logger{
      Out:   os.Stdout,
      Hooks: nil,
      Formatter: &logrus.JSONFormatter{
         TimestampFormat: "2006-01-02 15:04:05",
         CallerPrettyfier: func(f *runtime.Frame) (string, string) {

            pc, file, line, ok := runtime.Caller(1)
            if !ok {
               panic("Could not get context info for logger!")
            }
            filename := file[strings.LastIndex(file, "/")+1:] + ":" + strconv.Itoa(line)
            funcname := runtime.FuncForPC(pc).Name()
            fn := funcname[strings.LastIndex(funcname, ".")+1:]
            return filename, fn
         },


         PrettyPrint: true,
      },
      Level:        logrus.InfoLevel,
      ExitFunc:     nil,
   }
   return loggerImpl
}

1 Ответ

1 голос
/ 06 октября 2019

Один из способов сделать это - использовать WithFields и logrus.Fields следующим образом:

package main

import (
    "github.com/sirupsen/logrus"
    "os"
    "runtime"
    "strconv"
    "strings"
)

func main() {
    lgr().Log(logrus.InfoLevel, "info")
}

func lgr() *logrus.Entry {

    pc, file, line, ok := runtime.Caller(1)
    if !ok {
        panic("Could not get context info for logger!")
    }
    filename := file[strings.LastIndex(file, "/")+1:] + ":" + strconv.Itoa(line)
    funcname := runtime.FuncForPC(pc).Name()
    fn := funcname[strings.LastIndex(funcname, ".")+1:]

    loggerImpl := &logrus.Logger{
        Out:   os.Stdout,
        Hooks: nil,
        Formatter: &logrus.JSONFormatter{
            TimestampFormat: "2006-01-02 15:04:05",
            PrettyPrint:     true,
        },
        Level:    logrus.InfoLevel,
        ExitFunc: nil,
    }

    return loggerImpl.WithFields(logrus.Fields{
        "file":     filename,
        "function": fn,
    })
}

В приведенном выше коде *logrus.Entry содержит все методы, которые вы ожидаете от регистратора. Вы также можете использовать интерфейс logrus.FieldLogger, но если мы сделаем это, нам нужно будет придерживаться методов этого интерфейса (например, без Log метода - нужно использовать Info / Error и т. Д.).

package main

import (
    "github.com/sirupsen/logrus"
    "os"
    "runtime"
    "strconv"
    "strings"
)

func main() {
    lgr().Infoln("Hello world")
}

func lgr() logrus.FieldLogger {

    pc, file, line, ok := runtime.Caller(1)
    if !ok {
        panic("Could not get context info for logger!")
    }
    filename := file[strings.LastIndex(file, "/")+1:] + ":" + strconv.Itoa(line)
    funcname := runtime.FuncForPC(pc).Name()
    fn := funcname[strings.LastIndex(funcname, ".")+1:]

    loggerImpl := &logrus.Logger{
        Out:   os.Stdout,
        Hooks: nil,
        Formatter: &logrus.JSONFormatter{
            TimestampFormat: "2006-01-02 15:04:05",
            PrettyPrint:     true,
        },
        Level:    logrus.InfoLevel,
        ExitFunc: nil,
    }

    return loggerImpl.WithFields(logrus.Fields{
        "file":     filename,
        "function": fn,
    })
}

Выход:

{
  "file": "main.go:12",
  "function": "main",
  "level": "info",
  "msg": "Hello world",
  "time": "2019-10-07 01:24:10"
}
...