From 0c136d53d2a5785d5522dd4aeb5fb0a089097040 Mon Sep 17 00:00:00 2001 From: Adrien CABARBAYE Date: Mon, 13 Nov 2023 13:03:08 +0000 Subject: [PATCH] :sparkles: [`logs`] Add a `logr.Logger` quiet logger to only log errors (#368) ### Description - Add a quiet logger so that only error messages are logged ### Test Coverage - [x] This change is covered by existing or additional automated tests. - [ ] Manual testing has been performed (and evidence provided) as automated testing was not feasible. - [ ] Additional tests are not required for this change (e.g. documentation update). --- changes/20231113111138.feature | 1 + utils/logs/logrimp/quiet_logger.go | 40 +++++++++++++++++ utils/logs/logrimp/quiet_logger_test.go | 60 +++++++++++++++++++++++++ 3 files changed, 101 insertions(+) create mode 100644 changes/20231113111138.feature create mode 100644 utils/logs/logrimp/quiet_logger.go create mode 100644 utils/logs/logrimp/quiet_logger_test.go diff --git a/changes/20231113111138.feature b/changes/20231113111138.feature new file mode 100644 index 0000000000..8738595c9c --- /dev/null +++ b/changes/20231113111138.feature @@ -0,0 +1 @@ +:sparkles: [`logs`] Add a `logr.Logger` quiet logger to only log errors diff --git a/utils/logs/logrimp/quiet_logger.go b/utils/logs/logrimp/quiet_logger.go new file mode 100644 index 0000000000..177f2fbe2d --- /dev/null +++ b/utils/logs/logrimp/quiet_logger.go @@ -0,0 +1,40 @@ +package logrimp + +import ( + "github.com/go-logr/logr" +) + +type quietLogger struct { + logger logr.Logger +} + +func (l *quietLogger) Init(_ logr.RuntimeInfo) { + // ignored. +} + +func (l *quietLogger) Enabled(int) bool { + return false +} + +func (l *quietLogger) Info(_ int, _ string, _ ...any) { + // Ignored. +} + +func (l *quietLogger) Error(err error, msg string, keysAndValues ...any) { + l.logger.Error(err, msg, keysAndValues...) +} + +func (l *quietLogger) WithValues(keysAndValues ...any) logr.LogSink { + l.logger.WithValues(keysAndValues...) + return l +} + +func (l *quietLogger) WithName(name string) logr.LogSink { + l.logger.WithName(name) + return l +} + +// NewQuietLogger returns a quiet logger which only logs errors. +func NewQuietLogger(logger logr.Logger) logr.Logger { + return logr.New(&quietLogger{logger: logger}) +} diff --git a/utils/logs/logrimp/quiet_logger_test.go b/utils/logs/logrimp/quiet_logger_test.go new file mode 100644 index 0000000000..1f32e233d6 --- /dev/null +++ b/utils/logs/logrimp/quiet_logger_test.go @@ -0,0 +1,60 @@ +package logrimp + +import ( + "os" + "testing" + + "github.com/bxcodec/faker/v3" + "github.com/go-logr/logr" + "github.com/hashicorp/go-hclog" + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/require" + "go.uber.org/zap" + "golang.org/x/exp/slog" + + "github.com/ARM-software/golang-utils/utils/commonerrors" +) + +func TestQuietLoggerImplementations(t *testing.T) { + zl, err := zap.NewDevelopment() + require.NoError(t, err) + tests := []struct { + Logger logr.Logger + name string + }{ + { + Logger: NewNoopLogger(), + name: "NoOp", + }, + { + Logger: NewStdOutLogr(), + name: "Standard Output", + }, + { + Logger: NewZapLogger(zl), + name: "Zap", + }, + { + Logger: NewHclogLogger(hclog.New(nil)), + name: "HClog", + }, + { + Logger: NewLogrusLogger(logrus.New()), + name: "Logrus", + }, + { + Logger: NewSlogLogger(slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{}))), + name: "slog", + }, + } + for i := range tests { + test := tests[i] + t.Run(test.name, func(t *testing.T) { + logger := NewQuietLogger(test.Logger) + logger.WithName(faker.Name()).WithValues("foo", "bar").Info(faker.Sentence()) + logger.Error(commonerrors.ErrUnexpected, faker.Sentence(), faker.Word(), faker.Name()) + }, + ) + } + +}