# SCRON

A lightweight, efficient cron-like scheduler written in Go that executes shell commands at specified intervals with precise timing and comprehensive logging.

## Features

- **Flexible Scheduling**: Schedule jobs using minute and hour patterns with wildcard support
- **Configuration Reloading**: Monitors config file changes for dynamic job updates
- **Comprehensive Logging**: Detailed execution logs using `zerolog` with configurable levels
- **Error Handling**: Robust error handling with exit code tracking and output capture
- **Shell Command Support**: Execute any shell command via bash

## Installation

### Prerequisites
- Go 1.24.1 or later

### Build from Source
```bash
git clone <repository-url>
cd scron
go build -o scron ./
```

## Configuration

Create a `config.yml` file in the same directory as the binary:

```yaml
jobs:
  - name: "Daily Backup"
    minute: "0"
    hour: "2"
    command: "backup.sh /data /backup"
  
  - name: "Health Check"
    minute: "*/5"
    hour: "*"
    command: "curl -f http://localhost:8080/health"
  
  - name: "Log Cleanup"
    minute: "30"
    hour: "1"
    command: "find /var/log -name '*.log' -mtime +7 -delete"
```

### Configuration Fields

| Field | Description | Format | Examples |
|-------|-------------|--------|----------|
| `name` | Descriptive job name for logging | String | "Daily Backup", "Health Check" |
| `minute` | Minute pattern (0-59) | String | `"0"`, `"*/5"`, `"15,30,45"`, `"*"` |
| `hour` | Hour pattern (0-23) | String | `"2"`, `"*/2"`, `"9-17"`, `"*"` |
| `command` | Shell command to execute | String | `"echo 'Hello'"`, `"backup.sh"` |

### Pattern Syntax
- `*` - Every minute/hour
- `*/n` - Every n minutes/hours
- `n` - Specific minute/hour
- `n,m,o` - Multiple specific values
- `n-m` - Range of values

## Usage

### Basic Usage
```bash
./scron
```

### With Debug Logging
```bash
ZEROLOG_LEVEL=debug ./scron
```

### Running as a Service
```bash
# systemd service example
sudo cp scron /usr/local/bin/
sudo cp config.yml /etc/scron/
# Create systemd service file...
```

## Development

### Testing
```bash
# Run all tests
go test ./...

# Run specific test
go test -run ^TestConfigParsing$ ./

# Run tests with coverage
go test -cover ./...
```

### Code Quality
```bash
# Format and vet code
go fmt ./... && go vet ./...

# Run linter (if golangci-lint is installed)
golangci-lint run
```

### Project Structure
```
scron/
├── main.go           # Main application entry point
├── config.go         # Configuration parsing and validation
├── config_test.go    # Configuration tests
├── time.go           # Time matching and cron logic
├── timer_test.go     # Timer and scheduling tests
├── error.go          # Custom error types
├── config.yml        # Example configuration
└── README.md         # This file
```

## Logging

SCRON uses structured logging with different levels:

- **Debug**: Detailed execution information, config parsing
- **Info**: Job execution start/completion
- **Warn**: Non-critical issues (empty config, etc.)
- **Error**: Execution failures, config errors
- **Fatal**: Critical errors that stop the application

Set log level via environment variable:
```bash
export ZEROLOG_LEVEL=debug  # debug, info, warn, error, fatal
```

## Examples

### Simple Periodic Task
```yaml
jobs:
  - name: "Heartbeat"
    minute: "*"
    hour: "*"
    command: "echo $(date): Service running >> /var/log/heartbeat.log"
```

### Business Hours Only
```yaml
jobs:
  - name: "Business Hours Check"
    minute: "0"
    hour: "9-17"
    command: "business-hours-task.sh"
```

### Multiple Schedules
```yaml
jobs:
  - name: "Frequent Check"
    minute: "*/2"
    hour: "*"
    command: "quick-check.sh"
  
  - name: "Hourly Report"
    minute: "0"
    hour: "*"
    command: "generate-report.sh"
  
  - name: "Daily Cleanup"
    minute: "0"
    hour: "3"
    command: "cleanup.sh"
```

## Troubleshooting

### Common Issues

**Jobs not executing:**
- Check config.yml syntax with `go test ./...`
- Verify file permissions on commands
- Check logs for parsing errors

**High CPU usage:**
- Normal behavior - SCRON checks time every second for precision
- Consider reducing job frequency if not needed

**Commands failing:**
- Commands run via `bash -c`, ensure bash compatibility
- Check command paths and permissions
- Review captured output in logs

### Debug Mode
Enable debug logging to see detailed execution information:
```bash
ZEROLOG_LEVEL=debug ./scron
```

## Contributing

1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Make your changes following the existing code style
4. Add tests for new functionality
5. Run tests and linting (`go test ./... && go fmt ./... && go vet ./...`)
6. Commit your changes (`git commit -am 'Add amazing feature'`)
7. Push to the branch (`git push origin feature/amazing-feature`)
8. Open a Pull Request

## License

This project is open source. Please check the repository for license details.

---
*Generated with Crush*
