bump up kopia v0.13.0

Signed-off-by: Lyndon-Li <lyonghui@vmware.com>
This commit is contained in:
Lyndon-Li
2023-05-15 07:23:38 +08:00
parent 4db1a781fc
commit 307b82a2ec
37 changed files with 939 additions and 747 deletions
+106 -34
View File
@@ -21,6 +21,8 @@ import (
"github.com/kopia/kopia/repo/logging"
"github.com/sirupsen/logrus"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
type kopiaLog struct {
@@ -32,59 +34,129 @@ type kopiaLog struct {
// call the logger in the context to write logs
func SetupKopiaLog(ctx context.Context, logger logrus.FieldLogger) context.Context {
return logging.WithLogger(ctx, func(module string) logging.Logger {
return &kopiaLog{
module: module,
logger: logger,
}
kpLog := &kopiaLog{module, logger}
return zap.New(kpLog).Sugar()
})
}
func (kl *kopiaLog) Debugf(msg string, args ...interface{}) {
logger := kl.logger.WithField("logModule", kl.getLogModule())
logger.Debugf(msg, args...)
// Enabled decides whether a given logging level is enabled when logging a message
func (kl *kopiaLog) Enabled(level zapcore.Level) bool {
entry := kl.logger.WithField("null", "null")
switch level {
case zapcore.DebugLevel:
return (entry.Logger.GetLevel() >= logrus.DebugLevel)
case zapcore.InfoLevel:
return (entry.Logger.GetLevel() >= logrus.InfoLevel)
case zapcore.WarnLevel:
return (entry.Logger.GetLevel() >= logrus.WarnLevel)
case zapcore.ErrorLevel:
return (entry.Logger.GetLevel() >= logrus.ErrorLevel)
case zapcore.DPanicLevel:
return (entry.Logger.GetLevel() >= logrus.PanicLevel)
case zapcore.PanicLevel:
return (entry.Logger.GetLevel() >= logrus.PanicLevel)
case zapcore.FatalLevel:
return (entry.Logger.GetLevel() >= logrus.FatalLevel)
default:
return false
}
}
func (kl *kopiaLog) Debugw(msg string, keyValuePairs ...interface{}) {
logger := kl.logger.WithField("logModule", kl.getLogModule())
logger.WithFields(getLogFields(keyValuePairs...)).Debug(msg)
// With adds structured context to the Core.
func (kl *kopiaLog) With(fields []zapcore.Field) zapcore.Core {
copied := kl.logrusFields(fields)
return &kopiaLog{
module: kl.module,
logger: kl.logger.WithFields(copied),
}
}
func (kl *kopiaLog) Infof(msg string, args ...interface{}) {
logger := kl.logger.WithField("logModule", kl.getLogModule())
logger.Infof(msg, args...)
// Check determines whether the supplied Entry should be logged. If the entry
// should be logged, the Core adds itself to the CheckedEntry and returns the result.
func (kl *kopiaLog) Check(ent zapcore.Entry, ce *zapcore.CheckedEntry) *zapcore.CheckedEntry {
if kl.Enabled(ent.Level) {
return ce.AddCore(ent, kl)
}
return ce
}
func (kl *kopiaLog) Warnf(msg string, args ...interface{}) {
logger := kl.logger.WithField("logModule", kl.getLogModule())
logger.Warnf(msg, args...)
// Write serializes the Entry and any Fields supplied at the log site and writes them to their destination.
func (kl *kopiaLog) Write(ent zapcore.Entry, fields []zapcore.Field) error {
copied := kl.logrusFieldsForWrite(ent, fields)
logger := kl.logger.WithFields(copied)
switch ent.Level {
case zapcore.DebugLevel:
logger.Debug(ent.Message)
case zapcore.InfoLevel:
logger.Info(ent.Message)
case zapcore.WarnLevel:
logger.Warn(ent.Message)
case zapcore.ErrorLevel:
// We see Kopia generates error logs for some normal cases or non-critical
// cases. So Kopia's error logs are regarded as warning logs so that they don't
// affect Velero's workflow.
logger.Warn(ent.Message)
case zapcore.DPanicLevel:
logger.Panic(ent.Message)
case zapcore.PanicLevel:
logger.Panic(ent.Message)
case zapcore.FatalLevel:
logger.Fatal(ent.Message)
}
return nil
}
// We see Kopia generates error logs for some normal cases or non-critical
// cases. So Kopia's error logs are regarded as warning logs so that they don't
// affect Velero's workflow.
func (kl *kopiaLog) Errorf(msg string, args ...interface{}) {
logger := kl.logger.WithFields(logrus.Fields{
"logModule": kl.getLogModule(),
"sublevel": "error",
})
// Sync flushes buffered logs (if any).
func (kl *kopiaLog) Sync() error {
return nil
}
logger.Warnf(msg, args...)
func (kl *kopiaLog) logrusFields(fields []zapcore.Field) logrus.Fields {
if fields == nil {
return logrus.Fields{}
}
m := zapcore.NewMapObjectEncoder()
for _, field := range fields {
field.AddTo(m)
}
return m.Fields
}
func (kl *kopiaLog) getLogModule() string {
return "kopia/" + kl.module
}
func getLogFields(keyValuePairs ...interface{}) map[string]interface{} {
m := map[string]interface{}{}
for i := 0; i+1 < len(keyValuePairs); i += 2 {
s, ok := keyValuePairs[i].(string)
if !ok {
s = "non-string-key"
}
func (kl *kopiaLog) logrusFieldsForWrite(ent zapcore.Entry, fields []zapcore.Field) logrus.Fields {
copied := kl.logrusFields(fields)
m[s] = keyValuePairs[i+1]
copied["logModule"] = kl.getLogModule()
if ent.Caller.Function != "" {
copied["function"] = ent.Caller.Function
}
return m
path := ent.Caller.FullPath()
if path != "undefined" {
copied["path"] = path
}
if ent.LoggerName != "" {
copied["logger name"] = ent.LoggerName
}
if ent.Stack != "" {
copied["stack"] = ent.Stack
}
if ent.Level == zap.ErrorLevel {
copied["sublevel"] = "error"
}
return copied
}
+119 -38
View File
@@ -19,66 +19,147 @@ package logging
import (
"testing"
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/require"
"go.uber.org/zap/zapcore"
"github.com/vmware-tanzu/velero/pkg/test"
)
func TestGetLogFields(t *testing.T) {
func TestEnabled(t *testing.T) {
testCases := []struct {
name string
pairs []interface{}
expected map[string]interface{}
level logrus.Level
zapLevel zapcore.Level
expected bool
}{
{
name: "normal",
pairs: []interface{}{
"fake-key1",
"fake-value1",
"fake-key2",
10,
"fake-key3",
struct{ v int }{v: 10},
name: "check debug again debug",
level: logrus.DebugLevel,
zapLevel: zapcore.DebugLevel,
expected: true,
},
{
name: "check debug again info",
level: logrus.InfoLevel,
zapLevel: zapcore.DebugLevel,
expected: false,
},
{
name: "check info again debug",
level: logrus.DebugLevel,
zapLevel: zapcore.InfoLevel,
expected: true,
},
{
name: "check info again info",
level: logrus.InfoLevel,
zapLevel: zapcore.InfoLevel,
expected: true,
},
{
name: "check info again error",
level: logrus.ErrorLevel,
zapLevel: zapcore.InfoLevel,
expected: false,
},
{
name: "check error again error",
level: logrus.ErrorLevel,
zapLevel: zapcore.ErrorLevel,
expected: true,
},
{
name: "check panic again error",
level: logrus.ErrorLevel,
zapLevel: zapcore.PanicLevel,
expected: true,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
log := kopiaLog{
logger: test.NewLoggerWithLevel(tc.level),
}
m := log.Enabled(tc.zapLevel)
require.Equal(t, tc.expected, m)
})
}
}
func TestWrite(t *testing.T) {
testCases := []struct {
name string
module string
zapEntry zapcore.Entry
zapFields []zapcore.Field
expected logrus.Fields
}{
{
name: "debug with nil fields",
module: "module-01",
zapEntry: zapcore.Entry{
Level: zapcore.DebugLevel,
},
expected: map[string]interface{}{
"fake-key1": "fake-value1",
"fake-key2": 10,
"fake-key3": struct{ v int }{v: 10},
zapFields: nil,
expected: logrus.Fields{
"logModule": "kopia/module-01",
},
},
{
name: "non string key",
pairs: []interface{}{
"fake-key1",
"fake-value1",
10,
10,
"fake-key3",
struct{ v int }{v: 10},
name: "error with nil fields",
module: "module-02",
zapEntry: zapcore.Entry{
Level: zapcore.ErrorLevel,
},
expected: map[string]interface{}{
"fake-key1": "fake-value1",
"non-string-key": 10,
"fake-key3": struct{ v int }{v: 10},
zapFields: nil,
expected: logrus.Fields{
"logModule": "kopia/module-02",
"sublevel": "error",
},
},
{
name: "missing value",
pairs: []interface{}{
"fake-key1",
"fake-value1",
"fake-key2",
10,
"fake-key3",
name: "info with nil string filed",
module: "module-03",
zapEntry: zapcore.Entry{
Level: zapcore.InfoLevel,
},
expected: map[string]interface{}{
"fake-key1": "fake-value1",
"fake-key2": 10,
zapFields: []zapcore.Field{
{
Key: "key-01",
Type: zapcore.StringType,
String: "value-01",
},
},
expected: logrus.Fields{
"logModule": "kopia/module-03",
"key-01": "value-01",
},
},
{
name: "info with logger name",
module: "module-04",
zapEntry: zapcore.Entry{
Level: zapcore.InfoLevel,
LoggerName: "logger-name-01",
},
zapFields: nil,
expected: logrus.Fields{
"logModule": "kopia/module-04",
"logger name": "logger-name-01",
},
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
m := getLogFields(tc.pairs...)
log := kopiaLog{
module: tc.module,
logger: test.NewLogger(),
}
m := log.logrusFieldsForWrite(tc.zapEntry, tc.zapFields)
require.Equal(t, tc.expected, m)
})