From 93ca622a379515fcb2ed3b483610dcf5506f0d12 Mon Sep 17 00:00:00 2001 From: Andrew Ayer Date: Thu, 4 Apr 2024 08:09:00 -0400 Subject: [PATCH] Add NotifyError to StateProvider --- monitor/daemon.go | 2 +- monitor/errors.go | 14 ++++++++++++-- monitor/fsstate.go | 10 ++++++++++ monitor/monitor.go | 8 ++++---- monitor/state.go | 4 ++++ 5 files changed, 31 insertions(+), 7 deletions(-) diff --git a/monitor/daemon.go b/monitor/daemon.go index 2b47c16..79ca9ff 100644 --- a/monitor/daemon.go +++ b/monitor/daemon.go @@ -144,7 +144,7 @@ func (daemon *daemon) run(ctx context.Context) error { if err := daemon.loadLogList(ctx); err != nil { daemon.logListError = err.Error() daemon.logListErrorAt = time.Now() - recordError(fmt.Errorf("error reloading log list (will try again later): %w", err)) + recordError(ctx, daemon.config, nil, fmt.Errorf("error reloading log list (will try again later): %w", err)) } reloadLogListTicker.Reset(reloadLogListInterval()) case <-healthCheckTicker.C: diff --git a/monitor/errors.go b/monitor/errors.go index f43df1a..c62b874 100644 --- a/monitor/errors.go +++ b/monitor/errors.go @@ -10,9 +10,19 @@ package monitor import ( + "context" "log" + + "software.sslmate.com/src/certspotter/loglist" ) -func recordError(err error) { - log.Print(err) +func recordError(ctx context.Context, config *Config, ctlog *loglist.Log, errToRecord error) { + if err := config.State.NotifyError(ctx, ctlog, errToRecord); err != nil { + log.Printf("unable to notify about error: ", err) + if ctlog == nil { + log.Print(errToRecord) + } else { + log.Print(ctlog.URL, ": ", errToRecord) + } + } } diff --git a/monitor/fsstate.go b/monitor/fsstate.go index 550ba5b..70a2962 100644 --- a/monitor/fsstate.go +++ b/monitor/fsstate.go @@ -16,6 +16,7 @@ import ( "errors" "fmt" "io/fs" + "log" "os" "path/filepath" "strings" @@ -227,3 +228,12 @@ func (s *FilesystemState) NotifyHealthCheckFailure(ctx context.Context, ctlog *l } return nil } + +func (s *FilesystemState) NotifyError(ctx context.Context, ctlog *loglist.Log, err error) error { + if ctlog == nil { + log.Print(err) + } else { + log.Print(ctlog.URL, ":", err) + } + return nil +} diff --git a/monitor/monitor.go b/monitor/monitor.go index 3c65670..3877d1f 100644 --- a/monitor/monitor.go +++ b/monitor/monitor.go @@ -79,7 +79,7 @@ func monitorLog(ctx context.Context, config *Config, ctlog *loglist.Log, logClie if isFatalLogError(err) { return err } else if err != nil { - recordError(fmt.Errorf("error fetching latest STH for %s: %w", ctlog.URL, err)) + recordError(ctx, config, ctlog, fmt.Errorf("error fetching latest STH: %w", err)) return nil } latestSTH.LogID = ctlog.LogID @@ -97,7 +97,7 @@ func monitorLog(ctx context.Context, config *Config, ctlog *loglist.Log, logClie if isFatalLogError(err) { return err } else if err != nil { - recordError(fmt.Errorf("error reconstructing tree of size %d for %s: %w", latestSTH.TreeSize, ctlog.URL, err)) + recordError(ctx, config, ctlog, fmt.Errorf("error reconstructing tree of size %d: %w", latestSTH.TreeSize, err)) return nil } state = &LogState{ @@ -180,7 +180,7 @@ func monitorLog(ctx context.Context, config *Config, ctlog *loglist.Log, logClie for len(sths) > 0 && state.DownloadPosition.Size() == sths[0].TreeSize { if merkletree.Hash(sths[0].SHA256RootHash) != rootHash { - recordError(fmt.Errorf("error verifying %s at tree size %d: the STH root hash (%x) does not match the entries returned by the log (%x)", ctlog.URL, sths[0].TreeSize, sths[0].SHA256RootHash, rootHash)) + recordError(ctx, config, ctlog, fmt.Errorf("error verifying at tree size %d: the STH root hash (%x) does not match the entries returned by the log (%x)", sths[0].TreeSize, sths[0].SHA256RootHash, rootHash)) state.DownloadPosition = state.VerifiedPosition if err := config.State.StoreLogState(ctx, ctlog.LogID, state); err != nil { @@ -209,7 +209,7 @@ func monitorLog(ctx context.Context, config *Config, ctlog *loglist.Log, logClie if isFatalLogError(downloadErr) { return downloadErr } else if downloadErr != nil { - recordError(fmt.Errorf("error downloading entries from %s: %w", ctlog.URL, downloadErr)) + recordError(ctx, config, ctlog, fmt.Errorf("error downloading entries: %w", downloadErr)) return nil } diff --git a/monitor/state.go b/monitor/state.go index a5921ee..6595988 100644 --- a/monitor/state.go +++ b/monitor/state.go @@ -60,4 +60,8 @@ type StateProvider interface { // Called when a health check fails. The log is nil if the // feailure is not associated with a log. NotifyHealthCheckFailure(context.Context, *loglist.Log, HealthCheckFailure) error + + // Called when an error occurs. The log is nil if the error is + // not associated with a log. Note that most errors are transient. + NotifyError(context.Context, *loglist.Log, error) error }