Skip to content

Commit 797999c

Browse files
committedApr 21, 2023
Add task run next/prev time metrics
1 parent 868c01d commit 797999c

File tree

3 files changed

+71
-11
lines changed

3 files changed

+71
-11
lines changed
 

‎metrics.go

+22
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ var (
77
prometheusMetricTaskRunCount *prometheus.CounterVec
88
prometheusMetricTaskRunResult *prometheus.GaugeVec
99
prometheusMetricTaskRunTime *prometheus.GaugeVec
10+
prometheusMetricTaskRunPrevTs *prometheus.GaugeVec
11+
prometheusMetricTaskRunNextTs *prometheus.GaugeVec
1012
prometheusMetricTaskRunDuration *prometheus.GaugeVec
1113
)
1214

@@ -55,6 +57,24 @@ func initMetrics() {
5557
[]string{"cronSpec", "cronUser", "cronCommand"},
5658
)
5759
prometheus.MustRegister(prometheusMetricTaskRunDuration)
60+
61+
prometheusMetricTaskRunNextTs = prometheus.NewGaugeVec(
62+
prometheus.GaugeOpts{
63+
Name: "gocrond_task_run_next_time",
64+
Help: "gocrond task next run ts",
65+
},
66+
[]string{"cronSpec", "cronUser", "cronCommand"},
67+
)
68+
prometheus.MustRegister(prometheusMetricTaskRunNextTs)
69+
70+
prometheusMetricTaskRunPrevTs = prometheus.NewGaugeVec(
71+
prometheus.GaugeOpts{
72+
Name: "gocrond_task_run_prev_time",
73+
Help: "gocrond task prev run ts",
74+
},
75+
[]string{"cronSpec", "cronUser", "cronCommand"},
76+
)
77+
prometheus.MustRegister(prometheusMetricTaskRunPrevTs)
5878
}
5979

6080
func resetMetrics() {
@@ -63,4 +83,6 @@ func resetMetrics() {
6383
prometheusMetricTaskRunResult.Reset()
6484
prometheusMetricTaskRunTime.Reset()
6585
prometheusMetricTaskRunDuration.Reset()
86+
prometheusMetricTaskRunNextTs.Reset()
87+
prometheusMetricTaskRunPrevTs.Reset()
6688
}

‎parser.go

+6
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"regexp"
88
"strings"
99

10+
"github.com/robfig/cron/v3"
1011
log "github.com/sirupsen/logrus"
1112
)
1213

@@ -35,6 +36,7 @@ type CrontabEntry struct {
3536
Env []string
3637
Shell string
3738
CrontabPath string
39+
EntryId cron.EntryID
3840
}
3941

4042
type Parser struct {
@@ -65,6 +67,10 @@ func NewCronjobSystemParser(path string) (*Parser, error) {
6567
return p, nil
6668
}
6769

70+
func (e *CrontabEntry) SetEntryId(eid cron.EntryID) {
71+
(*e).EntryId = eid
72+
}
73+
6874
// Parse crontab
6975
func (p *Parser) Parse() []CrontabEntry {
7076
entries := p.parseLines()

‎runner.go

+43-11
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ import (
1414
)
1515

1616
type Runner struct {
17-
cron *cron.Cron
17+
cron *cron.Cron
18+
cronjobs map[cron.EntryID]*CrontabEntry
1819
}
1920

2021
func NewRunner() *Runner {
@@ -26,13 +27,14 @@ func NewRunner() *Runner {
2627
),
2728
),
2829
),
30+
cronjobs: map[cron.EntryID]*CrontabEntry{},
2931
}
3032
return r
3133
}
3234

3335
// Add crontab entry
3436
func (r *Runner) Add(cronjob CrontabEntry) error {
35-
_, err := r.cron.AddFunc(cronjob.Spec, r.cmdFunc(cronjob, func(execCmd *exec.Cmd) bool {
37+
eid, err := r.cron.AddFunc(cronjob.Spec, r.cmdFunc(&cronjob, func(execCmd *exec.Cmd) bool {
3638
// before exec callback
3739
log.WithFields(LogCronjobToFields(cronjob)).Infof("executing")
3840
return true
@@ -42,6 +44,8 @@ func (r *Runner) Add(cronjob CrontabEntry) error {
4244
prometheusMetricTask.With(r.cronjobToPrometheusLabels(cronjob)).Set(0)
4345
log.WithFields(LogCronjobToFields(cronjob)).Errorf("cronjob failed adding:%v", err)
4446
} else {
47+
cronjob.SetEntryId(eid)
48+
r.cronjobs[eid] = &cronjob
4549
prometheusMetricTask.With(r.cronjobToPrometheusLabels(cronjob)).Set(1)
4650
log.WithFields(LogCronjobToFields(cronjob)).Infof("cronjob added")
4751
}
@@ -51,7 +55,7 @@ func (r *Runner) Add(cronjob CrontabEntry) error {
5155

5256
// Add crontab entry with user
5357
func (r *Runner) AddWithUser(cronjob CrontabEntry) error {
54-
_, err := r.cron.AddFunc(cronjob.Spec, r.cmdFunc(cronjob, func(execCmd *exec.Cmd) bool {
58+
eid, err := r.cron.AddFunc(cronjob.Spec, r.cmdFunc(&cronjob, func(execCmd *exec.Cmd) bool {
5559
// before exec callback
5660
log.WithFields(LogCronjobToFields(cronjob)).Debugf("executing")
5761

@@ -86,6 +90,8 @@ func (r *Runner) AddWithUser(cronjob CrontabEntry) error {
8690
prometheusMetricTask.With(r.cronjobToPrometheusLabels(cronjob)).Set(0)
8791
log.WithFields(LogCronjobToFields(cronjob)).Errorf("cronjob failed adding: %v", err)
8892
} else {
93+
cronjob.SetEntryId(eid)
94+
r.cronjobs[eid] = &cronjob
8995
prometheusMetricTask.With(r.cronjobToPrometheusLabels(cronjob)).Set(1)
9096
log.WithFields(LogCronjobToFields(cronjob)).Infof("cronjob added")
9197
}
@@ -102,6 +108,7 @@ func (r *Runner) Len() int {
102108
func (r *Runner) Start() {
103109
log.Infof("start runner with %d jobs\n", r.Len())
104110
r.cron.Start()
111+
r.initAllCronEntryMetrics()
105112
}
106113

107114
// Stop runner
@@ -111,7 +118,7 @@ func (r *Runner) Stop() {
111118
}
112119

113120
// Execute crontab command
114-
func (r *Runner) cmdFunc(cronjob CrontabEntry, cmdCallback func(*exec.Cmd) bool) func() {
121+
func (r *Runner) cmdFunc(cronjob *CrontabEntry, cmdCallback func(*exec.Cmd) bool) func() {
115122
cmdFunc := func() {
116123
// fall back to normal shell if not specified
117124
taskShell := cronjob.Shell
@@ -137,25 +144,27 @@ func (r *Runner) cmdFunc(cronjob CrontabEntry, cmdCallback func(*exec.Cmd) bool)
137144

138145
elapsed := time.Since(start)
139146

140-
prometheusMetricTaskRunDuration.With(r.cronjobToPrometheusLabels(cronjob)).Set(elapsed.Seconds())
141-
prometheusMetricTaskRunTime.With(r.cronjobToPrometheusLabels(cronjob)).SetToCurrentTime()
147+
cronjobMetricCommonLables := r.cronjobToPrometheusLabels(*cronjob)
148+
prometheusMetricTaskRunDuration.With(cronjobMetricCommonLables).Set(elapsed.Seconds())
149+
prometheusMetricTaskRunTime.With(cronjobMetricCommonLables).SetToCurrentTime()
142150

143-
logFields := LogCronjobToFields(cronjob)
151+
logFields := LogCronjobToFields(*cronjob)
144152
logFields["elapsed_s"] = elapsed.Seconds()
145153
if execCmd.ProcessState != nil {
146154
logFields["exitCode"] = execCmd.ProcessState.ExitCode()
147155
}
148156

149157
if err != nil {
150-
prometheusMetricTaskRunCount.With(r.cronjobToPrometheusLabels(cronjob, prometheus.Labels{"result": "error"})).Inc()
151-
prometheusMetricTaskRunResult.With(r.cronjobToPrometheusLabels(cronjob)).Set(0)
158+
prometheusMetricTaskRunCount.With(r.cronjobToPrometheusLabels(*cronjob, prometheus.Labels{"result": "error"})).Inc()
159+
prometheusMetricTaskRunResult.With(cronjobMetricCommonLables).Set(0)
152160
logFields["result"] = "error"
153161
} else {
154-
prometheusMetricTaskRunCount.With(r.cronjobToPrometheusLabels(cronjob, prometheus.Labels{"result": "success"})).Inc()
155-
prometheusMetricTaskRunResult.With(r.cronjobToPrometheusLabels(cronjob)).Set(1)
162+
prometheusMetricTaskRunCount.With(r.cronjobToPrometheusLabels(*cronjob, prometheus.Labels{"result": "success"})).Inc()
163+
prometheusMetricTaskRunResult.With(cronjobMetricCommonLables).Set(1)
156164
logFields["result"] = "success"
157165
}
158166

167+
r.updateCronEntryMetrics(cronjob)
159168
log.WithFields(logFields).Info("finished")
160169
if len(cmdStdout) > 0 {
161170
log.Debugln(string(cmdStdout))
@@ -178,3 +187,26 @@ func (r *Runner) cronjobToPrometheusLabels(cronjob CrontabEntry, additionalLabel
178187
}
179188
return
180189
}
190+
191+
func (r *Runner) updateCronEntryMetrics(cronjob *CrontabEntry) {
192+
cronjobMetricCommonLables := r.cronjobToPrometheusLabels(*cronjob)
193+
entry := r.cron.Entry(cronjob.EntryId)
194+
195+
if entry.Next.IsZero() {
196+
prometheusMetricTaskRunNextTs.With(cronjobMetricCommonLables).Set(0)
197+
} else {
198+
prometheusMetricTaskRunNextTs.With(cronjobMetricCommonLables).Set(float64(entry.Next.Unix()))
199+
}
200+
201+
if entry.Prev.IsZero() {
202+
prometheusMetricTaskRunPrevTs.With(cronjobMetricCommonLables).Set(0)
203+
} else {
204+
prometheusMetricTaskRunPrevTs.With(cronjobMetricCommonLables).Set(float64(entry.Prev.Unix()))
205+
}
206+
}
207+
208+
func (r *Runner) initAllCronEntryMetrics() {
209+
for _, cronjob := range r.cronjobs {
210+
r.updateCronEntryMetrics(cronjob)
211+
}
212+
}

0 commit comments

Comments
 (0)