Restore --cron warning visibility; show destination on blob upload
--cron used to behave like full quiet mode for everything that
wasn't an error: warnings were swallowed both in the structured
log channel (LevelError gate) and at the snapshot terminus (the
"Finished (with N warnings)" line went through ui.Complete, which
is silenced under SetQuiet). A backup that, say, hit Full Disk
Access permission errors on a handful of files and skipped them
via --skip-errors would exit 0 and emit nothing — the cron job
would never page anyone.
--cron now obeys "silent only on total success":
* log.Initialize raises the cron/quiet log level from Error to
Warn so log.Warn output still reaches stdout (and therefore
cron's mail).
* The post-backup terminus message switches to ui.Warning when
WarningCount > 0. Warning is not silenced by SetQuiet, so cron
delivers the summary line whenever the count is non-zero. The
no-warnings path keeps ui.Complete, which IS silenced under
cron — that's the success path.
Separately, blob upload UI now names the actual destination
instead of the generic "backup destination store" string. The
Begin/Info lines emit the storer's reported Location (s3://bucket,
file:///mnt/usb/backup, rclone://remote/path, etc.), so anyone
watching a backup can see exactly where each blob is landing.
This commit is contained in:
@@ -46,8 +46,12 @@ func Initialize(cfg Config) {
|
||||
var level slog.Level
|
||||
|
||||
if cfg.Cron || cfg.Quiet {
|
||||
// In quiet/cron mode, only show errors
|
||||
level = slog.LevelError
|
||||
// In cron/quiet mode keep warnings and errors visible — the
|
||||
// whole point of --cron is to stay silent only on total
|
||||
// success, so that anything cron emails to root is genuinely
|
||||
// "something went wrong, look at it." A backup with stuck
|
||||
// permission errors or skipped files should NOT be silent.
|
||||
level = slog.LevelWarn
|
||||
} else if cfg.Debug || strings.Contains(os.Getenv("GODEBUG"), "vaultik") {
|
||||
level = slog.LevelDebug
|
||||
} else if cfg.Verbose {
|
||||
|
||||
@@ -1177,16 +1177,17 @@ func (s *Scanner) uploadBlobIfNeeded(ctx context.Context, blobPath string, blobW
|
||||
finishedBlob := blobWithReader.FinishedBlob
|
||||
|
||||
// Check if blob already exists (deduplication after restart)
|
||||
destination := s.storage.Info().Location
|
||||
if _, err := s.storage.Stat(ctx, blobPath); err == nil {
|
||||
log.Info("Blob already exists in storage, skipping upload",
|
||||
"hash", finishedBlob.Hash, "size", humanize.Bytes(uint64(finishedBlob.Compressed)))
|
||||
s.ui.Info("Blob %s (%s) already exists in backup destination store. Skipping upload.",
|
||||
s.ui.Hex(finishedBlob.Hash), s.ui.Size(finishedBlob.Compressed))
|
||||
s.ui.Info("Blob %s (%s) already exists at %s. Skipping upload.",
|
||||
s.ui.Hex(finishedBlob.Hash), s.ui.Size(finishedBlob.Compressed), s.ui.Path(destination))
|
||||
return true, nil
|
||||
}
|
||||
|
||||
s.ui.Begin("Uploading blob %s (%s) to backup destination store.",
|
||||
s.ui.Hex(finishedBlob.Hash), s.ui.Size(finishedBlob.Compressed))
|
||||
s.ui.Begin("Uploading blob %s (%s) to %s.",
|
||||
s.ui.Hex(finishedBlob.Hash), s.ui.Size(finishedBlob.Compressed), s.ui.Path(destination))
|
||||
|
||||
progressCallback := s.makeUploadProgressCallback(ctx, finishedBlob, startTime)
|
||||
|
||||
|
||||
@@ -92,8 +92,13 @@ func (v *Vaultik) CreateSnapshot(opts *SnapshotCreateOptions) error {
|
||||
}
|
||||
}
|
||||
|
||||
// Terminus must obey the --cron invariant: silent on total
|
||||
// success only. UI.Complete is dropped in cron/quiet mode (that's
|
||||
// the success path), but if any warnings fired during the run we
|
||||
// emit the summary via UI.Warning so cron actually delivers
|
||||
// something for the user to look at.
|
||||
if v.UI.WarningCount() > 0 {
|
||||
v.UI.Complete("Finished (with %d warnings).", v.UI.WarningCount())
|
||||
v.UI.Warning("Finished with %d warning(s) — review the output above.", v.UI.WarningCount())
|
||||
} else {
|
||||
v.UI.Complete("Finished successfully.")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user