如何从 ctrl "sigs.k8s.io/controller-runtime" 模拟 zap 记录器?
How to mock zap logger from ctrl "sigs.k8s.io/controller-runtime"?
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
的输出更改为缓冲区?
如果您只对测试日志消息感兴趣,可以使用挂钩。
特别是 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")
})
最小示例(在 playground 下载包时可能会超时):https://play.golang.org/p/oBN3SHFKVC8
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
的输出更改为缓冲区?
如果您只对测试日志消息感兴趣,可以使用挂钩。
特别是 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")
})
最小示例(在 playground 下载包时可能会超时):https://play.golang.org/p/oBN3SHFKVC8