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

介绍

零日志字段

我github.com/rs/zerolog在我的 golang 项目中使用。


我知道我可以使用类似这样的方法将字段添加到输出中:


package main


import (

    "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 main


import (

    "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()

}

但是,如果我想始终在每个日志行中打印当前活跃的消费者/生产者的数量怎么办?

素胚勾勒不出你
浏览 98回答 2
2回答

慕斯709654

您可以添加一个挂钩。为每个日志记录事件评估挂钩https://go.dev/play/p/Q7doafJGaeEpackage mainimport (&nbsp; &nbsp; "os"&nbsp; &nbsp; "github.com/rs/zerolog")type IntHook struct {&nbsp; &nbsp; Count int}func (h *IntHook) Run(e *zerolog.Event, l zerolog.Level, msg string) {&nbsp; &nbsp; e.Int("count", h.Count)&nbsp; &nbsp; h.Count++}func main() {&nbsp; &nbsp; var intHook IntHook&nbsp; &nbsp; log := zerolog.New(os.Stdout).Hook(&intHook)&nbsp; &nbsp; log.Info().Msg("hello world")&nbsp; &nbsp; 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/xu6aXpUmE0vpackage mainimport (&nbsp; &nbsp; "math/rand"&nbsp; &nbsp; "os"&nbsp; &nbsp; "github.com/rs/zerolog")func RandomHook(e *zerolog.Event, l zerolog.Level, msg string) {&nbsp; &nbsp; e.Int("random", rand.Intn(100))}func main() {&nbsp; &nbsp; var randomHook zerolog.HookFunc = RandomHook&nbsp; &nbsp; log := zerolog.New(os.Stdout).Hook(randomHook)&nbsp; &nbsp; log.Info().Msg("hello world")&nbsp; &nbsp; 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"}

largeQ

您可以使用zerolog Hook来实现这一点。挂钩是带有Run方法的接口,该方法在将事件数据写入给定io.Writer(在您的情况下os.Stderr)之前被调用。这是一些示例代码:type counter struct {&nbsp; &nbsp; name string&nbsp; &nbsp; 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) {&nbsp; &nbsp; e.Int32(c.name, c.get())}int main() {&nbsp; &nbsp; numConsumers, numProducers := 3, 3&nbsp; &nbsp; consumersRunning := &counter{&nbsp; &nbsp; &nbsp; &nbsp; name: "consumersRunning",&nbsp; &nbsp; &nbsp; &nbsp; value: int32(numConsumers),&nbsp; &nbsp; }&nbsp; &nbsp; producersRunning := &counter{&nbsp; &nbsp; &nbsp; &nbsp; name: "producersRunning",&nbsp; &nbsp; &nbsp; &nbsp; value: int32(numProducers),&nbsp; &nbsp; }&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; logger := zerolog.New(os.Stderr)&nbsp; &nbsp; consumerLogger := logger.With().Str("is", "consumer").Logger().Hook(consumersRunning)&nbsp; &nbsp; producerLogger := logger.With().Str("is", "producer").Logger().Hook(producersRunning)&nbsp; &nbsp; // your other code}您将使用计数器的inc和dec方法来修改运行的消费者/生产者的数量。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go