gpt4 book ai didi

logging - 在包之间共享库时的集中日志记录配置

转载 作者:IT王子 更新时间:2023-10-29 01:45:22 33 4
gpt4 key购买 nike

所以我正在使用一个结构化的日志库(logrus),并且我有一个core 包用作其他一些包的基础,我们称这个包为me/core ,然后是像 me/foo-serviceme/bar-service 等单独的包,它们将这个核心库用于常见的依赖项/实用程序,例如设置,配置加载,我还想将它用于标准化的事情,比如日志记录,所以我希望 me/core 能够为其他包配置日志记录,使用 Logrus 你可以做类似的事情

import(
log "github.com/Sirupsen/logrus"
)
[...]
log.SetLevel(log.DebugLevel)
log.SetFormatter(&log.TextFormatter{FullTimestamp:true})

然后做;

log.Debug("Moo")
log.WithFields(log.Fields{"structured":"data"}).Debug("I have structure data")

得到类似的输出

> DEBU[2016-04-12T22:11:38+01:00] Moo
> DEBU[2016-04-12T22:11:38+01:00] I have structure data structured=data

所以我想在我的 me/foo-service 包中配置它,比如

import(
"me/core/logging"
)

func main(){
logging.Setup()
}

只是出于各种原因,我遇到了问题。主要问题似乎是 me/coreme/foo-service 都有 logrus 库的销售版本,那些 log.Set* 命令修改变量 logrus.std 记录器,它包含标准的全局记录器,但这是两个包的单独实例,因为 me/core/vendor/.../logrus/stdme/foo-service/vendor/.../logrus/std 是不同的对象。

我尝试的第一件事是在 me/core/logging 中创建一个我可以在父级中使用的变量,比如

package logging

import(
log "github.com/Sirupsen/logrus"
)

var Log *log.Logger

func Setup(verbose bool){
Log = log.New()
if verbose{
Log.Level = log.DebugLevel
} else {
Log.Level = log.InfoLevel
}
Log.Formatter = &log.TextFormatter{FullTimestamp:true}
Log.Debug("Logging verbosely")
}

这适用于像这样的简单情况

package main

import(
"me/core/logging"
)

func main() {
logging.Setup(parsedOptions.Verbose)
logging.Log.Debug("Moo")
}

但是尝试使用结构化数据 Fields 会导致问题,我不能使用本地销售的 logrus 字段,例如

logging.Log.WithFields(log.Fields{"data":"hi"}).Debug("test")

当我得到

cannot use "me/foo-service/vendor/github.com/Sirupsen/logrus".Fields literal (type "me/foo-service/vendor/github.com/Sirupsen/logrus".Fields) as type "me/core/vendor/github.com/Sirupsen/logrus".Fields in argument to logging.Log.WithFields

并尝试用类似的东西来镜像 me/core/logging 中的字段

type Fields log.Fields

以太币不起作用,因为它仍然是一种不同的类型

cannot use logging.Fields literal (type logging.Fields) as type "me/core/vendor/github.com/Sirupsen/logrus".Fields in argument to logging.Log.WithFields

我也想不出任何方法将我的本地 log.stdme/foo-service 传递到 me/core因为它也是一种不同的类型,因为销售包。

目前我的工作涉及为每个方法创建一个镜像,所以在 me/core/logging 中我有一个类似的设置

package logging

import(
log "github.com/Sirupsen/logrus"
)

var Log *log.Logger
type Fields map[string]interface{}

func Setup(verbose bool){
Log = log.New()
if verbose{
Log.Level = log.DebugLevel
} else {
Log.Level = log.InfoLevel
}
Log.Formatter = &log.TextFormatter{FullTimestamp:true}
Log.Debug("Logging verbosely")
}

func Debug(msg interface{}){
Log.Debug(msg)
}

func WithFields(fields Fields) *log.Entry{
lf := log.Fields{}
for k,v := range fields{
lf[k] = v
}
return Log.WithFields(lf)
}

但这将涉及为每个 方法创建一个镜像,这看起来效率很低。

所以我想要一个关于如何让 me/core/vendor/.../logrus/stdme/foo-service 可用的建议,或者,如果我以完全错误的方式思考这个问题,那就是更好的方法。

最佳答案

您只能镜像 WithFields,因为其他接受内置类型。此外,由于 logging.Fieldslogrus.Fields 是同一类型,您可以更简单地做

func WithFields(f Fields) log.*Entry {
return Log.WithFields(log.Fields(f))
}

然后在你的服务中,你可以调用

logging.Log.Debug("message")
logging.WithFields(logging.Fields{"k":"v"}).Debug("message")

关于logging - 在包之间共享库时的集中日志记录配置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36584564/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com