From 3bdc2adc710cb6b4ae3863f10030e41449ca9bee Mon Sep 17 00:00:00 2001 From: Sherif Abdel-Naby Date: Sat, 10 Apr 2021 15:07:11 +0200 Subject: [PATCH] Add README.md :rocket: + Small Tweaks Signed-off-by: Sherif Abdel-Naby --- README.md | 284 ++++++++++++++++++++++- examples/schedule-cron/README.md | 29 +-- examples/schedule-fixed/README.md | 27 +-- examples/schedule-prom-metrics/README.md | 65 ++---- job/job.go | 2 +- metric.go | 14 +- schedule.go | 4 +- scheduler.go | 6 +- 8 files changed, 337 insertions(+), 94 deletions(-) diff --git a/README.md b/README.md index 4d79676..725549d 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@

🕰 Sched

Go In-Process Scheduler with Cron Expression Support

-
Run Jobs on a schedule supporting fixed interval, and cron-expression, instrument your processes and expose metrics for each job.
+
Run Jobs on a schedule, supports fixed interval, timely, and cron-expression timers; Instrument your processes and expose metrics for each job.

Go Doc @@ -25,3 +25,285 @@ GitHub license

+ +# Introduction + +A simple process manager that allows you to specify a Schedule that execute a Job based on a Timer. Schedule manage the +state of this job allowing you to start/stop/restart in concurrent safe way. Schedule also instrument this Job and +gather metrics and optionally expose them via [uber-go/tally](https://github.com/uber-go/tally#report-your-metrics) +scope. + +# Install + +``` bash +go get github.com/sherifabdlnaby/sched +``` + +``` go +import "github.com/sherifabdlnaby/sched" +``` + +# Requirements + +Go 1.13 >= + +----- + +# Concepts + +## Job + +Simply a `func(){}` implementation that is the schedule goal to run, and instrument. + +## Timer + +An Object that Implements +the [type Timer interface{}](https://pkg.go.dev/github.com/sherifabdlnaby/sched?utm_source=godoc#Timer). A Timer is +responsible for providing a schedule with the **next time the job should run** and if there will be subsequent runs. + +Packaged Implementations: + +1. [Fixed](https://pkg.go.dev/github.com/sherifabdlnaby/sched?utm_source=godoc#Fixed) :- Infinitely Fires a job at a + Fixed Interval (`time.Duration`) +2. [Cron](https://pkg.go.dev/github.com/sherifabdlnaby/sched?utm_source=godoc#Cron) :- Infinitely Fires a job based on + a [Cron Expression](https://en.wikipedia.org/wiki/Cron#CRON_expression), all Expressions supported + by [gorhill/cronexpr](https://github.com/gorhill/cronexpr) are supported. +2. [Once](https://pkg.go.dev/github.com/sherifabdlnaby/sched?utm_source=godoc#Once) :- A Timer that run **ONCE** after + an optional specific delay or at a specified time, schedule will stop after it fires. + +You can Implement your own Timer for your specific scheduling needs by implementing + +```go +type Timer interface { + // done indicated that there will be no more runs. + Next() (next time.Time, done bool) +} +``` + +## Schedule + +A Schedule wraps a Job and fires it according to Timer. + +```go + fixedTimer30second, _ := sched.NewFixed(30 * time.Second) + + job := func() { + log.Println("Doing some work...") + time.Sleep(1 * time.Second) + log.Println("Finished Work.") + } + + // Create Schedule + schedule := sched.NewSchedule("every30s", fixedTimer30second, job) + + // Start + schedule.Start() +``` + +### Options + +Additional Options can be passed to Schedule to change its behavior. + +```go +// Create Schedule +schedule := sched.NewSchedule("every30s", fixedTimer30second, job, + sched.WithLogger(sched.DefaultLogger()), + opt2, + opt3, + ...., +) +``` + +#### Logger Option + +`WithLogger( logger Logger)` -> Supply the Schedule the Logger it is going to use for logging. +1. [func DefaultLogger() Logger](https://pkg.go.dev/github.com/sherifabdlnaby/sched?utm_source=godoc#DefaultLogger) : +Provide a Default Logging Interface to be used Instead of Implementing your own. +1. [func NopLogger() Logger](https://pkg.go.dev/github.com/sherifabdlnaby/sched?utm_source=godoc#NopLogger) : A nop +Logger that will not output anything to stdout. + +#### Metrics Option + +`WithMetrics( scope tally.Scope)` -> Supply the Schedule with a metrics scope it can use to export metrics. + +1. Use any of `uber-go/tally` implementations (Prometheus, statsd, etc) +1. +Use [`func WithConsoleMetrics(printEvery time.Duration) Option`](https://pkg.go.dev/github.com/sherifabdlnaby/sched?utm_source=godoc#WithConsoleMetrics) +Implementation to Output Metrics to stdout (good for debugging) + +#### Expected Runtime + +`WithExpectedRunTime(d time.Duration)` -> Supply the Schedule with the expected duration for the job to run, schedule +will output corresponding logs and metrics if job run exceeded expected. + +## Schedule(r) + +Scheduler manage one or more Schedule creating them using common options, enforcing unique IDs, and supply methods to +Start / Stop all schedule(s). + + +---- + +# Exported Metrics + +| Metric | Type | Desc | +|--------------------------|----------|--------------------------------------------------------------------------------------------------------------------------------------------------------| +| up | Gauge | If the schedule is Running / Stopped | +| runs | Counter | Number of Runs Since Starting | +| runs_overlapping | Counter | Number of times more than one job was running together. (Overlapped) | +| run_actual_elapsed_time | Time | Elapsed Time between Starting and Ending of Job Execution | +| run_total_elapsed_time | Time | Total Elapsed Time between Creating the Job and Ending of Job Execution, This differ from Actual Elapsed time when Overlapping blocking is Implemented | +| run_errors | Counter | Count Number of Times a Job error'd(Panicked) during execution. | +| run_exceed_expected_time | Counter | Count Number of Times a Job Execution Time exceeded the Expected Time | + +### In Prometheus Format + +``` +# HELP sched_run_actual_elapsed_time sched_run_actual_elapsed_time summary +# TYPE sched_run_actual_elapsed_time summary +sched_run_actual_elapsed_time{id="every5s",quantile="0.5"} 0.203843151 +sched_run_actual_elapsed_time{id="every5s",quantile="0.75"} 1.104031623 +sched_run_actual_elapsed_time{id="every5s",quantile="0.95"} 1.104031623 +sched_run_actual_elapsed_time{id="every5s",quantile="0.99"} 1.104031623 +sched_run_actual_elapsed_time{id="every5s",quantile="0.999"} 1.104031623 +sched_run_actual_elapsed_time_sum{id="every5s"} 1.307874774 +sched_run_actual_elapsed_time_count{id="every5s"} 2 +# HELP sched_run_errors sched_run_errors counter +# TYPE sched_run_errors counter +sched_run_errors{id="every5s"} 0 +# HELP sched_run_exceed_expected_time sched_run_exceed_expected_time counter +# TYPE sched_run_exceed_expected_time counter +sched_run_exceed_expected_time{id="every5s"} 0 +# HELP sched_run_total_elapsed_time sched_run_total_elapsed_time summary +# TYPE sched_run_total_elapsed_time summary +sched_run_total_elapsed_time{id="every5s",quantile="0.5"} 0.203880714 +sched_run_total_elapsed_time{id="every5s",quantile="0.75"} 1.104065614 +sched_run_total_elapsed_time{id="every5s",quantile="0.95"} 1.104065614 +sched_run_total_elapsed_time{id="every5s",quantile="0.99"} 1.104065614 +sched_run_total_elapsed_time{id="every5s",quantile="0.999"} 1.104065614 +sched_run_total_elapsed_time_sum{id="every5s"} 1.307946328 +sched_run_total_elapsed_time_count{id="every5s"} 2 +# HELP sched_runs sched_runs counter +# TYPE sched_runs counter +sched_runs{id="every5s"} 2 +# HELP sched_runs_overlapping sched_runs_overlapping counter +# TYPE sched_runs_overlapping counter +sched_runs_overlapping{id="every5s"} 0 +# HELP sched_up sched_up gauge +# TYPE sched_up gauge +sched_up{id="every5s"} 1 +``` + +# Examples + +## Inline Example + +```go +package main + +import ( + "fmt" + "github.com/sherifabdlnaby/sched" + "log" + "os" + "os/signal" + "syscall" + "time" +) + +func main() { + + cronTimer, err := sched.NewCron("* * * * *") + if err != nil { + panic(fmt.Sprintf("invalid cron expression: %s", err.Error())) + } + + job := func() { + log.Println("Doing some work...") + time.Sleep(1 * time.Second) + log.Println("Finished Work.") + } + + // Create Schedule + schedule := sched.NewSchedule("cron", cronTimer, job, sched.WithLogger(sched.DefaultLogger())) + + // Start Schedule + schedule.Start() + + // Stop schedule after 5 Minutes + time.AfterFunc(5*time.Minute, func() { + schedule.Stop() + }) + + // Listen to CTRL + C + signalChan := make(chan os.Signal, 1) + signal.Notify(signalChan, syscall.SIGTERM, syscall.SIGINT, syscall.SIGQUIT) + _ = <-signalChan + + // Stop before shutting down. + schedule.Stop() + + return +} + +``` + +### Output for 3 minutes + +```bash +2021-04-10T12:30: 13.132+0200 INFO sched sched/schedule.go: 96 Job Schedule Started {"id": "cron"} +2021-04-10T12:30: 13.132+0200 INFO sched sched/schedule.go: 168 Job Next Run Scheduled {"id": "cron", "After": "47s", "At": "2021-04-10T12:31:00+02:00"} +2021-04-10T12: 31: 00.000+0200 INFO sched sched/schedule.go: 168 Job Next Run Scheduled {"id": "cron", "After": "1m0s", "At": "2021-04-10T12:32:00+02:00"} +2021-04-10T12: 31:00.000+0200 INFO sched sched/schedule.go: 193 Job Run Starting {"id": "cron", "Instance": "8e1044ab-20b6-4acf-8a15-e06c0418522c"} +2021/04/10 12: 31: 00 Doing some work... +2021/04/10 12: 31: 01 Finished Work. +2021-04-10T12: 31: 01.001+0200 INFO sched sched/schedule.go: 208 Job Finished {"id": "cron", "Instance": "8e1044ab-20b6-4acf-8a15-e06c0418522c", "Duration": "1.001s", "State": "FINISHED"} +2021-04-10T12:32: 00.002+0200 INFO sched sched/schedule.go: 168 Job Next Run Scheduled {"id": "cron", "After": "1m0s", "At": "2021-04-10T12:33:00+02:00"} +2021-04-10T12: 32: 00.002+0200 INFO sched sched/schedule.go: 193 Job Run Starting {"id": "cron", "Instance": "baae94eb-f818-4b34-a1f4-45b521a360a1"} +2021/04/10 12: 32: 00 Doing some work... +2021/04/10 12: 32: 01 Finished Work. +2021-04-10T12:32: 01.005+0200 INFO sched sched/schedule.go: 208 Job Finished {"id": "cron", "Instance": "baae94eb-f818-4b34-a1f4-45b521a360a1", "Duration": "1.003s", "State": "FINISHED"} +2021-04-10T12: 33: 00.001+0200 INFO sched sched/schedule.go:168 Job Next Run Scheduled {"id": "cron", "After": "1m0s", "At": "2021-04-10T12:34:00+02:00"} +2021-04-10T12:33: 00.001+0200 INFO sched sched/schedule.go: 193 Job Run Starting {"id": "cron", "Instance": "71c8f0bf-3624-4a92-909c-b4149f3c62a3"} +2021/04/10 12: 33: 00 Doing some work... +2021/04/10 12: 33: 01 Finished Work. +2021-04-10T12: 33: 01.004+0200 INFO sched sched/schedule.go:208 Job Finished {"id": "cron", "Instance": "71c8f0bf-3624-4a92-909c-b4149f3c62a3", "Duration": "1.003s", "State": "FINISHED"} + + +``` + +### Output With CTRL+C + +```bash +2021-04-10T12:28: 45.591+0200 INFO sched sched/schedule.go: 96 Job Schedule Started {"id": "cron"} +2021-04-10T12:28: 45.592+0200 INFO sched sched/schedule.go: 168 Job Next Run Scheduled {"id": "cron", "After": "14s", "At": "2021-04-10T12:29:00+02:00"} +2021-04-10T12: 29: 00.000+0200 INFO sched sched/schedule.go: 168 Job Next Run Scheduled {"id": "cron", "After": "1m0s", "At": "2021-04-10T12:30:00+02:00"} +2021-04-10T12: 29:00.000+0200 INFO sched sched/schedule.go: 193 Job Run Starting {"id": "cron", "Instance": "786540f1-594b-44a0-9a66-7181619e38a6"} +2021/04/10 12: 29: 00 Doing some work... +CTRL+C +2021-04-10T12: 29: 00.567+0200 INFO sched sched/schedule.go: 125 Stopping Schedule... {"id": "cron"} +2021-04-10T12: 29: 00.567+0200 INFO sched sched/schedule.go: 130 Waiting active jobs to finish... {"id": "cron"} +2021-04-10T12: 29: 00.567+0200 INFO sched sched/schedule.go: 171 Job Next Run Canceled {"id": "cron", "At": "2021-04-10T12:30:00+02:00"} +2021/04/10 12: 29: 01 Finished Work. +2021-04-10T12: 29:01.000+0200 INFO sched sched/schedule.go: 208 Job Finished {"id": "cron", "Instance": "786540f1-594b-44a0-9a66-7181619e38a6", "Duration": "1s", "State": "FINISHED"} +2021-04-10T12: 29: 01.000+0200 INFO sched sched/schedule.go: 133 Job Schedule Stopped {"id": "cron" } +``` + +# Todo(s) and Enhancements + +- [ ] Control Logging Verbosity +- [ ] Make Panic Recovery Optional +- [ ] Make Job a func() error and allow retry(s), backoff, and collect errors and their metrics +- [ ] Make Jobs context aware and support canceling Jobs Context. +- [ ] Make allow Overlapping Optional and Configure How Overlapping is handled/denied. +- [ ] Global Package-Level Metrics + +# License + +[MIT License](https://raw.githubusercontent.com/sherifabdlnaby/sched/master/LICENSE) +Copyright (c) 2021 Sherif Abdel-Naby + +# Contribution + +PR(s) are Open and Welcomed. ❤️ + diff --git a/examples/schedule-cron/README.md b/examples/schedule-cron/README.md index 91a4194..d2fce72 100644 --- a/examples/schedule-cron/README.md +++ b/examples/schedule-cron/README.md @@ -2,22 +2,19 @@ ## Output for 3 minutes -```json +```bash 2021-04-10T12:30: 13.132+0200 INFO sched sched/schedule.go: 96 Job Schedule Started {"id": "cron"} -2021-04-10T12:30: 13.132+0200 INFO sched sched/schedule.go: 168 Job Next Run Scheduled {"id": "cron", "After": "47s", "At": "2021-04-10T12:31:00+02:00" -} +2021-04-10T12:30: 13.132+0200 INFO sched sched/schedule.go: 168 Job Next Run Scheduled {"id": "cron", "After": "47s", "At": "2021-04-10T12:31:00+02:00"} 2021-04-10T12: 31: 00.000+0200 INFO sched sched/schedule.go: 168 Job Next Run Scheduled {"id": "cron", "After": "1m0s", "At": "2021-04-10T12:32:00+02:00"} 2021-04-10T12: 31:00.000+0200 INFO sched sched/schedule.go: 193 Job Run Starting {"id": "cron", "Instance": "8e1044ab-20b6-4acf-8a15-e06c0418522c"} 2021/04/10 12: 31: 00 Doing some work... 2021/04/10 12: 31: 01 Finished Work. 2021-04-10T12: 31: 01.001+0200 INFO sched sched/schedule.go: 208 Job Finished {"id": "cron", "Instance": "8e1044ab-20b6-4acf-8a15-e06c0418522c", "Duration": "1.001s", "State": "FINISHED"} -2021-04-10T12:32: 00.002+0200 INFO sched sched/schedule.go: 168 Job Next Run Scheduled {"id": "cron", "After": "1m0s", "At": "2021-04-10T12:33:00+02:00" -} +2021-04-10T12:32: 00.002+0200 INFO sched sched/schedule.go: 168 Job Next Run Scheduled {"id": "cron", "After": "1m0s", "At": "2021-04-10T12:33:00+02:00"} 2021-04-10T12: 32: 00.002+0200 INFO sched sched/schedule.go: 193 Job Run Starting {"id": "cron", "Instance": "baae94eb-f818-4b34-a1f4-45b521a360a1"} 2021/04/10 12: 32: 00 Doing some work... 2021/04/10 12: 32: 01 Finished Work. -2021-04-10T12:32: 01.005+0200 INFO sched sched/schedule.go: 208 Job Finished {"id": "cron", "Instance": "baae94eb-f818-4b34-a1f4-45b521a360a1", "Duration": "1.003s", "State": "FINISHED" -} +2021-04-10T12:32: 01.005+0200 INFO sched sched/schedule.go: 208 Job Finished {"id": "cron", "Instance": "baae94eb-f818-4b34-a1f4-45b521a360a1", "Duration": "1.003s", "State": "FINISHED"} 2021-04-10T12: 33: 00.001+0200 INFO sched sched/schedule.go:168 Job Next Run Scheduled {"id": "cron", "After": "1m0s", "At": "2021-04-10T12:34:00+02:00"} 2021-04-10T12:33: 00.001+0200 INFO sched sched/schedule.go: 193 Job Run Starting {"id": "cron", "Instance": "71c8f0bf-3624-4a92-909c-b4149f3c62a3"} 2021/04/10 12: 33: 00 Doing some work... @@ -29,23 +26,17 @@ ## Output With CTRL+C -```json +```bash 2021-04-10T12:28: 45.591+0200 INFO sched sched/schedule.go: 96 Job Schedule Started {"id": "cron"} -2021-04-10T12:28: 45.592+0200 INFO sched sched/schedule.go: 168 Job Next Run Scheduled {"id": "cron", "After": "14s", "At": "2021-04-10T12:29:00+02:00" -} +2021-04-10T12:28: 45.592+0200 INFO sched sched/schedule.go: 168 Job Next Run Scheduled {"id": "cron", "After": "14s", "At": "2021-04-10T12:29:00+02:00"} 2021-04-10T12: 29: 00.000+0200 INFO sched sched/schedule.go: 168 Job Next Run Scheduled {"id": "cron", "After": "1m0s", "At": "2021-04-10T12:30:00+02:00"} 2021-04-10T12: 29:00.000+0200 INFO sched sched/schedule.go: 193 Job Run Starting {"id": "cron", "Instance": "786540f1-594b-44a0-9a66-7181619e38a6"} 2021/04/10 12: 29: 00 Doing some work... CTRL+C 2021-04-10T12: 29: 00.567+0200 INFO sched sched/schedule.go: 125 Stopping Schedule... {"id": "cron"} -2021-04-10T12: 29: 00.567+0200 INFO sched sched/schedule.go: 130 Waiting active jobs to finish... {"id": "cron" -} -2021-04-10T12: 29: 00.567+0200 INFO sched sched/schedule.go: 171 Job Next Run Canceled {"id": "cron", "At": "2021-04-10T12:30:00+02:00" -} +2021-04-10T12: 29: 00.567+0200 INFO sched sched/schedule.go: 130 Waiting active jobs to finish... {"id": "cron"} +2021-04-10T12: 29: 00.567+0200 INFO sched sched/schedule.go: 171 Job Next Run Canceled {"id": "cron", "At": "2021-04-10T12:30:00+02:00"} 2021/04/10 12: 29: 01 Finished Work. -2021-04-10T12: 29:01.000+0200 INFO sched sched/schedule.go: 208 Job Finished {"id": "cron", "Instance": "786540f1-594b-44a0-9a66-7181619e38a6", "Duration": "1s", "State": "FINISHED" -} -2021-04-10T12: 29: 01.000+0200 INFO sched sched/schedule.go: 133 Job Schedule Stopped { -"id": "cron" -} +2021-04-10T12: 29:01.000+0200 INFO sched sched/schedule.go: 208 Job Finished {"id": "cron", "Instance": "786540f1-594b-44a0-9a66-7181619e38a6", "Duration": "1s", "State": "FINISHED"} +2021-04-10T12: 29: 01.000+0200 INFO sched sched/schedule.go: 133 Job Schedule Stopped {"id": "cron" } ``` diff --git a/examples/schedule-fixed/README.md b/examples/schedule-fixed/README.md index 3698775..eb3718b 100644 --- a/examples/schedule-fixed/README.md +++ b/examples/schedule-fixed/README.md @@ -4,15 +4,13 @@ ```json 2021-04-10T12:58: 48.724+0200 INFO sched sched/schedule.go: 96 Job Schedule Started {"id": "every30s"} -2021-04-10T12:58: 48.725+0200 INFO sched sched/schedule.go: 168 Job Next Run Scheduled {"id": "every30s", "After": "30s", "At": "2021-04-10T12:59:18+02:00" -} +2021-04-10T12:58: 48.725+0200 INFO sched sched/schedule.go: 168 Job Next Run Scheduled {"id": "every30s", "After": "30s", "At": "2021-04-10T12:59:18+02:00"} 2021-04-10T12: 59: 18.729+0200 INFO sched sched/schedule.go: 168 Job Next Run Scheduled {"id": "every30s", "After": "30s", "At": "2021-04-10T12:59:48+02:00"} 2021-04-10T12: 59:18.729+0200 INFO sched sched/schedule.go: 193 Job Run Starting {"id": "every30s", "Instance": "e05aa702-f11c-46ba-8d7c-6ae4049c382d"} 2021/04/10 12: 59: 18 Doing some work... 2021/04/10 12: 59: 19 Finished Work. 2021-04-10T12: 59: 19.733+0200 INFO sched sched/schedule.go: 208 Job Finished {"id": "every30s", "Instance": "e05aa702-f11c-46ba-8d7c-6ae4049c382d", "Duration": "1.004s", "State": "FINISHED"} -2021-04-10T12:59: 48.724+0200 INFO sched sched/schedule.go: 168 Job Next Run Scheduled {"id": "every30s", "After": "30s", "At": "2021-04-10T13:00:18+02:00" -} +2021-04-10T12:59: 48.724+0200 INFO sched sched/schedule.go: 168 Job Next Run Scheduled {"id": "every30s", "After": "30s", "At": "2021-04-10T13:00:18+02:00"} 2021-04-10T12: 59: 48.724+0200 INFO sched sched/schedule.go: 193 Job Run Starting {"id": "every30s", "Instance": "80ed574e-e4fc-4a9f-9741-6eda96ebd470"} 2021/04/10 12: 59: 48 Doing some work... 2021/04/10 12: 59: 49 Finished Work. @@ -23,10 +21,8 @@ 2021/04/10 13: 00: 18 Doing some work... 2021/04/10 13: 00: 19 Finished Work. 2021-04-10T13: 00: 19.729+0200 INFO sched sched/schedule.go:208 Job Finished {"id": "every30s", "Instance": "6bc1402c-a5e4-4634-9e49-acaaa6dcb5d0", "Duration": "1.003s", "State": "FINISHED"} -2021-04-10T13: 00: 48.725+0200 INFO sched sched/schedule.go: 168 Job Next Run Scheduled {"id": "every30s", "After": "30s", "At": "2021-04-10T13:01:18+02:00" -} -2021-04-10T13: 00: 48.725+0200 INFO sched sched/schedule.go:193 Job Run Starting {"id": "every30s", "Instance": "ed82fdd5-63a0-4fb4-b6a3-7fb74a973d1a" -} +2021-04-10T13: 00: 48.725+0200 INFO sched sched/schedule.go: 168 Job Next Run Scheduled {"id": "every30s", "After": "30s", "At": "2021-04-10T13:01:18+02:00"} +2021-04-10T13: 00: 48.725+0200 INFO sched sched/schedule.go:193 Job Run Starting {"id": "every30s", "Instance": "ed82fdd5-63a0-4fb4-b6a3-7fb74a973d1a"} 2021/04/10 13: 00: 48 Doing some work... 2021/04/10 13: 00: 49 Finished Work. 2021-04-10T13: 00: 49.730+0200 INFO sched sched/schedule.go: 208 Job Finished {"id": "every30s", "Instance": "ed82fdd5-63a0-4fb4-b6a3-7fb74a973d1a", "Duration": "1.005s", "State": "FINISHED"} @@ -36,8 +32,7 @@ 2021/04/10 13: 01: 19 Finished Work. 2021-04-10T13: 01: 19.728+0200 INFO sched sched/schedule.go: 208 Job Finished {"id": "every30s", "Instance": "a48eb5fa-2f62-4e9d-ae4e-550fbedc0cd6", "Duration": "1.003s", "State": "FINISHED"} 2021-04-10T13: 01: 48.725+0200 INFO sched sched/schedule.go: 168 Job Next Run Scheduled {"id": "every30s", "After": "30s", "At": "2021-04-10T13:02:18+02:00"} -2021-04-10T13: 01: 48.725+0200 INFO sched sched/schedule.go: 193 Job Run Starting {"id": "every30s", "Instance": "2347a38f-82d8-45aa-abb9-1f5192f53a09" -} +2021-04-10T13: 01: 48.725+0200 INFO sched sched/schedule.go: 193 Job Run Starting {"id": "every30s", "Instance": "2347a38f-82d8-45aa-abb9-1f5192f53a09"} 2021/04/10 13: 01:48 Doing some work... 2021/04/10 13: 01: 49 Finished Work. 2021-04-10T13: 01: 49.725+0200 INFO sched sched/schedule.go: 208 Job Finished {"id": "every30s", "Instance": "2347a38f-82d8-45aa-abb9-1f5192f53a09", "Duration": "1s", "State": "FINISHED" @@ -47,17 +42,13 @@ 2021/04/10 13: 02: 18 Doing some work... 2021/04/10 13: 02:19 Finished Work. 2021-04-10T13: 02: 19.722+0200 INFO sched sched/schedule.go: 208 Job Finished {"id": "every30s", "Instance": "b4f52aa8-999a-4d46-8cd0-f49c91b22ca3", "Duration": "1.001s", "State": "FINISHED"} -2021-04-10T13: 02: 48.721+0200 INFO sched sched/schedule.go: 193 Job Run Starting {"id": "every30s", "Instance": "e2c32b53-556c-48ca-98b0-9d39aa0fbd61" -} -2021-04-10T13:02: 48.721+0200 INFO sched sched/schedule.go: 168 Job Next Run Scheduled {"id": "every30s", "After": "30s", "At": "2021-04-10T13:03:18+02:00" -} +2021-04-10T13: 02: 48.721+0200 INFO sched sched/schedule.go: 193 Job Run Starting {"id": "every30s", "Instance": "e2c32b53-556c-48ca-98b0-9d39aa0fbd61"} +2021-04-10T13:02: 48.721+0200 INFO sched sched/schedule.go: 168 Job Next Run Scheduled {"id": "every30s", "After": "30s", "At": "2021-04-10T13:03:18+02:00"} 2021/04/10 13:02: 48 Doing some work... 2021/04/10 13: 02: 49 Finished Work. -2021-04-10T13: 02: 49.722+0200 INFO sched sched/schedule.go: 208 Job Finished {"id": "every30s", "Instance": "e2c32b53-556c-48ca-98b0-9d39aa0fbd61", "Duration": "1s", "State": "FINISHED" -} +2021-04-10T13: 02: 49.722+0200 INFO sched sched/schedule.go: 208 Job Finished {"id": "every30s", "Instance": "e2c32b53-556c-48ca-98b0-9d39aa0fbd61", "Duration": "1s", "State": "FINISHED"} 2021-04-10T13: 03: 18.719+0200 INFO sched sched/schedule.go: 168 Job Next Run Scheduled {"id": "every30s", "After": "30s", "At": "2021-04-10T13:03:48+02:00"} -2021-04-10T13: 03: 18.719+0200 INFO sched sched/schedule.go: 193 Job Run Starting {"id": "every30s", "Instance": "6a8aa794-3c9c-4ffe-a2a6-c4b78f31dd57" -} +2021-04-10T13: 03: 18.719+0200 INFO sched sched/schedule.go: 193 Job Run Starting {"id": "every30s", "Instance": "6a8aa794-3c9c-4ffe-a2a6-c4b78f31dd57"} 2021/04/10 13: 03: 18 Doing some work... 2021/04/10 13:03: 19 Finished Work. ... diff --git a/examples/schedule-prom-metrics/README.md b/examples/schedule-prom-metrics/README.md index 9f2ebf1..6551940 100644 --- a/examples/schedule-prom-metrics/README.md +++ b/examples/schedule-prom-metrics/README.md @@ -3,59 +3,38 @@ ## Output -```json +``` # HELP sched_run_actual_elapsed_time sched_run_actual_elapsed_time summary # TYPE sched_run_actual_elapsed_time summary -sched_run_actual_elapsed_time{ID="every5s", quantile="0.5" -} 0.205075002 -sched_run_actual_elapsed_time{ -ID="every5s", quantile="0.75" -} 1.103087326 -sched_run_actual_elapsed_time{ -ID="every5s", quantile="0.95" -} 2.204325295 -sched_run_actual_elapsed_time{ -ID="every5s",quantile="0.99" -} 2.204325295 -sched_run_actual_elapsed_time{ -ID="every5s", quantile="0.999" -} 2.204325295 -sched_run_actual_elapsed_time_sum{ -ID="every5s" -} 3.713109351 -sched_run_actual_elapsed_time_count{ -ID="every5s" -} 4 +sched_run_actual_elapsed_time{id="every5s",quantile="0.5"} 0.203843151 +sched_run_actual_elapsed_time{id="every5s",quantile="0.75"} 1.104031623 +sched_run_actual_elapsed_time{id="every5s",quantile="0.95"} 1.104031623 +sched_run_actual_elapsed_time{id="every5s",quantile="0.99"} 1.104031623 +sched_run_actual_elapsed_time{id="every5s",quantile="0.999"} 1.104031623 +sched_run_actual_elapsed_time_sum{id="every5s"} 1.307874774 +sched_run_actual_elapsed_time_count{id="every5s"} 2 # HELP sched_run_errors sched_run_errors counter # TYPE sched_run_errors counter -sched_run_errors{ID="every5s"} 0 +sched_run_errors{id="every5s"} 0 +# HELP sched_run_exceed_expected_time sched_run_exceed_expected_time counter +# TYPE sched_run_exceed_expected_time counter +sched_run_exceed_expected_time{id="every5s"} 0 # HELP sched_run_total_elapsed_time sched_run_total_elapsed_time summary # TYPE sched_run_total_elapsed_time summary -sched_run_total_elapsed_time{ -ID="every5s", quantile="0.5" -} 0.205178562 -sched_run_total_elapsed_time{ID="every5s", quantile="0.75" -} 1.103123691 -sched_run_total_elapsed_time{ -ID="every5s", quantile="0.95" -} 2.204367762 -sched_run_total_elapsed_time{ -ID="every5s", quantile="0.99" -} 2.204367762 -sched_run_total_elapsed_time{ -ID="every5s",quantile="0.999" -} 2.204367762 -sched_run_total_elapsed_time_sum{ -ID="every5s" -} 3.7133283589999997 -sched_run_total_elapsed_time_count{ID="every5s"} 4 +sched_run_total_elapsed_time{id="every5s",quantile="0.5"} 0.203880714 +sched_run_total_elapsed_time{id="every5s",quantile="0.75"} 1.104065614 +sched_run_total_elapsed_time{id="every5s",quantile="0.95"} 1.104065614 +sched_run_total_elapsed_time{id="every5s",quantile="0.99"} 1.104065614 +sched_run_total_elapsed_time{id="every5s",quantile="0.999"} 1.104065614 +sched_run_total_elapsed_time_sum{id="every5s"} 1.307946328 +sched_run_total_elapsed_time_count{id="every5s"} 2 # HELP sched_runs sched_runs counter # TYPE sched_runs counter -sched_runs{ID="every5s"} 3 +sched_runs{id="every5s"} 2 # HELP sched_runs_overlapping sched_runs_overlapping counter # TYPE sched_runs_overlapping counter -sched_runs_overlapping{ID="every5s"} 0 +sched_runs_overlapping{id="every5s"} 0 # HELP sched_up sched_up gauge # TYPE sched_up gauge -sched_up{ID="every5s"} 1 +sched_up{id="every5s"} 1 ``` diff --git a/job/job.go b/job/job.go index c4e4fe8..85e37cf 100644 --- a/job/job.go +++ b/job/job.go @@ -40,7 +40,7 @@ func NewJobWithID(id string, jobFunc func()) *Job { } } -//NewJob Create new Job, ID is assigned a UUID instead. +//NewJob Create new Job, id is assigned a UUID instead. func NewJob(jobFunc func()) *Job { return NewJobWithID(uuid.New().String(), jobFunc) } diff --git a/metric.go b/metric.go index c75fe13..9a2c847 100644 --- a/metric.go +++ b/metric.go @@ -20,13 +20,13 @@ type metrics struct { func newMetrics(name string, metricsScope tally.Scope) *metrics { subScope := metricsScope.SubScope("sched") return &metrics{ - up: subScope.Tagged(map[string]string{"ID": name}).Gauge("up"), - runs: subScope.Tagged(map[string]string{"ID": name}).Counter("runs"), - overlappingCount: subScope.Tagged(map[string]string{"ID": name}).Counter("runs_overlapping"), - runActualElapsed: subScope.Tagged(map[string]string{"ID": name}).Timer("run_actual_elapsed_time"), - runTotalElapsed: subScope.Tagged(map[string]string{"ID": name}).Timer("run_total_elapsed_time"), - runErrors: subScope.Tagged(map[string]string{"ID": name}).Counter("run_errors"), - runExceedExpected: subScope.Tagged(map[string]string{"ID": name}).Counter("run_exceed_expected_time"), + up: subScope.Tagged(map[string]string{"id": name}).Gauge("up"), + runs: subScope.Tagged(map[string]string{"id": name}).Counter("runs"), + overlappingCount: subScope.Tagged(map[string]string{"id": name}).Counter("runs_overlapping"), + runActualElapsed: subScope.Tagged(map[string]string{"id": name}).Timer("run_actual_elapsed_time"), + runTotalElapsed: subScope.Tagged(map[string]string{"id": name}).Timer("run_total_elapsed_time"), + runErrors: subScope.Tagged(map[string]string{"id": name}).Counter("run_errors"), + runExceedExpected: subScope.Tagged(map[string]string{"id": name}).Counter("run_exceed_expected_time"), } } diff --git a/schedule.go b/schedule.go index ca3cb53..202d38e 100644 --- a/schedule.go +++ b/schedule.go @@ -12,7 +12,7 @@ import ( // Schedule A Schedule is an object that wraps a Job (func(){}) and runs it on a schedule according to the supplied // Timer; With the the ability to expose metrics, and write logs to indicate job health, state, and stats. type Schedule struct { - ID string + id string // Source function used to create job.Job jobSrcFunc func() @@ -67,7 +67,7 @@ func NewSchedule(id string, timer Timer, jobFunc func(), opts ...Option) *Schedu metrics := *newMetrics(id, options.metricsScope) return &Schedule{ - ID: id, + id: id, state: NEW, jobSrcFunc: jobFunc, timer: timer, diff --git a/scheduler.go b/scheduler.go index f8253ab..29c1acc 100644 --- a/scheduler.go +++ b/scheduler.go @@ -27,7 +27,7 @@ func (s *Scheduler) Add(id string, timer Timer, job func(), extraOpts ...Option) defer s.mx.Unlock() if _, ok := s.schedules[id]; ok { - return fmt.Errorf("job with this ID already exists") + return fmt.Errorf("job with this id already exists") } // Create schedule @@ -39,7 +39,7 @@ func (s *Scheduler) Add(id string, timer Timer, job func(), extraOpts ...Option) return nil } -//Start Start the Schedule with the given ID. Return error if no Schedule with the given ID exist. +//Start Start the Schedule with the given id. Return error if no Schedule with the given id exist. func (s *Scheduler) Start(id string) error { s.mx.Lock() defer s.mx.Unlock() @@ -65,7 +65,7 @@ func (s *Scheduler) StartAll() { } } -//Stop Stop the Schedule with the given ID. Return error if no Schedule with the given ID exist. +//Stop Stop the Schedule with the given id. Return error if no Schedule with the given id exist. func (s *Scheduler) Stop(id string) error { s.mx.Lock() defer s.mx.Unlock()