{"id":16842098,"url":"https://github.com/theckman/cronner","last_synced_at":"2025-08-30T17:30:37.934Z","repository":{"id":45462629,"uuid":"75374226","full_name":"theckman/cronner","owner":"theckman","description":"cron job runner; statsd metrics with optional DogStatsd event emissions","archived":false,"fork":false,"pushed_at":"2020-12-23T21:37:46.000Z","size":576,"stargazers_count":55,"open_issues_count":1,"forks_count":6,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-12-16T16:48:21.223Z","etag":null,"topics":["cron","datadog","dogstatsd","metrics","monitoring","statsd"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/theckman.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-12-02T08:00:26.000Z","updated_at":"2024-01-11T21:22:01.000Z","dependencies_parsed_at":"2022-07-14T11:30:36.310Z","dependency_job_id":null,"html_url":"https://github.com/theckman/cronner","commit_stats":null,"previous_names":[],"tags_count":25,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theckman%2Fcronner","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theckman%2Fcronner/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theckman%2Fcronner/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theckman%2Fcronner/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/theckman","download_url":"https://codeload.github.com/theckman/cronner/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":231508405,"owners_count":18387386,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cron","datadog","dogstatsd","metrics","monitoring","statsd"],"created_at":"2024-10-13T12:44:21.497Z","updated_at":"2024-12-27T16:08:15.724Z","avatar_url":"https://github.com/theckman.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# cronner\n[![TravisCI Build Status](https://img.shields.io/travis/theckman/cronner/master.svg?style=flat)](https://travis-ci.org/theckman/cronner)\n\n`cronner` is a command line utility that wraps periodic (cron) jobs for statistics gathering and success monitoring.\nMetrics like the amount of time the command took to run, as well as the command's return code, are emitted as vanilla statsd metrics to port 8125.\nIt also implements file-level locking for a very simple and dumb job semaphore. This utility doesn't concern itself with the scheduling of jobs,\nand instead expects that it will be invoked by something like `cron`, `at`, or manually by an operator.\n\nThe utility also supports emitting [DogStatsD Events](http://docs.datadoghq.com/guides/dogstatsd/#events) on:\n\n* job start and job finish\n* job finish if the job failed\n* if the job is taking too long to finish running\n\nWhile there are no reports of issues having come up, if your statsd agent isn't DogStatsD-compliant its behavior\nmay be undefined if you try to emit events or attach tags to metrics.\n\nFor the finish DogStatsD event, the return code and output of the command are provided in the event body. If the output is too long, it is truncated. This output can optionally be saved to disk only if the job fails for later inspection.\n\n## Go 1.9+ Compatibility Notice\nVersion 1.0.0+ of `cronner` requires that the source be built against Go 1.9+. Go 1.9 released the transparent support for a monotonic time source,\nwithin the `time.Time` type. This change means that using `time.Now()` to keep track of how long something took is safe when leap seconds occur.\nThis was not the case before Go 1.9. If you attempt to build against an older Go runtime you should experience the following error:\n\n```\n./cronner.go:146: undefined: cronnerRequiresAtleastGoVersion19\n```\n\n## Project History\n`cronner` was originally developed as an internal application at PagerDuty and was subsequently open-sourced. The original repository can be found here:\n[PagerDuty/cronner](https://github.com/PagerDuty/cronner). After that project became unmaintained, this fork was created to continue the development\nand support of cronner.\n\nThe PagerDuty repository was officially deprecated in-favor of this one, with the final step being that this repository was detached from the\noriginal so it no longer appears to be a fork.\n\n## License\n`cronner` is released under the BSD 3-Clause License. See the `LICENSE` file for the full contents of the license.\n\n## Usage\n### Help Output\n\n```\nUsage:\n  cronner [OPTIONS] -- command [arguments]...\n\nApplication Options:\n  -d, --lock-dir=                  the directory where lock files will be placed (default: /var/lock)\n  -e, --event                      emit a start and end datadog event\n  -E, --event-fail                 only emit an event on failure\n  -F, --log-fail                   when a command fails, log its full output (stdout/stderr) to the log directory using the UUID as the filename\n  -g, --group=\u003cgroup\u003e              emit a cronner_group:\u003cgroup\u003e tag with statsd metrics\n  -G, --event-group=\u003cgroup\u003e        emit a cronner_group:\u003cgroup\u003e tag with Datadog events, does not get sent with statsd metrics\n  -H, --statsd-host=\u003chost\u003e         destination host to send datadog metrics\n  -k, --lock                       lock based on label so that multiple commands with the same label can not run concurrently\n  -l, --label=                     name for cron job to be used in statsd emissions and DogStatsd events. alphanumeric only; cronner will lowercase it\n      --log-path=                  where to place the log files for command output (path for -F/--log-fail output) (default: /var/log/cronner)\n  -L, --log-level=                 set the level at which to log at [none|error|info|debug] (default: error)\n  -N, --namespace=                 namespace for statsd emissions, value is prepended to metric name by statsd client (default: cronner)\n  -p, --passthru                   passthru stdout/stderr to controlling tty\n  -P, --use-parent                 if cronner invocation is runner under cronner, emit the parental values as tags\n  -s, --sensitive                  specify whether command output may contain sensitive details, this only avoids it being printed to stderr\n  -t, --tag=                       additional tags to add to datadog events and metrics (can be used multiple times), either \u003ckey\u003e:\u003cvalue\u003e or \u003cstring\u003e format\n  -V, --version                    print the version string and exit\n  -w, --warn-after=N               emit a warning event every N seconds if the job hasn't finished, set to 0 to disable (default: 0)\n  -W, --wait-secs=                 how long to wait for the file lock for (default: 0)\n\nHelp Options:\n  -h, --help                       Show this help message\n```\n\n### Running A Command\nThe label (`-l`, `--label`) flag is required.\n\nTo run the command `/bin/sleep 10` and emit the stats as `cronner.sleeptyime.time` and `cronner.sleepytime.exit_code` you would run:\n\n```\n$ cronner -l sleepytime -- /bin/sleep 10\n```\n\nNote that `--` in the command line arguments tells cronner to stop parsing CLI flags. It then grabs the rest of the arguments as the command to execute.\n\n#### Environment Variables\nThe `cronner` process sets a few environment variables for subprocesses to consume if they wish.\nThe `CRONNER_PARENT_UUID` environment variable is the canonical way for determining whether or not we are running under `cronner`.\n\n|Variable|Description|\n|---------|-----------|\n|`CRONNER_PARENT_UUID`|UUID being used by the parent `cronner` process for its events; use this being set to determine if running under cronner|\n|`CRONNER_PARENT_EVENT_GROUP`|event group used by the parent process for its events|\n|`CRONNER_PARENT_GROUP`|group used by the parent process for its metrics|\n|`CRONNER_PARENT_NAMESPACE`|namespace used by the parent process for its metrics|\n|`CRONNER_PARENT_LABEL`|label used by the parent process for its metrics|\n\nIf you invoke the `cronner` command with the `-P/--use-parent` flag it will look for these variables and tag the events and metrics emissions\nwith their values. It lowercases the variable name before emitting the tag, so `CRONNER_PARENT_GROUP` becomes `cronner_parent_group`.\n\n#### DogStatsd Emissions\nIf you were to have a UDP listener on port 8125 on localhost, the statsd emissions would look something like this:\n\n```\ncronner.sleepytime.time:10005.834649|ms\ncronner.sleepytime.exit_code:0|g\n```\n\nIt emits a timing metric for how long it took for the command to run, as well as the command's exit code.\n\n### Running A Command with a DogStatsD Event\nIf you want to run `/bin/sleep 5` as `sleepytime2` and emit a DogStatsD for when the job starts and finishes:\n\n```\n$ cronner -e -l sleepytime2 -- /bin/sleep 5\n```\n\nThe UDP datagrams emitted would then look like this:\n\n```\n_e{35,12}:Cron sleepytime2 starting on rinzler|job starting|k:ab31f2f6-498e-468a-b572-ab990065e8d3|s:cronner|t:info\ncronner.sleepytime2.time:5005.649979|ms\ncronner.sleepytime2.exit_code:0|g\n_e{55,22}:Cron sleepytime2 succeeded in 5.00565 seconds on rinzler|exit code: 0\\\\noutput:(none)|k:ab31f2f6-498e-468a-b572-ab990065e8d3|s:cronner|t:success\n```\n\n## Chef Cookbook\nTo make `cronner` easier to install and use, there is a\n[cronner](https://supermarket.chef.io/cookbooks/cronner) Chef cookbook\navailable for use. Not only does it allow you to install `cronner`, but it makes\nit easy to replace your `cron_d` resources with ones that will wrap the jobs\nwith `cronner`.\n\n## Contributors\n* Tim Heckman\n* Thomas Dziedzic\n* Alex Eftimie\n* Anthony O'Brien\n* Alex Hill\n* Andre Cloutier\n* R.T. Lechow\n\n## Development\n* set up your workspace as per the instructions for standard Go development\n* clone the cronner repository\n\n  ```BASH\n  git clone git@github.com:theckman/cronner.git\n  ```\n* make your changes to the codebase, including adding relevant test cases\n* run your tests to ensure all pass\n\n  ```BASH\n  go test -v ./... -check.vv\n  ```\n* confirm that building cronner works\n\n  ```BASH\n  go build\n  ```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftheckman%2Fcronner","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftheckman%2Fcronner","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftheckman%2Fcronner/lists"}