0

我正在使用logrus包来登录 Go 项目。为了在日志中显示键值对,文档给出了以下格式:

log.WithFields(log.Fields{
    "animal": "walrus",
    "size":   10,
  }).Info("A group of walrus emerges from the ocean")

我不想在每个日志中手动使用字符串键,而是希望在所有日志中使用一个通用结构(以避免键中出现拼写错误的机会)。

像这样的东西:

type LogMessage struct {
    Status  bool        `json:"status"`
    Message string      `json:"message"`
}

log.WithFields(&LogMessage {Status: false, Message: "Error User Already Exists"}).Info("User Creation Failed.")

日志输出应为:

time="2015-03-26T01:27:38-04:00" level=info msg="User Creation Failed." status=false message="Error User Already Exists"

如何实施?

谢谢你的帮助 !

4

2 回答 2

0

您不能将结构传递给WithFields(). 它需要Fields类型(基本上是map[string]interface{})。为避免在常用键名中出错,您可以创建常量 - 这样,如果您在常量名中输入错误,代码甚至都无法编译(最终编写起来会比传递结构更简洁):

const Status = "status"
const Message = "message"

//...
log.WithFields(log.Fields{Status: true, Message: "a message"}).Info("foo")

要准确实现您想要的,您需要在传递给之前将 struct 转换为 map WithFields()

import (
    structs "github.com/fatih/structs" // ARCHIVED
    log "github.com/sirupsen/logrus"
)

//...
    
type LogMessage struct {
    Status  bool        `json:"status"`
    Message string      `json:"message"`
}

log.WithFields(structs.Map(&LogMessage{Status: true, Message: "a message"})).Info("foo")

// Will output:
// time="2009-11-10T23:00:00Z" level=info msg=foo Message="a message" Status=true

(注意:我使用归档的库“结构”只是为了演示原理。进行转换所需的反射也会增加性能成本,所以我不会在程序的性能关键部分使用它)。

于 2021-09-15T12:02:49.923 回答
0

您可以使用自定义包装功能,您可以在其中设置字段键。

https://play.golang.org/p/H22M63kn8Jb

package main

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

func LogMyMessages(messageStruct *myMessageStruct) {
    log.WithFields(log.Fields{"status": messageStruct.Status, "message": messageStruct.Message}).Info("foo")
}

type myMessageStruct struct {
    Message string
    Status  bool
}

func main() {

    LogMyMessages(&myMessageStruct{Status: true, Message: "test message"})
}

给出这样的信息

time="2009-11-10T23:00:00Z" level=info msg=foo message="test message" status=true

于 2021-09-15T12:15:27.063 回答