Monitoring processes with mon
[mon](https://github.com/visionmedia/mon) is an extremely small, simple, and light-weight alternative to [monit](http://mmonit.com/monit/) for monitoring processes. Monit's approach of using a [DSL](http://en.wikipedia.org/wiki/Domain-specific_language) is at times inflexible and often annoying. Mon's approach is to monitor only a _single_ process, monitoring of several require a mon instance per process, however reducing single points of failure. This may sound like it's a lot of work to manage, but I promise you it's not! There's another tool for this called `mongroup(1)` to tie them together. ## Monitoring a single process Mon instances weigh in at about 400kb per process, so you don't have to worry about spawning a bunch of them. The simplest use of mon accepts a command to execute, and keep alive: $ mon "echo hello; sleep 5" Mon will execute the command with `/bin/sh -c`, so brace expansion and other shell goodies are completely fine. Once the sub process exits, mon will bring it back to life. By default mon logs to stdout: mon : child 94136 mon : sh -c "echo hey; sleep 5" hey mon : last restart less than one second ago mon : 10 attempts remaining mon : child 94138 mon : sh -c "echo hey; sleep 5" hey mon : last restart 5 seconds ago mon : 9 attempts remaining mon : child 94140 mon : sh -c "echo hey; sleep 5" hey Mon will continue to execute the command until mon itself is signalled with __SIGQUIT__ or __SIGTERM__ at which point it will signal the child using the same signal, and gracefully exit. When a process continues to fail upon restart, cyclic spawning will be detected by mon, it will then exit and log a warning. By default `10` restart attempts within 60 seconds are allowed, however you may tweak this value with `--attempts `. ## Failure alerts Mon provides two facilities for notification. The first is the `--on-restart ` flag, which mon will invoke upon _any_ restart. This is useful for emailing administrators the tail of a log file, notifying your team via IRC, etcetera. The second, and more crucial facility is the `--on-error ` flag, which is invoked only when a cyclic restart is detected, and mon has bailed out. Administrators should be notified immediately as the process is completely down. ## Daemonization Mon's `--daemonize` flag may be used to background the process and disassociate with the terminal, at this point stdio will be redirected to the log file specified by `--log`, otherwise defaulting as "./mon.log", typically this looks something like: $ mon -d -l /var/log/app.log "node app.js" ## Monitoring multiple processes with mongroup Using mon with several flags is obviously not something you'd want to be typing all the time, but part of the benefit of using mon is that shell scripts become your DSL. If you're not interested in doing this yourself but have several processes to manage I recommend checking out a project by [jgallen23](https://github.com/jgallen23) called [mongroup(1)](https://github.com/jgallen23/mongroup). I've forked the project to add some goodies, until merged you can find them [here](https://github.com/visionmedia/mongroup). Mongroup uses a simple configuration file, defaulting to the name `./mongroup.conf`, which simply lists out the `pids` and `files` directories, as well as one or more processes to spawn: pids = /var/run logs = /var/log web1 = node server 3000 web2 = node server 3001 web3 = node server 3002 web4 = node server 3003 redis = redis-server Mongroup ships with typical init-style commands `start`, `stop`, `restart`, `status` and so on, without a lot of the boilerplate associated with writing init scripts. ### Launching processes To check the status of your monitoring group, simply invoke `mongroup status`, or `mongroup`, as it's the default sub-command. You'll see a list of process names, pids, and the status itself:  Firing up the entire suite of processes takes only a single command, `mongroup start`:  Checking the status again will show the process uptime:  You may also start, stop, or restart single processes at a time via: $ mongroup stop [name] $ mongroup start [name] $ mongroup restart [name]  Since mongroup is working-directory sensitive unless the `--config ` flag is specified, I recommend adding a small snippet to your shell profile similar to the following: procs() { (cd ~ && mongroup $@) } If you're super paranoid you can monitor mon with mon: $ mon "mon 'node app'" That's all for now! __EDIT__: changes to mongroup(1) have been merged! https://github.com/jgallen23/mongroup










