From c4c4bc095706c36a7d63c4fcd5ba6e715818a2dc Mon Sep 17 00:00:00 2001 From: Tom Morelly Date: Fri, 20 Sep 2024 09:02:22 +1000 Subject: [PATCH] feat(monitor): introduce MonitorWithStatus --- README.md | 1 + executor.go | 10 ++++++++++ monitor.go | 8 ++++++++ scheduler.go | 11 +++++++++++ 4 files changed, 30 insertions(+) diff --git a/README.md b/README.md index 4a1de758..504f8314 100644 --- a/README.md +++ b/README.md @@ -151,6 +151,7 @@ The provided NewLogger uses the standard library's log package. ### Metrics Metrics may be collected from the execution of each job. - [**Monitor**](https://pkg.go.dev/github.com/go-co-op/gocron/v2#Monitor): +- [**MonitorStatus**](https://pkg.go.dev/github.com/go-co-op/gocron/v2#MonitorStatus) (includes status and error (if any) of the Job) A monitor can be used to collect metrics for each job from a scheduler. - Implementations: [go-co-op monitors](https://github.com/go-co-op?q=-monitor&type=all&language=&sort=) (don't see what you need? request on slack to get a repo created to contribute it!) diff --git a/executor.go b/executor.go index ae346b1e..ab1b3314 100644 --- a/executor.go +++ b/executor.go @@ -49,6 +49,8 @@ type executor struct { locker Locker // monitor for reporting metrics monitor Monitor + // monitorStatus for reporting metrics + monitorStatus MonitorStatus } type jobIn struct { @@ -401,9 +403,11 @@ func (e *executor) runJob(j internalJob, jIn jobIn) { if err != nil { _ = callJobFuncWithParams(j.afterJobRunsWithError, j.id, j.name, err) e.incrementJobCounter(j, Fail) + e.recordJobTimingWithStatus(startTime, time.Now(), j, Fail, err) } else { _ = callJobFuncWithParams(j.afterJobRuns, j.id, j.name) e.incrementJobCounter(j, Success) + e.recordJobTimingWithStatus(startTime, time.Now(), j, Success, nil) } } @@ -426,6 +430,12 @@ func (e *executor) recordJobTiming(start time.Time, end time.Time, j internalJob } } +func (e *executor) recordJobTimingWithStatus(start time.Time, end time.Time, j internalJob, status JobStatus, err error) { + if e.monitorStatus != nil { + e.monitorStatus.RecordJobTimingWithStatus(start, end, j.id, j.name, j.tags, status, err) + } +} + func (e *executor) incrementJobCounter(j internalJob, status JobStatus) { if e.monitor != nil { e.monitor.IncrementJob(j.id, j.name, j.tags, status) diff --git a/monitor.go b/monitor.go index d3c5bbd9..4f25fd86 100644 --- a/monitor.go +++ b/monitor.go @@ -26,3 +26,11 @@ type Monitor interface { // to handle instantiating and recording the value RecordJobTiming(startTime, endTime time.Time, id uuid.UUID, name string, tags []string) } + +// MonitorStatus extends RecordJobTiming with the job status. +type MonitorStatus interface { + Monitor + // RecordJobTimingWithStatus will provide details about the job, its status, error and the timing and expects the underlying implementation + // to handle instantiating and recording the value + RecordJobTimingWithStatus(startTime, endTime time.Time, id uuid.UUID, name string, tags []string, status JobStatus, err error) +} diff --git a/scheduler.go b/scheduler.go index 90ff5212..8173f424 100644 --- a/scheduler.go +++ b/scheduler.go @@ -945,3 +945,14 @@ func WithMonitor(monitor Monitor) SchedulerOption { return nil } } + +// WithMonitorStatus sets the metrics provider to be used by the Scheduler. +func WithMonitorStatus(monitor MonitorStatus) SchedulerOption { + return func(s *scheduler) error { + if monitor == nil { + return ErrWithMonitorNil + } + s.exec.monitorStatus = monitor + return nil + } +}