Add NotifyError to StateProvider

This commit is contained in:
Andrew Ayer 2024-04-04 08:09:00 -04:00
parent 7bb5602d09
commit 93ca622a37
5 changed files with 31 additions and 7 deletions

View File

@ -144,7 +144,7 @@ func (daemon *daemon) run(ctx context.Context) error {
if err := daemon.loadLogList(ctx); err != nil { if err := daemon.loadLogList(ctx); err != nil {
daemon.logListError = err.Error() daemon.logListError = err.Error()
daemon.logListErrorAt = time.Now() 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()) reloadLogListTicker.Reset(reloadLogListInterval())
case <-healthCheckTicker.C: case <-healthCheckTicker.C:

View File

@ -10,9 +10,19 @@
package monitor package monitor
import ( import (
"context"
"log" "log"
"software.sslmate.com/src/certspotter/loglist"
) )
func recordError(err error) { func recordError(ctx context.Context, config *Config, ctlog *loglist.Log, errToRecord error) {
log.Print(err) 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)
}
}
} }

View File

@ -16,6 +16,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"io/fs" "io/fs"
"log"
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
@ -227,3 +228,12 @@ func (s *FilesystemState) NotifyHealthCheckFailure(ctx context.Context, ctlog *l
} }
return nil 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
}

View File

@ -79,7 +79,7 @@ func monitorLog(ctx context.Context, config *Config, ctlog *loglist.Log, logClie
if isFatalLogError(err) { if isFatalLogError(err) {
return err return err
} else if err != nil { } 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 return nil
} }
latestSTH.LogID = ctlog.LogID latestSTH.LogID = ctlog.LogID
@ -97,7 +97,7 @@ func monitorLog(ctx context.Context, config *Config, ctlog *loglist.Log, logClie
if isFatalLogError(err) { if isFatalLogError(err) {
return err return err
} else if err != nil { } 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 return nil
} }
state = &LogState{ 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 { for len(sths) > 0 && state.DownloadPosition.Size() == sths[0].TreeSize {
if merkletree.Hash(sths[0].SHA256RootHash) != rootHash { 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 state.DownloadPosition = state.VerifiedPosition
if err := config.State.StoreLogState(ctx, ctlog.LogID, state); err != nil { 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) { if isFatalLogError(downloadErr) {
return downloadErr return downloadErr
} else if downloadErr != nil { } 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 return nil
} }

View File

@ -60,4 +60,8 @@ type StateProvider interface {
// Called when a health check fails. The log is nil if the // Called when a health check fails. The log is nil if the
// feailure is not associated with a log. // feailure is not associated with a log.
NotifyHealthCheckFailure(context.Context, *loglist.Log, HealthCheckFailure) error 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
} }