diff --git a/config/profile.go b/config/profile.go index c45f37a5..76c1bcd6 100644 --- a/config/profile.go +++ b/config/profile.go @@ -44,6 +44,7 @@ type BackupSection struct { FilesFrom []string `mapstructure:"files-from" argument:"files-from"` Schedule []string `mapstructure:"schedule"` SchedulePermission string `mapstructure:"schedule-permission"` + ScheduleLog string `mapstructure:"schedule-log"` OtherFlags map[string]interface{} `mapstructure:",remain"` } @@ -54,6 +55,7 @@ type RetentionSection struct { AfterBackup bool `mapstructure:"after-backup"` Schedule []string `mapstructure:"schedule"` SchedulePermission string `mapstructure:"schedule-permission"` + ScheduleLog string `mapstructure:"schedule-log"` OtherFlags map[string]interface{} `mapstructure:",remain"` } @@ -62,6 +64,7 @@ type RetentionSection struct { type OtherSectionWithSchedule struct { Schedule []string `mapstructure:"schedule"` SchedulePermission string `mapstructure:"schedule-permission"` + ScheduleLog string `mapstructure:"schedule-log"` OtherFlags map[string]interface{} `mapstructure:",remain"` } @@ -199,6 +202,7 @@ func (p *Profile) Schedules() []*ScheduleConfig { permission: p.Backup.SchedulePermission, environment: p.Environment, nice: 10, // hard-coded for now + logfile: p.Backup.ScheduleLog, } configs = append(configs, config) } @@ -211,6 +215,7 @@ func (p *Profile) Schedules() []*ScheduleConfig { permission: p.Retention.SchedulePermission, environment: p.Environment, nice: 10, // hard-coded for now + logfile: p.Retention.ScheduleLog, } configs = append(configs, config) } @@ -223,6 +228,7 @@ func (p *Profile) Schedules() []*ScheduleConfig { permission: p.Check.SchedulePermission, environment: p.Environment, nice: 10, // hard-coded for now + logfile: p.Check.ScheduleLog, } configs = append(configs, config) } diff --git a/config/schedule.go b/config/schedule.go index 39cc33f5..d7b2c4ac 100644 --- a/config/schedule.go +++ b/config/schedule.go @@ -12,6 +12,7 @@ type ScheduleConfig struct { jobDescription string timerDescription string nice int + logfile string } func (s *ScheduleConfig) Title() string { @@ -71,3 +72,7 @@ func (s *ScheduleConfig) SetTimerDescription(description string) { func (s *ScheduleConfig) Nice() int { return s.nice } + +func (s *ScheduleConfig) Logfile() string { + return s.logfile +} diff --git a/examples/windows.yaml b/examples/windows.yaml index 5fcfa95a..511cddd3 100644 --- a/examples/windows.yaml +++ b/examples/windows.yaml @@ -40,14 +40,17 @@ test: - "2020-07-31" - "mon..fri *:0,15,30,45" schedule-permission: system + schedule-log: "test-backup.log" check: schedule: - "*-*-1" - "sun *-*-1" - "mon *-11..12-*" schedule-permission: system + schedule-log: "test-check.log" retention: schedule: - "sun 3:30" - "*-7,8-* 12:00" schedule-permission: system + schedule-log: "test-retention.log" diff --git a/logger.go b/logger.go index 98caa5ad..0074993e 100644 --- a/logger.go +++ b/logger.go @@ -2,6 +2,7 @@ package main import ( "log" + "os" "github.com/creativeprojects/clog" "github.com/creativeprojects/resticprofile/remote" @@ -13,16 +14,16 @@ func setupRemoteLogger(client *remote.Client) { clog.SetDefaultLogger(logger) } -func setupFileLogger(flags commandLineFlags) (*clog.FileHandler, error) { - fileHandler, err := clog.NewFileHandler(flags.logFile, "", log.LstdFlags) +func setupFileLogger(flags commandLineFlags) (*os.File, error) { + file, err := os.OpenFile(flags.logFile, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644) if err != nil { return nil, err } - logger := newFilteredLogger(flags, fileHandler) + logger := newFilteredLogger(flags, clog.NewStandardLogHandler(file, "", log.LstdFlags)) // default logger added with level filtering clog.SetDefaultLogger(logger) - // but return fileHandler (so we can close it at the end) - return fileHandler, nil + // and return the file handle (so we can close it at the end) + return file, nil } func setupConsoleLogger(flags commandLineFlags) { diff --git a/main.go b/main.go index 77b85bca..a6a99215 100644 --- a/main.go +++ b/main.go @@ -91,14 +91,16 @@ func main() { } } else if flags.logFile != "" { - fileHandler, err := setupFileLogger(flags) + file, err := setupFileLogger(flags) if err != nil { // back to a console logger setupConsoleLogger(flags) clog.Errorf("cannot open logfile: %s", err) } else { + // also redirect all terminal output + term.SetOutput(file) // only close the file at the end if the logger opened it properly - defer fileHandler.Close() + defer file.Close() } } else { diff --git a/schedule_jobs.go b/schedule_jobs.go index 69f0b141..791f7b3f 100644 --- a/schedule_jobs.go +++ b/schedule_jobs.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "os" + "runtime" "github.com/creativeprojects/clog" "github.com/creativeprojects/resticprofile/config" @@ -28,14 +29,19 @@ func scheduleJobs(configFile string, configs []*config.ScheduleConfig) error { defer schedule.Close() for _, scheduleConfig := range configs { - scheduleConfig.SetCommand(wd, binary, []string{ + args := []string{ "--no-ansi", "--config", configFile, "--name", scheduleConfig.Title(), - getResticCommand(scheduleConfig.SubTitle()), - }) + } + if runtime.GOOS != "darwin" && scheduleConfig.Logfile() != "" { + args = append(args, "--log", scheduleConfig.Logfile()) + } + args = append(args, getResticCommand(scheduleConfig.SubTitle())) + + scheduleConfig.SetCommand(wd, binary, args) scheduleConfig.SetJobDescription( fmt.Sprintf("resticprofile %s for profile %s in %s", scheduleConfig.SubTitle(), scheduleConfig.Title(), configFile)) scheduleConfig.SetTimerDescription(