2022-03-26 13:23:39 +05:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"io/ioutil"
|
|
|
|
"os"
|
|
|
|
"os/exec"
|
|
|
|
"path/filepath"
|
|
|
|
"strings"
|
|
|
|
"sync"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/BurntSushi/toml"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
|
|
)
|
|
|
|
|
|
|
|
type JobConfig struct {
|
|
|
|
Cron string
|
|
|
|
Command string
|
|
|
|
Description string
|
|
|
|
}
|
|
|
|
|
2022-03-26 20:38:39 +05:00
|
|
|
var globalMutex sync.RWMutex
|
2022-03-26 13:23:39 +05:00
|
|
|
|
|
|
|
func readJob(filePath string) (*Job, error) {
|
|
|
|
var jobConfig JobConfig
|
|
|
|
|
|
|
|
_, err := toml.DecodeFile(filePath, &jobConfig)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
command, params := parseCommand(jobConfig.Command)
|
|
|
|
|
|
|
|
job := &Job{
|
|
|
|
Name: strings.TrimSuffix(filepath.Base(filePath), filepath.Ext(filePath)),
|
|
|
|
Cron: jobConfig.Cron,
|
|
|
|
Command: command,
|
|
|
|
Params: params,
|
|
|
|
FileName: strings.TrimSuffix(filepath.Base(filePath), filepath.Ext(filepath.Base(filePath))),
|
|
|
|
Description: jobConfig.Description}
|
|
|
|
|
|
|
|
return job, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (js *JobConfig) Write() {
|
|
|
|
buf := new(bytes.Buffer)
|
|
|
|
toml.NewEncoder(buf).Encode(*js)
|
|
|
|
ioutil.WriteFile("job.conf", buf.Bytes(), 0644)
|
|
|
|
}
|
|
|
|
|
|
|
|
type Job struct {
|
|
|
|
Name string // from filename
|
|
|
|
|
|
|
|
Cron string // cron decription
|
|
|
|
Command string // command for execution
|
|
|
|
Params []string // command params
|
|
|
|
FileName string // short job name
|
|
|
|
Description string // job description
|
|
|
|
|
|
|
|
// Fields for stats
|
|
|
|
CurrentRunningCount int
|
|
|
|
LastStartTime string
|
|
|
|
LastEndTime string
|
|
|
|
LastExecutionDuration string
|
|
|
|
LastError string
|
|
|
|
}
|
|
|
|
|
|
|
|
func (j *Job) Run() {
|
|
|
|
startTime := time.Now()
|
|
|
|
|
2022-03-26 20:38:39 +05:00
|
|
|
globalMutex.Lock()
|
2022-03-26 13:23:39 +05:00
|
|
|
j.CurrentRunningCount++
|
|
|
|
j.LastStartTime = startTime.Format(timeFormat)
|
2022-03-26 20:38:39 +05:00
|
|
|
globalMutex.Unlock()
|
2022-03-26 13:23:39 +05:00
|
|
|
|
|
|
|
jobLogFile, _ := os.OpenFile(filepath.Join(logFilesPath, j.FileName+".txt"), os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
|
|
|
|
defer jobLogFile.Close()
|
|
|
|
defer jobLogFile.WriteString("\n")
|
|
|
|
|
|
|
|
l := log.New()
|
|
|
|
l.SetOutput(jobLogFile)
|
|
|
|
l.SetFormatter(logFormat)
|
|
|
|
|
|
|
|
log.WithField("job", j.FileName).Info("started")
|
|
|
|
l.Info("started")
|
|
|
|
|
|
|
|
cmd := exec.Command(j.Command, j.Params...)
|
|
|
|
cmd.Stdout = jobLogFile
|
|
|
|
cmd.Stderr = jobLogFile
|
|
|
|
|
|
|
|
err := cmd.Run()
|
|
|
|
if err != nil {
|
|
|
|
log.WithField("job", j.FileName).Error(err.Error())
|
|
|
|
l.WithField("job", j.FileName).Error(err.Error())
|
|
|
|
|
2022-03-26 20:38:39 +05:00
|
|
|
globalMutex.Lock()
|
2022-03-26 13:23:39 +05:00
|
|
|
j.LastError = err.Error()
|
2022-03-26 20:38:39 +05:00
|
|
|
globalMutex.Unlock()
|
2022-03-26 13:23:39 +05:00
|
|
|
} else {
|
2022-03-26 20:38:39 +05:00
|
|
|
globalMutex.Lock()
|
2022-03-26 13:23:39 +05:00
|
|
|
j.LastError = ""
|
2022-03-26 20:38:39 +05:00
|
|
|
globalMutex.Unlock()
|
2022-03-26 13:23:39 +05:00
|
|
|
}
|
|
|
|
|
|
|
|
endTime := time.Now()
|
|
|
|
log.WithField("job", j.FileName).Infof("finished (%s)", endTime.Sub(startTime).Truncate(time.Second).String())
|
|
|
|
l.Infof("finished (%s)", endTime.Sub(startTime).Truncate(time.Second).String())
|
|
|
|
|
2022-03-26 20:38:39 +05:00
|
|
|
globalMutex.Lock()
|
2022-03-26 13:23:39 +05:00
|
|
|
j.CurrentRunningCount--
|
|
|
|
j.LastEndTime = endTime.Format(timeFormat)
|
|
|
|
j.LastExecutionDuration = endTime.Sub(startTime).Truncate(time.Second).String()
|
2022-03-26 20:38:39 +05:00
|
|
|
globalMutex.Unlock()
|
2022-03-26 13:23:39 +05:00
|
|
|
}
|