Add reliability improvements and config persistence feature

- Implement context cleanup with sync.Once and io.Closer interface
- Add regex-based error classification for robust error handling
- Create ProcessManager with thread-safe process tracking
- Add disk space caching with 30s TTL for performance
- Implement metrics collection with structured logging
- Add config persistence (.dbbackup.conf) for directory-local settings
- Auto-save/auto-load configuration with --no-config and --no-save-config flags
- Successfully tested with 42GB d7030 database (35K large objects, 36min backup)
- All cross-platform builds working (9/10 platforms)
This commit is contained in:
2025-11-19 04:43:22 +00:00
parent ccf70db840
commit e80c16bf0e
14 changed files with 787 additions and 13 deletions

View File

@@ -13,9 +13,13 @@ import (
// Logger defines the interface for logging
type Logger interface {
Debug(msg string, args ...any)
Info(msg string, args ...any)
Warn(msg string, args ...any)
Error(msg string, args ...any)
Info(msg string, keysAndValues ...interface{})
Warn(msg string, keysAndValues ...interface{})
Error(msg string, keysAndValues ...interface{})
// Structured logging methods
WithFields(fields map[string]interface{}) Logger
WithField(key string, value interface{}) Logger
Time(msg string, args ...any)
// Progress logging for operations
@@ -109,10 +113,11 @@ func (l *logger) Error(msg string, args ...any) {
}
func (l *logger) Time(msg string, args ...any) {
// Time logs are always at info level with special formatting
// Time logs are always at info level with special formatting
l.logWithFields(logrus.InfoLevel, "[TIME] "+msg, args...)
}
// StartOperation creates a new operation logger
func (l *logger) StartOperation(name string) OperationLogger {
return &operationLogger{
name: name,
@@ -121,6 +126,24 @@ func (l *logger) StartOperation(name string) OperationLogger {
}
}
// WithFields creates a logger with structured fields
func (l *logger) WithFields(fields map[string]interface{}) Logger {
return &logger{
logrus: l.logrus.WithFields(logrus.Fields(fields)).Logger,
level: l.level,
format: l.format,
}
}
// WithField creates a logger with a single structured field
func (l *logger) WithField(key string, value interface{}) Logger {
return &logger{
logrus: l.logrus.WithField(key, value).Logger,
level: l.level,
format: l.format,
}
}
func (ol *operationLogger) Update(msg string, args ...any) {
elapsed := time.Since(ol.startTime)
ol.parent.Info(fmt.Sprintf("[%s] %s", ol.name, msg),