Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 是否可以在不丢失行号前缀的情况下包装logrus.Logger函数?_Go_Logging_Callstack - Fatal编程技术网

Go 是否可以在不丢失行号前缀的情况下包装logrus.Logger函数?

Go 是否可以在不丢失行号前缀的情况下包装logrus.Logger函数?,go,logging,callstack,Go,Logging,Callstack,使用包装的logrus函数/记录器时,记录器会在所有日志行前加上记录器函数调用的文件名和行号,例如: INFO[0000]logging.go:39 myfolder/logging.Info() 如果我像这样包装日志函数,例如: 包日志记录 import ( "fmt" "github.com/sirupsen/logrus" "os" "path" "runti

使用包装的logrus函数/记录器时,记录器会在所有日志行前加上记录器函数调用的文件名和行号,例如:

INFO[0000]logging.go:39 myfolder/logging.Info()
如果我像这样包装日志函数,例如: 包日志记录

import (
    "fmt"
    "github.com/sirupsen/logrus"
    "os"
    "path"
    "runtime"
)

var (
    log *logrus.Logger
)

func init() {

    log = logrus.New()
    log.SetReportCaller(true)
    log.Formatter = &logrus.TextFormatter{
        CallerPrettyfier: func(f *runtime.Frame) (string, string) {
            filename := path.Base(f.File)
            return fmt.Sprintf("%s()", f.Function), fmt.Sprintf("%s:%d", filename, f.Line)
        },
    }
}

func Info(args ...interface{}) {
        log.Info(args...)
}
此函数发出的每一行都将以
日志函数调用的行号作为前缀。这与预期的一样,但所需的行为是每一行都以调用
Info
的行的行号作为前缀

所需输出应为:

INFO[0000]myfile.go:39 myfolder/myfile.myfunction()

有什么办法吗?

在logrus中是不可能做到的。我有一个类似的要求,并最终做了以下为我们工作

包mylog
进口(
“fmt”
“github.com/Sirupsen/logrus”
“运行时”
“字符串”
)
var logger=logrus.New()
func SetLogFormatter(格式化程序logrus.formatter){
logger.Formatter=格式化程序
}
//Info在标准记录器上记录信息级别的消息。
函数信息(参数…接口{}){
如果logger.Level>=logrus.InfoLevel{
条目:=logger.WithFields(logrus.Fields{})
entry.Data[“file”]=fileInfo(2)
entry.Info(args…)
}
}
func fileInfo(跳过整型)字符串{
_,文件,行,确定:=runtime.Caller(跳过)
如果!好的{
file=“”
直线=1
}否则{
斜杠:=strings.LastIndex(文件“/”)
如果斜杠>=0{
file=file[斜杠+1:]
}
}
返回fmt.Sprintf(“%s:%d”,文件,行)
}

看看这个或它的一些变体是否适用于您的用例。我已经从上面的代码片段中删除了特定于应用程序的代码。

希望我没有误解,因此您需要调用记录器的“实际”路径和行号。下面的代码(以json格式为例)应该给出您想要的。如果要添加更多信息,如函数名等,只需修改
caller()
方法

logrus.SetReportCaller(true)
// ...
logrus.SetFormatter(&logrus.JSONFormatter){
CallerPropertyFiler:caller(),
野外地图:logrus.FieldMap{
logrus.FieldKeyFile:“调用者”,
},
})
//调用者返回日志调用者的字符串表示形式,其格式为
//`/path/to/file.go:line\u number`。e、 g.`/internal/app/api.go:25`
func caller()func(*runtime.Frame)(函数字符串,文件字符串){
return func(f*runtime.Frame)(函数字符串、文件字符串){
p、 _uwk:=os.Getwd()
返回“”,fmt.Sprintf(“%s:%d”,strings.TrimPrefix(f.File,p),f.Line)
}
}

这对我很有用,谢谢你@mayank patel。我的建议是,你也应该添加这个解决方案,因为这是这个问题的第一个谷歌搜索结果。
{
  "caller": "/internal/controller/create.go:21",
  "level": "info",
  "msg": "i am a dummy log",
  "time": "2020-08-30T19:17:48+01:00"
}