为了账号安全,请及时绑定邮箱和手机立即绑定

github.com/rs/zerolog 字段的延迟评估

github.com/rs/zerolog 字段的延迟评估

Go
素胚勾勒不出你 2023-02-06 18:40:49
介绍零日志字段我github.com/rs/zerolog在我的 golang 项目中使用。我知道我可以使用类似这样的方法将字段添加到输出中:package mainimport (    "os"    "github.com/rs/zerolog")func main() {    logger := zerolog.New(os.Stderr).With().Timestamp().Logger()    logger.Int("myIntField", 42)    logger.Info("a regular log output") // this log entry will also contain the integer field `myIntField`}但是我想要的是在行的运行时评估logger.Info("a regular log output")字段的值是什么myIntField。那个设定我有一个带有 go-routines 的生产者/消费者设置(例如参见https://goplay.tools/snippet/hkoMAwqKcwj),我有两个整数,它们自动计算仍在运行的消费者和生产者 go-routines 的数量。在拆除消费者和生产者后,我想在运行时显示这些数字。这是使用 log 而不是 zerolog 时的代码:package mainimport (    "fmt"    "log"    "os"    "sync"    "sync/atomic")func main() {    numProducers := int32(3)    numConsumers := int32(3)    producersRunning := numProducers    consumersRunning := numConsumers    var wg sync.WaitGroup    l := log.New(os.Stderr, "", 0)    // producers    for i := int32(0); i < numProducers; i++ {        idx := i        wg.Add(1)        go (func() {            // producer tear down            defer func() {                atomic.AddInt32(&producersRunning, -1)                l.Printf("producer-%3d . producersRunning: %3d\n", idx, producersRunning)                wg.Done()            }()            // this is where the actual producer works is happening        })()    }    // consumers    for i := int32(0); i < numConsumers; i++ {        idx := i        wg.Add(1)        go (func() {            // consumer tear down            defer func() {                atomic.AddInt32(&consumersRunning, -1)                l.Printf("consumer-%3d . consumersRunning: %3d\n", idx, consumersRunning)                wg.Done()            }()            // this is where the actual consumer works is happening        })()    }    fmt.Println("waiting")    wg.Wait()}但是,如果我想始终在每个日志行中打印当前活跃的消费者/生产者的数量怎么办?
查看完整描述

2 回答

?
慕斯709654

TA贡献1840条经验 获得超5个赞

您可以添加一个挂钩。为每个日志记录事件评估挂钩

https://go.dev/play/p/Q7doafJGaeE

package main


import (

    "os"


    "github.com/rs/zerolog"

)


type IntHook struct {

    Count int

}


func (h *IntHook) Run(e *zerolog.Event, l zerolog.Level, msg string) {

    e.Int("count", h.Count)

    h.Count++

}


func main() {

    var intHook IntHook

    log := zerolog.New(os.Stdout).Hook(&intHook)


    log.Info().Msg("hello world")

    log.Info().Msg("hello world one more time")

}

输出是


{"level":"info","count":0,"message":"hello world"}

{"level":"info","count":1,"message":"hello world one more time"}

需要Count在调用之间保存指针Hook.Run


可能对你HookFunc来说更好一些。它是为每个事件调用的无状态函数。以下是为每条消息调用 PRNG 的函数挂钩示例:https ://go.dev/play/p/xu6aXpUmE0v


package main


import (

    "math/rand"

    "os"


    "github.com/rs/zerolog"

)


func RandomHook(e *zerolog.Event, l zerolog.Level, msg string) {

    e.Int("random", rand.Intn(100))

}


func main() {

    var randomHook zerolog.HookFunc = RandomHook

    log := zerolog.New(os.Stdout).Hook(randomHook)


    log.Info().Msg("hello world")

    log.Info().Msg("hello world one more time")

}

输出


{"level":"info","random":81,"message":"hello world"}

{"level":"info","random":87,"message":"hello world one more time"}


查看完整回答
反对 回复 2023-02-06
?
largeQ

TA贡献2039条经验 获得超7个赞

您可以使用zerolog Hook来实现这一点。挂钩是带有Run方法的接口,该方法在将事件数据写入给定io.Writer(在您的情况下os.Stderr)之前被调用。


这是一些示例代码:


type counter struct {

    name string

    value int32

}


func (c *counter) inc() { atomic.AddInt32(&c.value, 1) }

func (c *counter) dec() { atomic.AddInt32(&c.value, -1) }

func (c *counter) get() { atomic.LoadInt32(&c.value) }


func (c *counter) Run(e *zerolog.Event, _ zerolog.Level, _ string) {

    e.Int32(c.name, c.get())

}


int main() {

    numConsumers, numProducers := 3, 3


    consumersRunning := &counter{

        name: "consumersRunning",

        value: int32(numConsumers),

    }

    producersRunning := &counter{

        name: "producersRunning",

        value: int32(numProducers),

    }

    

    logger := zerolog.New(os.Stderr)

    consumerLogger := logger.With().Str("is", "consumer").Logger().Hook(consumersRunning)

    producerLogger := logger.With().Str("is", "producer").Logger().Hook(producersRunning)


    // your other code

}

您将使用计数器的inc和dec方法来修改运行的消费者/生产者的数量。


查看完整回答
反对 回复 2023-02-06
  • 2 回答
  • 0 关注
  • 97 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信