Skip to content

umputun/cronn

Repository files navigation

cronn - cli cron replacement and scheduler container

Cronn | cli cron replacement and scheduler container

Build Status Coverage Status

Cronn is a crontab jobs scheduler with some nice extras. It allows to run commands on specified time intervals and can be used directly as well as from a container.

Use cases

  • Run any job with easy to use cli scheduler
  • Schedule tasks in containers (cronn can be used as CMD or ENTRYPOINT)
  • Use umputun/cronn as a base image

In addition cronn provides:

  • Both single-job scheduler and more traditional crontab file with multiple jobs
  • Runs as an ordinary process or the entry point of a container
  • Supports wide range of date templates
  • Optional notification on failed or/and passed jobs using email, Slack, Telegram, or webhook
  • Optional jitter adding a random delay prior to execution of a job
  • Automatic resume (restart) of jobs in cronn service or container failed unexpectedly
  • Reload crontab file on changes
  • Optional repeater for failed jobs
  • Optional de-duplication preventing the same jobs to run in parallel
  • Rotated logs

Basic usage

  • cronn -c "30 23 * * 1-5 command arg1 arg2 ..." - runs command with arg1 and arg2 every day at 23:30
  • cronn -c "@every 5s ls -la" - runs ls -la every 5 seconds
  • cronn -f crontab - runs jobs from the crontab file

Scheduling can be defined as:

  • standard 5-parts crontab syntax minute, hour, day-of-month, month, day-of-week
  • @syntax (descriptors), like @every 5m, @midnight, @daily, @yearly, @annually, @monthly, @weekly and @hourly.

Cronn also understands various day-realted templates evaluated at the time of job's execution:

  • {{.YYYYMMDD}} - current day in local TZ
  • {{.YYYY}} - current year
  • {{.YYYYMM}} - year and month
  • {{.YY}} - current year (short form)
  • {{.MM}} - current month
  • {{.DD}} - current day
  • {{.ISODATE} - day-time formatted as 2006-01-02T00:00:00.000Z (RFC3339)
  • {{.UNIX}} - unix timestamp (in seconds)
  • {{.UNIXMSEC}} - unix timestamp (in milliseconds)

Templates can be passed in command line or crontab file and will be evaluated and replaced at the moment cronn executes the command. For example cronn "0 0 * * 1-5" echo {{.YYYYMMDD}} will print the current date every weekday on midnight.

Optional modes

By default, all the optional modes are disabled. This includes:

  • Logging mode
  • Debug mode: produces more debug info
  • Auto-resume mode: executes terminated task(s) on startup.
  • Auto-update mode: checks for changes in crontab file (-f mode only) and reloads updated jobs.
  • Reload crontab on SIGHUP signal
  • Notification mode: sends email, Slack, Telegram and\or Webhook notifications on failed or passed jobs
  • De-duplication mode: prevents the same jobs to run in parallel
  • Repeater mode: repeats failed jobs
  • Rotated logs: creates rotated logs
  • Jitter mode: adds a random delay prior to execution of a job

Auto-Resume

  • auto-resume mode is disabled by default. To enable it, add --resume=<directory> to the command line or set $CRONN_RESUME environment variable.
  • each task creates a flag-file named as <ts>-<seq>.cronn in $CRONN_RESUME directory and removes this flag on completion.
  • flag file's content is the command line for the running job.
  • at the start time cronn will discover all flag files and will execute them sequentially in case if multiple flag files discovered. Note: it won't block usual, scheduled tasks and it is possible to have initial (auto-resume) task running in parallel with regular tasks.
  • old resume files (>=24h) ignored
  • usually it is not necessary to map $CRONN_RESUME location to host's FS as we don't want it to survive container recreation. However, it will survive container's restart.
  • by default resume jobs executed sequentially, but can be configured to run in parallel with --resume-concur=2..N option.

Auto-Update

  • auto-update mode is disabled by default. To enable it, add --update to the command line or set $CRONN_UPDATE environment variable.
  • if enabled, cronn will check for changes in crontab file (-f mode only) and reload updated jobs.
  • the check is performed every 10 seconds by default and can be changed with --update-interval=<duration> option.
  • user can send SIGHUP signal to cronn to force update check.
  • if user wishes to disable aut-update check but allow SIGHUP reloads the --update-interval can be set to 0s. Pls note: in order to reload crontab file on SIGHUP signal update mode has to be enabled with --update.

Repeater

  • Optional repeater retries failed job multiple times. It uses backoff strategy with an exponential interval.
  • Duration interval goes in steps with last * math.Pow(factor, attempt) increments.
  • Optional jitter randomizes intervals a little bit. Factor = 1 effectively makes this strategy fixed with duration delay.

Deduplication

Optional de-duplication prevents the same jobs to run in parallel. Jobs are identified by their command line and scheduling. By default this option is off. To enable it, add --dedup to the command line or set $CRONN_DEDUP environment variable.

Notifications

You can enable one or more notification methods: Slack, Webhook, Telegram, and Email. Either --notify.enabled-error or --notify.enabled-complete or both should be enabled for notifications to work.

Email

Enabled if --notify.to option is set, which could be list of emails. Please set all SMTP-related options for the email notifications to work.

Slack

Enabled if --notify.slack-channels option is set, which could be list of channels, channelIDs, and userIDs. Please set --notify.slack-token for this method to work.

Webhook

Enabled if --notify.webhook-urls option is set, which could be list of URLs.

Telegram

Enabled if --notify.telegram-destinations option is set, which could be list of channels, userIDs, and channelIDs (a number, like -1001480738202: use that instruction to obtain it). Please set --notify.telegram-token obtained from BotFather for this method to work.

Text of notification is expected to be in HTML, tags which are not allowed in Telegram will be automatically removed.

Notification text

When enabled, notifications are sent to the specified destinations on job failure or completion. User can define custom templates for notifications messages with --notify.complete-template and --notify.err-template options. Default templates are in HTML. The following variables are available:

  • {{.Command}} - the command with arguments
  • {{.Spec}} - the crontab specification
  • {{.Host}} - the hostname of the machine where the job is running
  • {{.TS}} - the time-stamp of event
  • {{.Error}} - the error message if any

Logging

  • In order to allow logging, add --log.enabled to the command line or set $CRONN_LOG_ENABLED environment variable.
  • By default logs send to stdout and errors to stderr.
  • To specify log file, add --log.filename=<path> to the command line or set $CRONN_LOG_FILE environment variable.
  • Files are rotated every according to --log.max-size=<size>, --log.max-files=<files> and --log.max-age=<days> options.
  • The maximum number of rotated backup files set with --log.max-backups=<files>.
  • To turn compression on, add --log.enabled-compress to the command line or set $CRONN_LOG_ENABLED_COMPRESS environment variable.

Things to know

  1. CTRL-C won't kill cronn process right away but will wait till job(s) completion
  2. each job runs as sh -c cmd args... to allow use of env and all other shell-related goodies

All application Options

  -f, --file=                     crontab file (default: crontab) [$CRONN_FILE]
  -c, --command=                  crontab single command [$CRONN_COMMAND]
  -r, --resume=                   auto-resume location [$CRONN_RESUME]
      --resume-concur=            auto-resume concurrency level (default: 1) [$CRONN_RESUME_CONCUR]
  -u, --update                    auto-update mode [$CRONN_UPDATE]
      --update-interval=          auto-update interval (default: 10s) [$CRONN_UPDATE_INTERVAL]
  -j, --jitter                    enable jitter [$CRONN_JITTER]
      --jitter-duration=          jitter duration (default: 10s) [$CRONN_JITTER_DURATION]
      --dedup                     prevent duplicated jobs [$CRONN_DEDUP]

repeater:
      --repeater.attempts=        how many time repeat failed job (default: 1) [$CRONN_REPEATER_ATTEMPTS]
      --repeater.duration=        initial duration (default: 1s) [$CRONN_REPEATER_DURATION]
      --repeater.factor=          backoff factor (default: 3) [$CRONN_REPEATER_FACTOR]
      --repeater.jitter           jitter [$CRONN_REPEATER_JITTER]

notify:
      --notify.enabled-error          enable email notifications on errors [$CRONN_NOTIFY_ENABLED_ERROR]
      --notify.enabled-complete       enable completion notifications [$CRONN_NOTIFY_ENABLED_COMPLETE]
      --notify.err-template=          error template file [$CRONN_NOTIFY_ERR_TEMPLATE]
      --notify.complete-template=     completion template file [$CRONN_NOTIFY_COMPLET_TEMPLATE]
      --notify.smtp-host=             SMTP host [$CRONN_NOTIFY_SMTP_HOST]
      --notify.smtp-port=             SMTP port [$CRONN_NOTIFY_SMTP_PORT]
      --notify.smtp-username=         SMTP user name [$CRONN_NOTIFY_SMTP_USERNAME]
      --notify.smtp-password=         SMTP password [$CRONN_NOTIFY_SMTP_PASSWORD]
      --notify.smtp-tls               enable SMTP TLS [$CRONN_NOTIFY_SMTP_TLS]
      --notify.smtp-starttls          enable SMTP StartTLS [$CRONN_NOTIFY_SMTP_STARTTLS]
      --notify.smtp-timeout=          SMTP TCP connection timeout (default: 10s) [$CRONN_NOTIFY_SMTP_TIMEOUT]
      --notify.from=                  SMTP from email [$CRONN_NOTIFY_FROM]
      --notify.to=                    SMTP to email(s) [$CRONN_NOTIFY_TO]
      --notify.max-log=               max number of log lines name (default: 100) [$CRONN_NOTIFY_MAX_LOG]
      --notify.host=                  host name running cronn [$CRONN_NOTIFY_HOSTNAME]
      --notify.slack-token=           API token for the Slack bot [$CRONN_NOTIFY_SLACK_TOKEN]
      --notify.slack-channels=        List of Slack channels the bot will post messages to [$CRONN_NOTIFY_SLACK_CHANNELS]
      --notify.telegram-token=        API token for the Telegram bot [$CRONN_NOTIFY_TELEGRAM_TOKEN]
      --notify.telegram-destinations= List of Telegram chat IDs the bot will post messages to [$CRONN_NOTIFY_TELEGRAM_DESTINATIONS]
      --notify.webhook-urls=          List of webhook URLs the bot will post messages to [$CRONN_NOTIFY_WEBHOOK_URLS]
      --notify.timeout=                timeout for notifications (default: 10s) [$TIMEOUT]
log:
      --log.enabled               enable logging [$CRONN_LOG_ENABLED]
      --log.debug                 debug mode [$CRONN_LOG_DEBUG]
      --log.prefix                enable log prefix with current command [$CRONN_LOG_PREFIX]
      --log.filename=             file to write logs to. Log to stdout if not specified [$CRONN_LOG_FILENAME]
      --log.max-size=             maximum size in megabytes of the log file before it gets rotated (default: 100) [$CRONN_LOG_MAX_SIZE]
      --log.max-age=              maximum number of days to retain old log files (default: 0) [$CRONN_LOG_MAX_AGE]
      --log.max-backups=          maximum number of old log files to retain (default: 7) [$CRONN_LOG_MAX_BACKUPS]
      --log.enabled-compress      determines if the rotated log files should be compressed using gzip [$CRONN_LOG_ENABLED_COMPRESS]

Help Options:
  -h, --help                      Show this help message

Credits