Only print log errors to stderr if -verbose specified

Log errors are so frequent that they are drowning out fatal errors. This commit will reserve stderr for fatal errors by default. See #104 for background.

This means that operators will need to enable -verbose if they want to get details about why a health check failed.  This seems better than making stderr noisy by default. The long-term solution is #106.
This commit is contained in:
Andrew Ayer 2025-05-19 13:43:39 -04:00
parent ce80beb1d4
commit 15e35abdaa
4 changed files with 12 additions and 8 deletions

View File

@ -203,6 +203,7 @@ func main() {
ScriptDir: defaultScriptDir(),
Email: flags.email,
Stdout: flags.stdout,
Quiet: !flags.verbose,
}
config := &monitor.Config{
LogListSource: flags.logs,

View File

@ -173,7 +173,7 @@ to write a file or execute a script), it prints a message to stderr and
exits with a non-zero status.
When certspotter encounters a problem monitoring a log, it prints a message
to stderr and continues running. It will try monitoring the log again later;
to stderr if `-verbose` is specified and continues running. It will try monitoring the log again later;
most log errors are transient.
Every 24 hours (unless overridden by `-healthcheck`), certspotter performs the
@ -190,7 +190,7 @@ standard out, as described above.
Health check failures should be rare, and you should take them seriously because it means
certspotter might not detect all certificates. It might also be an indication
of CT log misbehavior. Consult certspotter's stderr output for details, and if
of CT log misbehavior. Enable the `-verbose` flag and consult stderr for details, and if
you need help, file an issue at <https://github.com/SSLMate/certspotter>.
# EXIT STATUS

View File

@ -34,6 +34,7 @@ type FilesystemState struct {
ScriptDir string
Email []string
Stdout bool
Quiet bool
}
func (s *FilesystemState) logStateDir(logID LogID) string {
@ -248,10 +249,12 @@ func (s *FilesystemState) NotifyHealthCheckFailure(ctx context.Context, ctlog *l
}
func (s *FilesystemState) NotifyError(ctx context.Context, ctlog *loglist.Log, err error) error {
if !s.Quiet {
if ctlog == nil {
log.Print(err)
} else {
log.Print(ctlog.GetMonitoringURL(), ": ", err)
}
}
return nil
}

View File

@ -120,7 +120,7 @@ func (e *StaleSTHInfo) Text() string {
text := new(strings.Builder)
fmt.Fprintf(text, "certspotter has been unable to contact %s since %s. Consequentially, certspotter may fail to notify you about certificates in this log.\n", e.Log.GetMonitoringURL(), e.LastSuccessString())
fmt.Fprintf(text, "\n")
fmt.Fprintf(text, "For details, see certspotter's stderr output.\n")
fmt.Fprintf(text, "For details, enable -verbose and see certspotter's stderr output.\n")
fmt.Fprintf(text, "\n")
if e.LatestSTH != nil {
fmt.Fprintf(text, "Latest known log size = %d\n", e.LatestSTH.TreeSize)
@ -133,7 +133,7 @@ func (e *BacklogInfo) Text() string {
text := new(strings.Builder)
fmt.Fprintf(text, "certspotter has been unable to download entries from %s in a timely manner. Consequentially, certspotter may be slow to notify you about certificates in this log.\n", e.Log.GetMonitoringURL())
fmt.Fprintf(text, "\n")
fmt.Fprintf(text, "For more details, see certspotter's stderr output.\n")
fmt.Fprintf(text, "For details, enable -verbose and see certspotter's stderr output.\n")
fmt.Fprintf(text, "\n")
fmt.Fprintf(text, "Current log size = %d (as of %s)\n", e.LatestSTH.TreeSize, e.LatestSTH.StoredAt)
fmt.Fprintf(text, "Current position = %d\n", e.Position)