A Rust-based task scheduler to run commands at specified intervals, providing a modern alternative to traditional cron jobs. It supports YAML-based configuration, flexible scheduling syntax, and various output options.
- YAML-based configuration
- Flexible scheduling syntax
- Timezone support
- Command execution
- Config validation
- Configurable logging (stdout, file, or syslog)
- Concurrent execution prevention
- Custom working directory
- Configurable output redirection
- Time limits for tasks
- Environment variable support
- Run as different user
- Alert system for task failures (email, webhook, command)
- Support for cron syntax conversion
- Multiple config file locations support
- Task execution time measurement
- Shell customization
- Parallel task execution
See the default config for the list of available options.
cargo install --path .- Create a configuration file, run the following to generate a sample configuration file:
cron-rs generate-config > config.yml- Run the scheduler:
cron-rs run- Validate your configuration:
cron-rs validate ./config.yml- Convert from existing crontab configuration:
cron-rs generate-from-crontab > config.ymlThe scheduler will look for configuration files in the following locations (in order):
- Path specified with
--configargument ./config.ymlin current directory$XDG_CONFIG_HOME/cron-rs/config.ymlor$HOME/.config/cron-rs/config.yml/etc/cron-rs.yml
name: Unique identifier for the taskcmd: Command to executetimezone: Timezone for the task (optional, defaults to system timezone)avoid_overlapping: Boolean flag to prevent concurrent execution (optional, defaults to false)working_directory: Working directory for the task (optional, defaults to current directory)stdout: Path for stdout redirection (optional)stderr: Path for stderr redirection (optional)time_limit: Maximum execution time in seconds (optional)env: Environment variables for the task (optional)run_as: User to run the task as (optional)shell: Shell to use for command execution (optional, defaults to /bin/sh)
You can use either when or every to specify when a task should run:
when:
day_of_week: [Mon, Tue, Wed, Thu, Fri, Sat, Sun]
year: '*' # or specific year
month: '*' # or specific month
day: '*' # or specific day
hour: '*' # or specific hour
minute: '*' # or specific minute
second: '*' # or specific secondevery: "5 minutes" # or "1 hour", "2 days", etc.You can configure alerts to be sent when tasks fail:
alerts:
on_failure:
# Email alert
- type: email
to: '[email protected]'
subject: 'Task failed'
body: 'The task {{ task_name }} failed with exit code {{ exit_code }}'
smtp_server: 'smtp.example.com'
smtp_port: 587
smtp_username: '[email protected]'
smtp_password: 'password'
# Command alert
- type: cmd
cmd: 'mail -s "Task failed" [email protected]'
# Webhook alert
- type: webhook
url: 'https://example.com/webhook'
method: POST
body: '{"task_name": "{{ task_name }}", "exit_code": "{{ exit_code }}"}'
headers:
Content-Type: application/jsonYou can set a maximum execution time for tasks. If a task exceeds its time limit, it will be terminated:
tasks:
- name: TimeLimitedTask
cmd: sleep 600
every: "1 minute"
time_limit: 300 # Task will be terminated after 5 minutesYou can specify environment variables for each task:
tasks:
- name: EnvTask
cmd: echo $MY_VAR
every: "5 minutes"
env:
MY_VAR: "Hello, World!"
PATH: /custom/path:/usr/bin:/binYou can run tasks as a different user:
tasks:
- name: WebTask
cmd: touch /var/www/html/test.txt
every: "1 hour"
run_as: www-dataNote: The scheduler must have sufficient permissions to run commands as the specified user.
By default, task output is redirected to files in a .tmp directory:
- Standard output goes to
.tmp/{task_name}_stdout.log - Standard error goes to
.tmp/{task_name}_stderr.log
You can customize these paths using the stdout and stderr options:
tasks:
- name: CustomOutputTask
cmd: echo "Hello, World!"
every: "1 minute"
stdout: /var/log/myapp/stdout.log
stderr: /var/log/myapp/stderr.logTasks run in the current directory by default. You can specify a different working directory using the working_directory option:
tasks:
- name: WorkInDirectory
cmd: ls -la
every: "5 minutes"
working_directory: /path/to/directoryThe avoid_overlapping option prevents multiple instances of the same task from running simultaneously. When enabled:
- The scheduler checks if a previous instance of the task is still running
- If a previous instance is found, the new execution is skipped
- A warning is logged when execution is skipped due to overlapping
Example:
tasks:
- name: LongRunningTask
cmd: sleep 60
every: "30 seconds"
avoid_overlapping: true # This task will never run concurrentlyThe logging configuration supports three output types:
stdout(default): Logs are written to standard outputfile: Logs are written to a specified filesyslog: Logs are written to the system syslog
Example configurations:
# Log to stdout (default)
logging:
output: stdout
level: info
# Log to file
logging:
output: file
level: debug
path: /var/log/cron-rs.log
# Log to syslog
logging:
output: syslog
level: warnThe configuration file supports two formats for specifying when a task should run:
when:
day_of_week: [Mon, Tue, Wed, Thu, Fri, Sat, Sun]
year: '*' # or specific year
month: '*' # or specific month
day: '*' # or specific day
hour: '*' # or specific hour
minute: '*' # or specific minute
second: '*' # or specific secondThe compact format follows this structure:
[days_of_week] year-month-day hour:minute:second
when: '[Mon,Tue] *-*/2-01..04 12:00:00'[Mon,Tue]: The task will run only on Mondays and Tuesdays*: Any year*/2: Every other month (January, March, May, July, September, November)01..04: Days 1 through 4 of the month12:00:00: At exactly 12:00:00 (noon)
*: Matches any value (wildcard)n: Exact match (e.g.,5for the 5th day)n..m: Range (e.g.,1..5for days 1 through 5, both included)*/n: Every nth value (e.g.,*/2for every other value)[a,b,c]: List of values (e.g.,[Mon,Wed,Fri]for those specific days)
You can combine these patterns for powerful scheduling flexibility.
You can specify a timezone for each task using the timezone field:
timezone: 'Europe/Madrid'If not defined, it will use the system's default timezone.