From 0d38bb1850801605642a828b259e2f37613e4806 Mon Sep 17 00:00:00 2001 From: jmontesi Date: Tue, 28 Nov 2023 11:53:37 +0100 Subject: [PATCH 1/5] log: add new log package that uses slog as global logger The log package provides top-level funtions for creating log records in four different log levels as well as some other helper functions to set up the logging parameters and create special log handlers. Two slog handlers are created: the MultiHandler that allows distributing the logs to several io.Writer objects and the CustomHandler to produce the log output in a specifc format. The certdb.Check type is also modified to add two new fields: a logger and a log archive where the check's log will be stored. The check's logger has the two handlers described above chained, so that the log output is written to the log file and to the check's log archive. A log file has been created with a default name cnf-test-log. Only a couple of log lines have been produces using this new logger as an example. The bulk of the work for converting the old log lines so that they use the new package will be done in a separate change. --- .gitignore | 1 + Makefile | 2 +- cnf-certification-test/manageability/suite.go | 2 +- cnf-certification-test/observability/suite.go | 8 +- cnf-certification-test/performance/suite.go | 2 +- internal/log/custom_handler.go | 117 ++++++++++++++++++ internal/log/log.go | 58 +++++++++ internal/log/multi_handler.go | 52 ++++++++ main.go | 67 ++++++---- pkg/certsuite/certsuite.go | 9 ++ pkg/checksdb/check.go | 39 +++++- 11 files changed, 326 insertions(+), 31 deletions(-) create mode 100644 internal/log/custom_handler.go create mode 100644 internal/log/log.go create mode 100644 internal/log/multi_handler.go diff --git a/.gitignore b/.gitignore index fee10a1ed..18990b958 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ catalog.json claim.json tnf-execution.log cnf-certification-test/tnf-execution.log +cnf-certification-test/cnf-test-log .idea vendor *.test diff --git a/Makefile b/Makefile index a296c61fb..e4ea5492d 100644 --- a/Makefile +++ b/Makefile @@ -115,7 +115,7 @@ build-cnf-tests: results-html # build the CNF test binary for local development dev: - PATH=${PATH}:${GOBIN} go build -ldflags "${LINKER_TNF_RELEASE_FLAGS}" ./cnf-certification-test + PATH=${PATH}:${GOBIN} go build -ldflags "${LINKER_TNF_RELEASE_FLAGS}" -o ./cnf-certification-test # Builds the CNF test binary with debug flags build-cnf-tests-debug: results-html diff --git a/cnf-certification-test/manageability/suite.go b/cnf-certification-test/manageability/suite.go index bd6b2c3e4..0b3bf73e1 100644 --- a/cnf-certification-test/manageability/suite.go +++ b/cnf-certification-test/manageability/suite.go @@ -46,7 +46,7 @@ var ( } ) -func init() { +func LoadChecks() { logrus.Debugf("Entering %s suite", common.ManageabilityTestKey) checksGroup := checksdb.NewChecksGroup(common.ManageabilityTestKey). diff --git a/cnf-certification-test/observability/suite.go b/cnf-certification-test/observability/suite.go index 56272f487..f4728bd39 100644 --- a/cnf-certification-test/observability/suite.go +++ b/cnf-certification-test/observability/suite.go @@ -28,6 +28,7 @@ import ( pdbv1 "github.com/test-network-function/cnf-certification-test/cnf-certification-test/observability/pdb" "github.com/test-network-function/cnf-certification-test/internal/clientsholder" + "github.com/test-network-function/cnf-certification-test/internal/log" "github.com/test-network-function/cnf-certification-test/pkg/checksdb" "github.com/test-network-function/cnf-certification-test/pkg/provider" "github.com/test-network-function/cnf-certification-test/pkg/testhelper" @@ -45,8 +46,9 @@ var ( } ) -func init() { +func LoadChecks() { logrus.Debugf("Entering %s suite", common.ObservabilityTestKey) + log.Debug("Loading %s suite checks", common.ObservabilityTestKey) checksGroup := checksdb.NewChecksGroup(common.ObservabilityTestKey). WithBeforeEachFn(beforeEachFn) @@ -124,13 +126,16 @@ func containerHasLoggingOutput(cut *provider.Container) (bool, error) { func testContainersLogging(check *checksdb.Check, env *provider.TestEnvironment) { // Iterate through all the CUTs to get their log output. The TC checks that at least // one log line is found. + check.LogInfo("Entering testContainersLogging") var compliantObjects []*testhelper.ReportObject var nonCompliantObjects []*testhelper.ReportObject for _, cut := range env.Containers { logrus.Info(fmt.Sprintf("Checking %s has some logging output", cut)) + check.LogInfo("Container %s has some logging output", cut) hasLoggingOutput, err := containerHasLoggingOutput(cut) if err != nil { tnf.Logf(logrus.ErrorLevel, "Failed to get %s log output: %s", cut, err) + check.LogError("Failed to get container %s log output, err: %v", cut, err) nonCompliantObjects = append(nonCompliantObjects, testhelper.NewContainerReportObject(cut.Namespace, cut.Podname, cut.Name, "Could not get log output", false)) continue @@ -138,6 +143,7 @@ func testContainersLogging(check *checksdb.Check, env *provider.TestEnvironment) if !hasLoggingOutput { tnf.Logf(logrus.ErrorLevel, "%s does not have any line of log to stderr/stdout", cut) + check.LogError("Container %s does not have any line of log to stderr/stdout", cut) nonCompliantObjects = append(nonCompliantObjects, testhelper.NewContainerReportObject(cut.Namespace, cut.Podname, cut.Name, "No log line to stderr/stdout found", false)) } else { diff --git a/cnf-certification-test/performance/suite.go b/cnf-certification-test/performance/suite.go index ce07894a2..0ca440412 100644 --- a/cnf-certification-test/performance/suite.go +++ b/cnf-certification-test/performance/suite.go @@ -83,7 +83,7 @@ var ( ) //nolint:funlen -func init() { +func LoadChecks() { logrus.Debugf("Entering %s suite", common.PerformanceTestKey) checksGroup := checksdb.NewChecksGroup(common.PerformanceTestKey). diff --git a/internal/log/custom_handler.go b/internal/log/custom_handler.go new file mode 100644 index 000000000..8bf1f096c --- /dev/null +++ b/internal/log/custom_handler.go @@ -0,0 +1,117 @@ +package log + +import ( + "context" + "fmt" + "io" + "log/slog" + "path/filepath" + "runtime" + "sync" + "time" +) + +type CustomHandler struct { + opts Options + attrs []slog.Attr + mu *sync.Mutex + out io.Writer +} + +type Options struct { + // Level reports the minimum level to log. + // Levels with lower levels are discarded. + // If nil, the Handler uses [slog.LevelInfo]. + Level slog.Leveler +} + +func NewCustomHandler(out io.Writer, opts *Options) *CustomHandler { + h := &CustomHandler{out: out, mu: &sync.Mutex{}} + if opts != nil { + h.opts = *opts + } + if h.opts.Level == nil { + h.opts.Level = slog.LevelInfo + } + return h +} + +func (h *CustomHandler) Enabled(ctx context.Context, level slog.Level) bool { + return level >= h.opts.Level.Level() +} + +// The Handle method will write a log line with the following format: +// LOG_LEVEL [TIME] [SOURCE_FILE] [CUSTOM_ATTRS] MSG +func (h *CustomHandler) Handle(ctx context.Context, r slog.Record) error { + buf := make([]byte, 0, 1024) + // Level + buf = h.appendAttr(buf, slog.Any(slog.LevelKey, r.Level)) + // Time + if !r.Time.IsZero() { + buf = h.appendAttr(buf, slog.Time(slog.TimeKey, r.Time)) + } + // Source + if r.PC != 0 { + fs := runtime.CallersFrames([]uintptr{r.PC}) + f, _ := fs.Next() + buf = h.appendAttr(buf, slog.String(slog.SourceKey, fmt.Sprintf("%s: %d", filepath.Base(f.File), f.Line))) + } + // Attributes + for _, attr := range h.attrs { + buf = h.appendAttr(buf, attr) + } + // Message + buf = h.appendAttr(buf, slog.String(slog.MessageKey, r.Message)) + buf = append(buf, "\n"...) + h.mu.Lock() + defer h.mu.Unlock() + _, err := h.out.Write(buf) + return err +} + +// Not implemented. WithGroup just returns the same handler. +func (h *CustomHandler) WithGroup(name string) slog.Handler { + return h +} + +func (h *CustomHandler) WithAttrs(attrs []slog.Attr) slog.Handler { + if len(attrs) == 0 { + return h + } + + // Create a new handler with default attributes + h2 := *h + // A deep copy of the attributes is required + h2.attrs = make([]slog.Attr, len(h.attrs)+len(attrs)) + copy(h2.attrs, h.attrs) + h2.attrs = append(h2.attrs, attrs...) + + return &h2 +} + +func (h *CustomHandler) appendAttr(buf []byte, a slog.Attr) []byte { + // Resolve the Attr's value before doing anything else. + a.Value = a.Value.Resolve() + // Ignore empty Attrs. + if a.Equal(slog.Attr{}) { + return buf + } + switch a.Value.Kind() { + case slog.KindString: + if a.Key == slog.MessageKey { + buf = fmt.Appendf(buf, "%s ", a.Value.String()) + } else { + buf = fmt.Appendf(buf, "[%s] ", a.Value.String()) + + } + case slog.KindTime: + buf = fmt.Appendf(buf, "[%s] ", a.Value.Time().Format(time.StampMilli)) + default: + if a.Key == slog.LevelKey { + buf = fmt.Appendf(buf, "%-5s ", a.Value.String()) + } else { + buf = fmt.Appendf(buf, "[%s: %s] ", a.Key, a.Value) + } + } + return buf +} diff --git a/internal/log/log.go b/internal/log/log.go new file mode 100644 index 000000000..48e03c358 --- /dev/null +++ b/internal/log/log.go @@ -0,0 +1,58 @@ +package log + +import ( + "context" + "fmt" + "io" + "log/slog" + "runtime" + "time" +) + +type Logger struct { + *slog.Logger +} + +var logger *slog.Logger + +func SetupLogger(logWriter io.Writer) { + opts := Options{ + Level: slog.LevelDebug, + } + logger = slog.New(NewCustomHandler(logWriter, &opts)) +} + +func Debug(msg string, args ...any) { + Logf(logger, slog.LevelDebug, msg, args...) +} + +func Info(msg string, args ...any) { + Logf(logger, slog.LevelInfo, msg, args...) +} + +func Warn(msg string, args ...any) { + Logf(logger, slog.LevelWarn, msg, args...) +} + +func Error(msg string, args ...any) { + Logf(logger, slog.LevelError, msg, args...) +} + +func GetMultiLogger(w io.Writer) *slog.Logger { + opts := Options{ + Level: slog.LevelDebug, + } + return slog.New(NewMultiHandler(logger.Handler(), NewCustomHandler(w, &opts))) +} + +// The Logf function should be called inside a log wrapper function. +// Otherwise the code source reference will be invalid. +func Logf(logger *slog.Logger, level slog.Level, format string, args ...any) { + if !logger.Enabled(context.Background(), level) { + return + } + var pcs [1]uintptr + runtime.Callers(3, pcs[:]) // skip [Callers, Log, LogWrapper] + r := slog.NewRecord(time.Now(), level, fmt.Sprintf(format, args...), pcs[0]) + _ = logger.Handler().Handle(context.Background(), r) +} diff --git a/internal/log/multi_handler.go b/internal/log/multi_handler.go new file mode 100644 index 000000000..b7e23c9f0 --- /dev/null +++ b/internal/log/multi_handler.go @@ -0,0 +1,52 @@ +package log + +import ( + "context" + "log/slog" +) + +type MultiHandler struct { + handlers []slog.Handler +} + +func NewMultiHandler(handlers ...slog.Handler) *MultiHandler { + return &MultiHandler{ + handlers: handlers, + } +} + +func (h *MultiHandler) Enabled(ctx context.Context, level slog.Level) bool { + for i := range h.handlers { + if h.handlers[i].Enabled(ctx, level) { + return true + } + } + + return false +} + +func (h *MultiHandler) Handle(ctx context.Context, r slog.Record) error { + for i := range h.handlers { + if err := h.handlers[i].Handle(ctx, r.Clone()); err != nil { + return err + } + } + + return nil +} + +func (h *MultiHandler) WithAttrs(attrs []slog.Attr) slog.Handler { + handlersWithAttrs := make([]slog.Handler, len(h.handlers)) + for i := range h.handlers { + handlersWithAttrs[i] = h.handlers[i].WithAttrs(attrs) + } + return NewMultiHandler(handlersWithAttrs...) +} + +func (h *MultiHandler) WithGroup(name string) slog.Handler { + handlersWithGroup := make([]slog.Handler, len(h.handlers)) + for i := range h.handlers { + handlersWithGroup[i] = h.handlers[i].WithGroup(name) + } + return NewMultiHandler(handlersWithGroup...) +} diff --git a/main.go b/main.go index effcc5341..1a7108c66 100644 --- a/main.go +++ b/main.go @@ -19,25 +19,20 @@ package main import ( _ "embed" "flag" + "fmt" "os" "path/filepath" "time" - log "github.com/sirupsen/logrus" + "github.com/sirupsen/logrus" "github.com/test-network-function/cnf-certification-test/pkg/certsuite" "github.com/test-network-function/cnf-certification-test/pkg/loghelper" "github.com/test-network-function/cnf-certification-test/pkg/versions" - _ "github.com/test-network-function/cnf-certification-test/cnf-certification-test/accesscontrol" - _ "github.com/test-network-function/cnf-certification-test/cnf-certification-test/certification" - _ "github.com/test-network-function/cnf-certification-test/cnf-certification-test/lifecycle" - _ "github.com/test-network-function/cnf-certification-test/cnf-certification-test/manageability" - _ "github.com/test-network-function/cnf-certification-test/cnf-certification-test/networking" - _ "github.com/test-network-function/cnf-certification-test/cnf-certification-test/observability" - _ "github.com/test-network-function/cnf-certification-test/cnf-certification-test/performance" "github.com/test-network-function/cnf-certification-test/cnf-certification-test/webserver" "github.com/test-network-function/cnf-certification-test/internal/clientsholder" + "github.com/test-network-function/cnf-certification-test/internal/log" "github.com/test-network-function/cnf-certification-test/pkg/configuration" ) @@ -50,6 +45,8 @@ const ( TNFReportKey = "cnf-certification-test" extraInfoKey = "testsExtraInfo" noLabelsExpr = "none" + logFileName = "cnf-test-log" + logFilePermissions = 0o644 ) const ( @@ -103,14 +100,14 @@ func init() { func setLogLevel() { params := configuration.GetTestParameters() - var logLevel, err = log.ParseLevel(params.LogLevel) + var logLevel, err = logrus.ParseLevel(params.LogLevel) if err != nil { - log.Error("TNF_LOG_LEVEL environment set with an invalid value, defaulting to DEBUG \n Valid values are: trace, debug, info, warn, error, fatal, panic") - logLevel = log.DebugLevel + logrus.Error("TNF_LOG_LEVEL environment set with an invalid value, defaulting to DEBUG \n Valid values are: trace, debug, info, warn, error, fatal, panic") + logLevel = logrus.DebugLevel } - log.Info("Log level set to: ", logLevel) - log.SetLevel(logLevel) + logrus.Info("Log level set to: ", logLevel) + logrus.SetLevel(logLevel) } func getK8sClientsConfigFileNames() []string { @@ -130,42 +127,66 @@ func getK8sClientsConfigFileNames() []string { func main() { err := configuration.LoadEnvironmentVariables() if err != nil { - log.Fatalf("could not load the environment variables, error: %v", err) + fmt.Fprintf(os.Stderr, "could not load the environment variables, err: %v", err) + os.Exit(1) } // Set up logging params for logrus loghelper.SetLogFormat() setLogLevel() - log.Infof("TNF Version : %v", versions.GitVersion()) - log.Infof("Claim Format Version: %s", versions.ClaimFormatVersion) - log.Infof("Labels filter : %v", *labelsFlag) + // Set up logger + err = os.Remove(logFileName) + if err != nil && !os.IsNotExist(err) { + fmt.Fprintf(os.Stderr, "could not delete old log file, err: %v", err) + os.Exit(1) + } + + logFile, err := os.OpenFile(logFileName, os.O_RDWR|os.O_CREATE, logFilePermissions) + if err != nil { + fmt.Fprintf(os.Stderr, "could not create log file, err: %v", err) + os.Exit(1) + } + defer logFile.Close() + + log.SetupLogger(logFile) + log.Info("Log file: %s", logFileName) + + certsuite.LoadChecksDB() + + logrus.Infof("TNF Version : %v", versions.GitVersion()) + logrus.Infof("Claim Format Version: %s", versions.ClaimFormatVersion) + logrus.Infof("Labels filter : %v", *labelsFlag) + + log.Info("TNF Version : %v", versions.GitVersion()) + log.Info("Claim Format Version: %s", versions.ClaimFormatVersion) + log.Info("Labels filter : %v", *labelsFlag) if *listFlag { // ToDo: List all the available checks, filtered with --labels. - log.Errorf("Not implemented yet.") + logrus.Errorf("Not implemented yet.") os.Exit(1) } // Diagnostic functions will run when no labels are provided. if *labelsFlag == noLabelsExpr { - log.Warnf("CNF Certification Suite will run in diagnostic mode so no test case will be launched.") + logrus.Warnf("CNF Certification Suite will run in diagnostic mode so no test case will be launched.") } var timeout time.Duration timeout, err = time.ParseDuration(*timeoutFlag) if err != nil { - log.Errorf("Failed to parse timeout flag %v: %v, using default timeout value %v", *timeoutFlag, err, timeoutFlagDefaultvalue) + logrus.Errorf("Failed to parse timeout flag %v: %v, using default timeout value %v", *timeoutFlag, err, timeoutFlagDefaultvalue) timeout = timeoutFlagDefaultvalue } // Set clientsholder singleton with the filenames from the env vars. - log.Infof("Output folder for the claim file: %s", *claimPath) + logrus.Infof("Output folder for the claim file: %s", *claimPath) if *serverModeFlag { - log.Info("Running CNF Certification Suite in web server mode.") + logrus.Info("Running CNF Certification Suite in web server mode.") webserver.StartServer(*claimPath) } else { - log.Info("Running CNF Certification Suite in stand-alone mode.") + logrus.Info("Running CNF Certification Suite in stand-alone mode.") _ = clientsholder.GetClientsHolder(getK8sClientsConfigFileNames()...) certsuite.Run(*labelsFlag, *claimPath, timeout) } diff --git a/pkg/certsuite/certsuite.go b/pkg/certsuite/certsuite.go index 225032bd6..458fa3243 100644 --- a/pkg/certsuite/certsuite.go +++ b/pkg/certsuite/certsuite.go @@ -6,6 +6,9 @@ import ( "time" "github.com/sirupsen/logrus" + "github.com/test-network-function/cnf-certification-test/cnf-certification-test/manageability" + "github.com/test-network-function/cnf-certification-test/cnf-certification-test/observability" + "github.com/test-network-function/cnf-certification-test/cnf-certification-test/performance" "github.com/test-network-function/cnf-certification-test/cnf-certification-test/results" "github.com/test-network-function/cnf-certification-test/pkg/checksdb" "github.com/test-network-function/cnf-certification-test/pkg/claimhelper" @@ -14,6 +17,12 @@ import ( "github.com/test-network-function/cnf-certification-test/pkg/provider" ) +func LoadChecksDB() { + manageability.LoadChecks() + observability.LoadChecks() + performance.LoadChecks() +} + func Run(labelsFilter, outputFolder string, timeout time.Duration) { var env provider.TestEnvironment env.SetNeedsRefresh() diff --git a/pkg/checksdb/check.go b/pkg/checksdb/check.go index 5bc0572ea..1fa97af2b 100644 --- a/pkg/checksdb/check.go +++ b/pkg/checksdb/check.go @@ -2,10 +2,13 @@ package checksdb import ( "fmt" + "log/slog" + "strings" "sync" "time" "github.com/sirupsen/logrus" + "github.com/test-network-function/cnf-certification-test/internal/log" "github.com/test-network-function/cnf-certification-test/pkg/testhelper" ) @@ -45,17 +48,45 @@ type Check struct { CapturedOutput string FailureReason string + logger *slog.Logger + logArchive *strings.Builder + StartTime, EndTime time.Time Timeout time.Duration Error error } func NewCheck(id string, labels []string) *Check { - return &Check{ - ID: id, - Labels: labels, - Result: CheckResultPassed, + check := &Check{ + ID: id, + Labels: labels, + Result: CheckResultPassed, + logArchive: &strings.Builder{}, } + + check.logger = log.GetMultiLogger(check.logArchive).With("check", check.ID) + + return check +} + +func (check *Check) LogDebug(msg string, args ...any) { + log.Logf(check.logger, slog.LevelDebug, msg, args...) +} + +func (check *Check) LogInfo(msg string, args ...any) { + log.Logf(check.logger, slog.LevelInfo, msg, args...) +} + +func (check *Check) LogWarn(msg string, args ...any) { + log.Logf(check.logger, slog.LevelWarn, msg, args...) +} + +func (check *Check) LogError(msg string, args ...any) { + log.Logf(check.logger, slog.LevelError, msg, args...) +} + +func (check *Check) GetLogs() string { + return check.logArchive.String() } func (check *Check) WithCheckFn(checkFn func(check *Check) error) *Check { From e01a617e72a03411c9e26494dde762a1d0a9729d Mon Sep 17 00:00:00 2001 From: jmontesi Date: Tue, 28 Nov 2023 13:15:01 +0100 Subject: [PATCH 2/5] Add new suites and fix linting errors --- cnf-certification-test/accesscontrol/suite.go | 2 +- cnf-certification-test/certification/suite.go | 2 +- cnf-certification-test/lifecycle/suite.go | 2 +- cnf-certification-test/networking/suite.go | 2 +- internal/log/custom_handler.go | 11 ++++++----- internal/log/log.go | 3 ++- internal/log/multi_handler.go | 1 + main.go | 3 ++- pkg/certsuite/certsuite.go | 8 ++++++++ 9 files changed, 23 insertions(+), 11 deletions(-) diff --git a/cnf-certification-test/accesscontrol/suite.go b/cnf-certification-test/accesscontrol/suite.go index 468e63f23..b56c75cb8 100644 --- a/cnf-certification-test/accesscontrol/suite.go +++ b/cnf-certification-test/accesscontrol/suite.go @@ -65,7 +65,7 @@ var ( ) //nolint:funlen -func init() { +func LoadChecks() { logrus.Debugf("Entering %s suite", common.AccessControlTestKey) checksGroup := checksdb.NewChecksGroup(common.AccessControlTestKey). diff --git a/cnf-certification-test/certification/suite.go b/cnf-certification-test/certification/suite.go index 748e243bc..87c368773 100644 --- a/cnf-certification-test/certification/suite.go +++ b/cnf-certification-test/certification/suite.go @@ -75,7 +75,7 @@ var ( } ) -func init() { +func LoadChecks() { logrus.Debugf("Entering %s suite", common.AffiliatedCertTestKey) checksGroup := checksdb.NewChecksGroup(common.AffiliatedCertTestKey). diff --git a/cnf-certification-test/lifecycle/suite.go b/cnf-certification-test/lifecycle/suite.go index 9a1daa674..83bf6ac51 100644 --- a/cnf-certification-test/lifecycle/suite.go +++ b/cnf-certification-test/lifecycle/suite.go @@ -67,7 +67,7 @@ var ( ) //nolint:funlen -func init() { +func LoadChecks() { logrus.Debugf("Entering %s suite", common.LifecycleTestKey) checksGroup := checksdb.NewChecksGroup(common.LifecycleTestKey). diff --git a/cnf-certification-test/networking/suite.go b/cnf-certification-test/networking/suite.go index bf29f79b3..1b79fa021 100644 --- a/cnf-certification-test/networking/suite.go +++ b/cnf-certification-test/networking/suite.go @@ -57,7 +57,7 @@ var ( ) //nolint:funlen -func init() { +func LoadChecks() { logrus.Debugf("Entering %s suite", common.NetworkingTestKey) checksGroup := checksdb.NewChecksGroup(common.NetworkingTestKey). diff --git a/internal/log/custom_handler.go b/internal/log/custom_handler.go index 8bf1f096c..712dbe2e8 100644 --- a/internal/log/custom_handler.go +++ b/internal/log/custom_handler.go @@ -36,14 +36,16 @@ func NewCustomHandler(out io.Writer, opts *Options) *CustomHandler { return h } -func (h *CustomHandler) Enabled(ctx context.Context, level slog.Level) bool { +func (h *CustomHandler) Enabled(_ context.Context, level slog.Level) bool { return level >= h.opts.Level.Level() } // The Handle method will write a log line with the following format: // LOG_LEVEL [TIME] [SOURCE_FILE] [CUSTOM_ATTRS] MSG -func (h *CustomHandler) Handle(ctx context.Context, r slog.Record) error { - buf := make([]byte, 0, 1024) +// +//nolint:gocritic +func (h *CustomHandler) Handle(_ context.Context, r slog.Record) error { + buf := make([]byte, 0, 1024) //nolint:gomnd // Level buf = h.appendAttr(buf, slog.Any(slog.LevelKey, r.Level)) // Time @@ -70,7 +72,7 @@ func (h *CustomHandler) Handle(ctx context.Context, r slog.Record) error { } // Not implemented. WithGroup just returns the same handler. -func (h *CustomHandler) WithGroup(name string) slog.Handler { +func (h *CustomHandler) WithGroup(_ string) slog.Handler { return h } @@ -102,7 +104,6 @@ func (h *CustomHandler) appendAttr(buf []byte, a slog.Attr) []byte { buf = fmt.Appendf(buf, "%s ", a.Value.String()) } else { buf = fmt.Appendf(buf, "[%s] ", a.Value.String()) - } case slog.KindTime: buf = fmt.Appendf(buf, "[%s] ", a.Value.Time().Format(time.StampMilli)) diff --git a/internal/log/log.go b/internal/log/log.go index 48e03c358..12be527ce 100644 --- a/internal/log/log.go +++ b/internal/log/log.go @@ -52,7 +52,8 @@ func Logf(logger *slog.Logger, level slog.Level, format string, args ...any) { return } var pcs [1]uintptr - runtime.Callers(3, pcs[:]) // skip [Callers, Log, LogWrapper] + // skip [Callers, Log, LogWrapper] + runtime.Callers(3, pcs[:]) //nolint:gomnd r := slog.NewRecord(time.Now(), level, fmt.Sprintf(format, args...), pcs[0]) _ = logger.Handler().Handle(context.Background(), r) } diff --git a/internal/log/multi_handler.go b/internal/log/multi_handler.go index b7e23c9f0..92b8f0e03 100644 --- a/internal/log/multi_handler.go +++ b/internal/log/multi_handler.go @@ -25,6 +25,7 @@ func (h *MultiHandler) Enabled(ctx context.Context, level slog.Level) bool { return false } +//nolint:gocritic func (h *MultiHandler) Handle(ctx context.Context, r slog.Record) error { for i := range h.handlers { if err := h.handlers[i].Handle(ctx, r.Clone()); err != nil { diff --git a/main.go b/main.go index 1a7108c66..c15b16699 100644 --- a/main.go +++ b/main.go @@ -124,6 +124,7 @@ func getK8sClientsConfigFileNames() []string { return fileNames } +//nolint:funlen func main() { err := configuration.LoadEnvironmentVariables() if err != nil { @@ -165,7 +166,7 @@ func main() { if *listFlag { // ToDo: List all the available checks, filtered with --labels. logrus.Errorf("Not implemented yet.") - os.Exit(1) + os.Exit(1) //nolint:gocritic } // Diagnostic functions will run when no labels are provided. diff --git a/pkg/certsuite/certsuite.go b/pkg/certsuite/certsuite.go index 458fa3243..1108c304a 100644 --- a/pkg/certsuite/certsuite.go +++ b/pkg/certsuite/certsuite.go @@ -6,7 +6,11 @@ import ( "time" "github.com/sirupsen/logrus" + "github.com/test-network-function/cnf-certification-test/cnf-certification-test/accesscontrol" + "github.com/test-network-function/cnf-certification-test/cnf-certification-test/certification" + "github.com/test-network-function/cnf-certification-test/cnf-certification-test/lifecycle" "github.com/test-network-function/cnf-certification-test/cnf-certification-test/manageability" + "github.com/test-network-function/cnf-certification-test/cnf-certification-test/networking" "github.com/test-network-function/cnf-certification-test/cnf-certification-test/observability" "github.com/test-network-function/cnf-certification-test/cnf-certification-test/performance" "github.com/test-network-function/cnf-certification-test/cnf-certification-test/results" @@ -18,7 +22,11 @@ import ( ) func LoadChecksDB() { + accesscontrol.LoadChecks() + certification.LoadChecks() + lifecycle.LoadChecks() manageability.LoadChecks() + networking.LoadChecks() observability.LoadChecks() performance.LoadChecks() } From 257437af557ad5f0debd8c61b68dc3327505ffce Mon Sep 17 00:00:00 2001 From: jmontesi Date: Wed, 29 Nov 2023 16:15:15 +0100 Subject: [PATCH 3/5] Some small changes --- internal/log/custom_handler.go | 8 ++++---- main.go | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/internal/log/custom_handler.go b/internal/log/custom_handler.go index 712dbe2e8..1b5b82882 100644 --- a/internal/log/custom_handler.go +++ b/internal/log/custom_handler.go @@ -43,9 +43,9 @@ func (h *CustomHandler) Enabled(_ context.Context, level slog.Level) bool { // The Handle method will write a log line with the following format: // LOG_LEVEL [TIME] [SOURCE_FILE] [CUSTOM_ATTRS] MSG // -//nolint:gocritic +//nolint:gocritic // r param is heavy but defined in the slog.Handler interface func (h *CustomHandler) Handle(_ context.Context, r slog.Record) error { - buf := make([]byte, 0, 1024) //nolint:gomnd + var buf []byte // Level buf = h.appendAttr(buf, slog.Any(slog.LevelKey, r.Level)) // Time @@ -71,9 +71,9 @@ func (h *CustomHandler) Handle(_ context.Context, r slog.Record) error { return err } -// Not implemented. WithGroup just returns the same handler. +// Not implemented. Returns the nil handler. func (h *CustomHandler) WithGroup(_ string) slog.Handler { - return h + return nil } func (h *CustomHandler) WithAttrs(attrs []slog.Attr) slog.Handler { diff --git a/main.go b/main.go index 81184868c..51c8a4fc6 100644 --- a/main.go +++ b/main.go @@ -45,7 +45,7 @@ const ( TNFReportKey = "cnf-certification-test" extraInfoKey = "testsExtraInfo" noLabelsExpr = "none" - logFileName = "cnf-test-log" + logFileName = "cnf-certsuite.log" logFilePermissions = 0o644 ) From 17ef07ad7c903de244fc5eceb3c90e3d2d6fbb9a Mon Sep 17 00:00:00 2001 From: jmontesi Date: Wed, 29 Nov 2023 17:22:16 +0100 Subject: [PATCH 4/5] Remove some log lines --- main.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/main.go b/main.go index 51c8a4fc6..dfd3b0c74 100644 --- a/main.go +++ b/main.go @@ -159,10 +159,6 @@ func main() { logrus.Infof("Claim Format Version: %s", versions.ClaimFormatVersion) logrus.Infof("Labels filter : %v", *labelsFlag) - log.Info("TNF Version : %v", versions.GitVersion()) - log.Info("Claim Format Version: %s", versions.ClaimFormatVersion) - log.Info("Labels filter : %v", *labelsFlag) - certsuite.LoadChecksDB() if *listFlag { From f037993669635eff927b697eefeb96a208476791 Mon Sep 17 00:00:00 2001 From: jmontesi Date: Thu, 30 Nov 2023 09:30:47 +0100 Subject: [PATCH 5/5] Fix log lines --- main.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.go b/main.go index ee9362683..b9a4c1b97 100644 --- a/main.go +++ b/main.go @@ -121,11 +121,11 @@ func getK8sClientsConfigFileNames() []string { kubeConfigFilePath := filepath.Join(params.Home, ".kube", "config") // Check if the kubeconfig path exists if _, err := os.Stat(kubeConfigFilePath); err == nil { - log.Infof("kubeconfig path %s is present", kubeConfigFilePath) + logrus.Infof("kubeconfig path %s is present", kubeConfigFilePath) // Only add the kubeconfig to the list of paths if it exists, since it is not added by the user fileNames = append(fileNames, kubeConfigFilePath) } else { - log.Infof("kubeconfig path %s is not present", kubeConfigFilePath) + logrus.Infof("kubeconfig path %s is not present", kubeConfigFilePath) } }