英文:
How to mock zap logger from ctrl "sigs.k8s.io/controller-runtime"?
问题
你可以使用zap
包中的New
函数创建一个新的Logger
实例,并将其输出重定向到缓冲区。然后,你可以将这个新的Logger
实例传递给testLog
,以便将日志输出到缓冲区。
以下是修改后的代码示例:
package logger
import (
"bytes"
"github.com/onsi/ginkgo"
"github.com/onsi/gomega"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
)
var _ = Describe("Logger", func() {
It("Test Default Log Level", func() {
buf := &bytes.Buffer{}
testLog := ctrl.Log.WithName("setup")
testLog.Info("This is a test")
Expect(buf.String()).To(Equal("This is a test"))
})
})
func SetLogger() {
opts := zap.Options{
Development: developmentFlag,
StacktraceLevel: stacktraceLevel,
Level: isLevelEnabler,
Encoder: logFmtEncoder,
}
buf := &bytes.Buffer{}
logger := zap.New(zap.UseFlagOptions(&opts), zap.Output(zap.AddSync(buf)))
ctrl.SetLogger(logger)
}
在SetLogger
函数中,我们创建了一个新的Logger
实例logger
,并将其输出重定向到缓冲区buf
。然后,我们将这个新的Logger
实例传递给ctrl.SetLogger
,以便将日志输出到缓冲区。
这样,当你调用testLog.Info
时,日志将被写入缓冲区buf
中。你可以通过检查buf.String()
来获取缓冲区中的日志内容。
英文:
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")
})
})
And this is the SetLogger
function, which is used also in production:
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)))
}
How I can change the output of the testLog.Info
to buffer?
答案1
得分: 1
如果你只对测试日志消息感兴趣,可以使用一个钩子(hook)。
具体来说,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,
// 这里的 'zap' 选择器是 'go.uber.org/zap'
ZapOpts: []zap.Option{
zap.Hooks(func(entry zapcore.Entry) error {
buf.WriteString(entry.Message)
return nil
}),
},
}
// 这里我调用 'k8szap' 选择器的包是 '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")
// 将缓冲区传递给 SetLogger
SetLogger(buf)
testLog.Info("This is a test")
Expect(buf.String(), "This is a test")
})
最简化的示例(在 playground 中下载包可能会超时):https://play.golang.org/p/oBN3SHFKVC8
英文:
If you are only interested in testing the log message, you can use a hook.
In particular zap.Hooks
function constructs a zap.Option
from a variable number of hooks. A hook is just a func(entry zapcore.Entry) error
which you can use to intercept the entry and write its message to the buffer.
To set this zap.Option
into your sigs.k8s.io
logger, you set it to the ZapOpts
field:
opts := k8szap.Options{
// ...
ZapOpts: []zap.Option{
zap.Hooks(func(entry zapcore.Entry) error {
buf.WriteString(entry.Message)
return nil
}),
},
}
So since you need access to the buffer, you can pass it as argument to the SetLogger
function:
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)))
}
And then in your test function:
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")
})
Minimal example (it may timeout when downloading the packages in the playground): https://play.golang.org/p/oBN3SHFKVC8
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论