From c9e1594f3343e60428d83b93bf7c5ebf2287dd9a Mon Sep 17 00:00:00 2001 From: Ljubisa Gacevic Date: Mon, 3 Mar 2025 13:08:46 +0100 Subject: [PATCH 1/2] fix(check): improve format of errors on multiple checks --- pkg/check/runner.go | 92 ++++++++++++++++++++++++++++++++---------- pkg/stamper/stamper.go | 8 ++-- 2 files changed, 74 insertions(+), 26 deletions(-) diff --git a/pkg/check/runner.go b/pkg/check/runner.go index 19ecce00c..9f8f46fb7 100644 --- a/pkg/check/runner.go +++ b/pkg/check/runner.go @@ -91,39 +91,38 @@ func (c *CheckRunner) Run(ctx context.Context, checks []string) error { }) } - type errorCheck struct { - check string - err error - } - - var errors []errorCheck + checkResults := make([]checkResult, 0, len(validatedChecks)) + hasFailures := false + // run checks for _, check := range validatedChecks { c.logger.WithField("type", check.typeName).Infof("running check: %s", check.name) c.logger.Debugf("check options: %+v", check.options) - if err := check.Run(ctx, c.cluster); err != nil { - c.logger.WithField("type", check.typeName).Errorf("check '%s' failed: %v", check.name, err) - errors = append(errors, errorCheck{ - check: check.name, - err: fmt.Errorf("check %s failed: %w", check.name, err), - }) + err := check.Run(ctx, c.cluster) + if err != nil { + hasFailures = true + c.logger.WithFields(map[string]interface{}{ + "type": check.typeName, + "error": err, + }).Errorf("'%s' check failed", check.name) } else { - c.logger.WithField("type", check.typeName).Infof("%s check completed successfully", check.name) + c.logger.WithField("type", check.typeName).Infof("'%s' check completed successfully", check.name) } + + // append check result + checkResults = append(checkResults, checkResult{ + check: check.name, + err: err, + timestamp: time.Now(), + }) } - if len(errors) == 1 { - return errors[0].err - } else if len(errors) > 1 { - var errStrings []string - for _, e := range errors { - errStrings = append(errStrings, fmt.Sprintf("[%s]: {%v}", e.check, e.err)) - c.logger.Errorf("%s: %v", e.check, e.err) - } - return fmt.Errorf("multiple checks failed: %s", strings.Join(errStrings, "; ")) + if hasFailures { + return formatErrorReport(checkResults) } + c.logger.WithField("total_checks", len(checkResults)).Info("All checks completed successfully") return nil } @@ -166,3 +165,52 @@ func createChildContext(ctx context.Context, timeout *time.Duration) (context.Co } return context.WithCancel(ctx) } + +type checkResult struct { + check string + err error + timestamp time.Time +} + +func formatErrorReport(results []checkResult) error { + var failedChecks []string + var failedDetails []string + + // if there is only one error, return it directly + if len(results) == 1 { + return results[0].err + } + + for _, result := range results { + if result.err != nil { + failedChecks = append(failedChecks, result.check) + failedDetails = append(failedDetails, result.DetailString()) + } + } + + totalChecks := len(results) + failedCount := len(failedChecks) + + return fmt.Errorf("CHECK_FAILED | %d/%d checks failed | Checks: %s | %s", + failedCount, + totalChecks, + strings.Join(failedChecks, ","), + strings.Join(failedDetails, " | ")) +} + +func (e checkResult) String() string { + if e.err != nil { + return fmt.Sprintf("%s: %v", e.check, e.err) + } + return fmt.Sprintf("%s: success", e.check) +} + +func (e checkResult) DetailString() string { + timestamp := e.timestamp.Format("2006-01-02T15:04:05") + if e.err != nil { + return fmt.Sprintf(`{"check":"%s","time":"%s","error":"%v"}`, + e.check, timestamp, e.err) + } + return fmt.Sprintf(`{"check":"%s","time":"%s","status":"success"}`, + e.check, timestamp) +} diff --git a/pkg/stamper/stamper.go b/pkg/stamper/stamper.go index 5ec8bd640..c86c3251a 100644 --- a/pkg/stamper/stamper.go +++ b/pkg/stamper/stamper.go @@ -99,7 +99,7 @@ func (s *Client) Create(ctx context.Context, duration time.Duration, depth uint1 s.log.WithFields(map[string]interface{}{ "duration": duration, "depth": depth, - }).Infof("creating postage batch on nodes") + }).Info("creating postage batch on nodes") nodes, err := s.getNodes(ctx) if err != nil { @@ -125,7 +125,7 @@ func (s *Client) Dilute(ctx context.Context, usageThreshold float64, dilutionDep s.log.WithFields(map[string]interface{}{ "usageThreshold": usageThreshold, "dilutionDepth": dilutionDepth, - }).Infof("diluting postage batch on nodes") + }).Info("diluting postage batch on nodes") nodes, err := s.getNodes(ctx) if err != nil { @@ -148,7 +148,7 @@ func (s *Client) Set(ctx context.Context, ttlThreshold time.Duration, topupTo ti "topupTo": topupTo, "usageThreshold": usageThreshold, "dilutionDepth": dilutionDepth, - }).Infof("setting topup and dilution on postage batch on nodes") + }).Info("setting topup and dilution on postage batch on nodes") nodes, err := s.getNodes(ctx) if err != nil { @@ -174,7 +174,7 @@ func (s *Client) Topup(ctx context.Context, ttlThreshold time.Duration, topupTo s.log.WithFields(map[string]interface{}{ "ttlThreshold": ttlThreshold, "topupTo": topupTo, - }).Infof("topup postage batch on nodes") + }).Info("topup postage batch on nodes") nodes, err := s.getNodes(ctx) if err != nil { From 3cfa34609e8577c70a37439f0f3c26e7d1954d21 Mon Sep 17 00:00:00 2001 From: Ljubisa Gacevic Date: Mon, 3 Mar 2025 13:21:15 +0100 Subject: [PATCH 2/2] fix(check): improve log when check is starting --- pkg/check/runner.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pkg/check/runner.go b/pkg/check/runner.go index 9f8f46fb7..9688a897a 100644 --- a/pkg/check/runner.go +++ b/pkg/check/runner.go @@ -96,8 +96,10 @@ func (c *CheckRunner) Run(ctx context.Context, checks []string) error { // run checks for _, check := range validatedChecks { - c.logger.WithField("type", check.typeName).Infof("running check: %s", check.name) - c.logger.Debugf("check options: %+v", check.options) + c.logger.WithFields(map[string]interface{}{ + "type": check.typeName, + "options": fmt.Sprintf("%+v", check.options), + }).Infof("running check: %s", check.name) err := check.Run(ctx, c.cluster) if err != nil {