如何从 ctrl“sigs.k8s.io/controller-runtime”模拟 zap 记录器?
Posted
技术标签:
【中文标题】如何从 ctrl“sigs.k8s.io/controller-runtime”模拟 zap 记录器?【英文标题】:How to mock zap logger from ctrl "sigs.k8s.io/controller-runtime"? 【发布时间】:2021-12-13 15:30:30 【问题描述】:package logger
import (
"bytes"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
ctrl "sigs.k8s.io/controller-runtime"
)
var _ = Describe("Logger", func()
It("Test Default Log Level", func()
buf := &bytes.Buffer
testLog := ctrl.Log.WithName("setup")
SetLogger()
testLog.Info("This is a test")
Expect(buf.String(),"This is a test")
)
)
这是SetLogger
函数,也用于生产:
package logger
import (
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
...
)
func SetLogger()
opts := zap.Options
Development: developmentFlag,
StacktraceLevel: stacktraceLevel,
Level: isLevelEnabler,
Encoder: logFmtEncoder,
ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts)))
如何将testLog.Info
的输出更改为缓冲区?
【问题讨论】:
【参考方案1】:如果你只对测试日志消息感兴趣,你可以使用钩子。
特别是zap.Hooks
函数从可变数量的挂钩构造zap.Option
。钩子只是一个func(entry zapcore.Entry) error
,您可以使用它来拦截条目并将其消息写入缓冲区。
要将此zap.Option
设置到您的sigs.k8s.io
记录器中,请将其设置为ZapOpts
字段:
opts := k8szap.Options
// ...
ZapOpts: []zap.Option
zap.Hooks(func(entry zapcore.Entry) error
buf.WriteString(entry.Message)
return nil
),
,
因此,由于您需要访问缓冲区,因此可以将其作为参数传递给 SetLogger
函数:
func SetLogger(buf *bytes.Buffer)
opts := zap.Options
Development: developmentFlag,
StacktraceLevel: stacktraceLevel,
Level: isLevelEnabler,
Encoder: logFmtEncoder,
// here 'zap' selector is 'go.uber.org/zap'
ZapOpts: []zap.Option
zap.Hooks(func(entry zapcore.Entry) error
buf.WriteString(entry.Message)
return nil
),
,
// here I call 'k8szap' selector the package 'sigs.k8s.io/controller-runtime/pkg/log/zap'
ctrl.SetLogger(k8szap.New(k8szap.UseFlagOptions(&opts)))
然后在你的测试函数中:
It("Test Default Log Level", func()
buf := &bytes.Buffer
testLog := ctrl.Log.WithName("setup")
// pass buffer to SetLogger
SetLogger(buf)
testLog.Info("This is a test")
Expect(buf.String(), "This is a test")
)
最小示例(在操场上下载包时可能会超时):https://play.golang.org/p/oBN3SHFKVC8
【讨论】:
@blackGrren - 再次感谢您的支持,我还有 2 个问题:在真实情况下(不在测试中)我需要将什么传递给 buf *bytes.Buffer 而不是在测试中?设置记录器后是否可以设置它或者它必须处于初始化阶段? @user1365697 如果您使用指针*bytes.Buffer
从技术上讲,您可以保留变量并随时为其分配一些其他值,但是如果出现错误,这已经成熟你的程序有并发代码。在初始化期间设置它可能是一个更好的选择
@blackGrren - 真实情况下的 *bytes.Buffer 应该是什么?当我从生产调用中调用它时
@user1365697 好吧,这取决于你想要做什么。为什么在生产中需要这个?如果您的目标是将输出重定向到其他地方,更好的选择可能是zapcore.NewTee
,类似于here。如果这只是为了测试,你最好稍微重构一下代码,因为测试的东西不应该溢出到生产代码中......但这有点超出你的问题范围,所以很难回答
@blackGrren - 我在生产中不需要它,所以我应该将什么传递给 SetLogger,因为我向 SetLogger 添加了新的参数 buf *bytes.Buffer 所以它也在生产中以上是关于如何从 ctrl“sigs.k8s.io/controller-runtime”模拟 zap 记录器?的主要内容,如果未能解决你的问题,请参考以下文章