1. Introduction
  2. The monit ruleset
  3. Start monit at system boot
  4. Monit driver script
  5. Building from source
  6. Feedback

1. Introduction

This is an update to a reddit posting I made about monitoring cron and restarting it if it dies.

I've only had cron fail on me once (on Solaris, if anyone cares), but I depend on cron for so many things that I set up monit to keep an eye on it.

After I got it working, I added a few other checks:

2. The monit ruleset

Here are the basic rules I use - plaintext is here:

########################################################################
## Monit control file
##
## Revision: 2.7  Date: 2026-09-22 19:53:34-04 
## Source: /usr/local/src/m/monit/admin/RCS/monitrc,v 
## UUID: 74fc1f9b-3e66-4446-8118-40cb3c9dddbd 
########################################################################
##
## Comments begin with a '#' and extend through the end of the line.
## Keywords are case insensitive.  All paths MUST BE FULLY QUALIFIED,
## starting with '/'.

## Start Monit in the background (run as a daemon):
set daemon 120              # check services at 120-second intervals
    with start delay 30     # optional: delay first check by 30 seconds

## Set logging.
set log /var/log/monitlog

## Set the location of the Monit lock file.
set pidfile /var/run/monit.pid

## Unique id for the Monit instance.
set idfile /var/log/monit.id

## State file which saves monitoring states on each cycle.
set statefile /var/log/monit.state

## Set the list of mail servers for alert delivery.
set mailserver localhost

## Monit will drop alert events if no mail servers are available.
## To retry delivery, use the EVENTQUEUE statement.
set eventqueue
    basedir /var/monit  # base directory where events will be stored
    slots 100           # optionally limit the queue size

## Who gets alerts if/when a service has errors.
set alert you@your.site.com

## Check general system resources.  $HOST is set by monit.
check system $HOST
      if loadavg (1min) > 4             then alert
      if loadavg (5min) > 2             then alert
      if cpu usage > 95% for 10 cycles  then alert
      if memory usage > 75%             then alert
      if swap usage > 25%               then alert

## LOCAL: Make sure cron is running.
check process cron with pidfile /var/run/cron.pid
      group system
      start program = "/usr/sbin/service cron start"
      stop  program = "/usr/sbin/service cron stop"

## LOCAL: Make sure SSH is running.
check process sshd with pidfile /var/run/sshd.pid
      group system
      start program = "/usr/sbin/service sshd start"
      stop  program = "/usr/sbin/service sshd stop"

## LOCAL: Make sure NTP is running.
check process ntpd with pidfile /var/db/ntp/ntpd.pid
      group system
      start program = "/usr/sbin/service ntpd start"
      stop  program = "/usr/sbin/service ntpd stop"
      if failed host 127.0.0.1 port 123 type udp then alert

## LOCAL: Make sure syslogd is running.
check process syslogd with pidfile /var/run/syslog.pid
      group system
      start program = "/usr/sbin/service syslogd start"
      stop  program = "/usr/sbin/service syslogd stop"

## HTTP interface to view status.
set httpd port 80 and
    use address localhost  # only accept connection from localhost
    allow localhost        # allow localhost to connect to the server

## LOCAL: Check Apache binary: checksum, permissions, uid and gid.
check file apache_bin with path /usr/local/apache2/bin/httpd
      if failed checksum and expect the sum 6036a2...bf7e3
                                 then unmonitor
      if failed permission 755   then unmonitor
      if failed uid "root"       then unmonitor
      if failed gid "wheel"      then unmonitor
      alert security@your.site.com on {
             checksum, permission, uid, gid
          } with the mail-format { subject: Alarm! }
      group server

## LOCAL: Check that Apache is running and responsive.
check process apache with pidfile /usr/local/apache2/logs/httpd.pid
      start program = "/usr/local/bin/web.server start"
          with timeout 10 seconds
      stop program  = "/usr/local/bin/web.server stop"
      if cpu > 60% for 2 cycles               then alert
      if cpu > 80% for 5 cycles               then restart
      if totalmem > 200.0 MB for 5 cycles     then restart
      if children > 250                       then restart
      if disk read > 500 kb/s for 10 cycles   then alert
      if disk write > 500 kb/s for 10 cycles  then alert
      if failed port 80 protocol http         then restart
      if 3 restarts within 5 cycles           then unmonitor
      group system

## EOF

Season to taste and copy them to /usr/local/etc/monitrc, or wherever you've configured them to live.

To do a syntax test:

root# chown root:wheel /usr/local/etc/monitrc
root# chmod 600        /usr/local/etc/monitrc

root# monit -t
 New Monit id: 3658d...64bab30
 Stored in '/var/log/monit.id'
Control file syntax OK

me% head /var/log/monit.id /var/log/monitlog
==> /var/log/monit.id <==
3658d5ac25a00ca5aabb9a78464bab30

==> /var/log/monitlog <==
[EDT Aug 30 03:57:01] info     :  New Monit id:
 3658d...64bab30
 Stored in '/var/log/monit.id'

3. Start monit at system boot

I use rc.local:

...

# Monit server -- depends on webserver already running.
svr='/usr/local/bin/monit.server'
if test -x "$svr" ; then
    $svr start
    /usr/bin/logger -t $tag monit.server
fi

# Track reboots.
x=$(uname -rs | tr 'A-Z ' 'a-z-')
/bin/date "+$x %Y-%m-%d %H:%M:%S %z" >> /var/log/reboot

echo '.'
/usr/bin/logger -t $tag rc.local finish

4. Monit driver script

You can easily administer monit via CLI, but I like scripts for my services that allow consistent sub-commands. Copy the driver script somewhere you can find it, like /usr/local/bin.

NAME:
   monit.server

SYNOPSIS:
   monit.server COMMAND

DESCRIPTION:
   Script file to start and stop Monit services.

   COMMAND is one of the following:
      start   -- starts Monit service
      stop    -- stops Monit service
      check   -- run syntax check for Monit control file
      help    -- this message
      id      -- print Monit unique ID
      reload  -- reinitialise running Monit daemon
      restart -- stops and restarts Monit
      status  -- displays status of Monit service
      summary -- displays service states

HISTORY:
   Based on "Life with qmail" script and
   https://sosheskaz.github.io/tutorial/2017/03/28/FreeBSD-rcd-Setup.html

Sample summary output:

root# monit.server summary
Monit 5.25.3 uptime: 22d 15h 19m
 Service Name                     Status                      Type
 hairball                         OK                          System
 cron                             OK                          Process
 sshd                             OK                          Process
 ntpd                             OK                          Process
 syslogd                          OK                          Process
 apache                           OK                          Process
 apache_bin                       OK                          File
up:             7 (100.0%)
down:           0 (0.0%)
initialising:   0 (0.0%)
unmonitored:    0 (0.0%)
total:          7 services

The full monit.server script can be found here.

5. Building from source

5.1. Download

I got the source for the version that works for my FreeBSD installation:

curl https://mmonit.com/monit/dist/monit-5.25.3.tar.gz
curl https://mmonit.com/monit/dist/monit-5.25.3.tar.gz.sha256

Unfortunately there's no GPG signature.

5.2. Build

Change to the source directory and do:

export CC=cc
export CFLAGS=-O2
export CPPFLAGS=-I/usr/local/include
export CXX=c++
export LDFLAGS=-L/usr/local/lib

dest=/usr/local

./configure             \
    --prefix=$dest      \
    --mandir=$dest/man  \
    --with-zlib         \
    --with-piddir=/var/run

make

My results:

Monit Build Information:

            Architecture: FREEBSD
   SSL include directory: /usr/include
   SSL library directory: /usr/lib
          Compiler flags: -Wno-address -Wno-pointer-sign -O2 -Wall -Wunused
                          -Wno-unused-label -funsigned-char -D_GNU_SOURCE
                          -std=c99 -D _REENTRANT -I/usr/include -I/usr/include
            Linker flags: -lpam -lz -lkvm -ldevstat -lpthread -lcrypt
                          -L/usr/lib -lssl -lcrypto -L/usr/lib
       pid file location: /var/run
       Install directory: /usr/local

I ran make with no surprises.

5.3. Install and give it a whirl

Copy everything into place; make install should do this. If you rotate the files in /var/log, you may have to mess with your syslog/rsyslog setup:

root# /usr/local/bin/install monit /usr/local/bin
root# /usr/local/bin/install -c 744 monit.server /usr/local/bin
root# /usr/local/bin/install -m 644 monit.1 /usr/local/man/man1
root# cp /dev/null /var/log/monitlog

Copy your desired rules to /usr/local/etc/monitrc and set the permissions:

root# chown root:wheel /usr/local/etc/monitrc
root# chmod 600        /usr/local/etc/monitrc

Check your configuration and see if she starts:

root# monit -t
root# monit.server start
root# monit.server summary
root# monit.server status

Now kill cron or syslogd and watch it restart as if by magic.

6. Feedback

Feel free to send comments.

Generated from article.t2t by txt2tags
$Revision: 1.7 $
$Date: 2026-10-23 19:19:54-04 $
$UUID: e4e05820-8645-38ee-b2c0-f55fd3aa0325 $