Over the past few days I've been doing tons of DevOps work. Lots of setting up server monitoring, security, and automation. Most recently I wanted to give monit a try, as I've heard some good things about it. I was able to install it and get it up and running pretty hassle free. I added in a few process checks for nginx, php-fpm, and postgres and it instantly was able to start tracking those processes for me.
If you've gone through some of my other posts, you might remember a guide that I wrote about settings up BitTorrent Sync on a remote server, well today I'm going to expand on that a bit and add BitTorrent sync into my monit checks!
There were multiple apparent walls that I was going to run into, as BitTorrent sync wasn't exactly written to be placed on a web server, so it lacks a few things like PID logging and the ability to start/stop the service. In order to overcome this, I figured the wisest approach would be to write a wrapper for the btsync program that would enable stop/start.
If you're unsure what a PID is and why it's important, read on; otherwise, skip the next section and get into the meat of this tutorial.
What is a PID?
A PID is a process id. Have you ever run
ps aux on your system? If so, you've probably seen a list with rows like this
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 4038 8.9 4.8 144436 49100 ? Ssl 15:22 0:17 /BTSync/btsync --config /BTSync/sync.conf
The number that is in the PID column is obviously the PID. These are unique identifiers for a single process. This unique PID can be used to kill or restart a process. I find that a lot of linux newbies often end up calling
killall btsync if they wish to kill the process called
btsync, but this isn't the proper way to do it, as there could be multiple instances of the btsync process. You should only use
killall if you with to kill multiple processes at once. Like
killall nginx to stop nginx and all child nodes.
Killing based on PID is much more precise. If we wish to kill the above BitTorrent sync process, we would just use
kill -KILL 4038. The problem here is that the PID is unique, so upon starting back up it would have changed.
The way around this, is most programs log the PID inside a file. Typically the PID file would be something like
/var/run/nginx.pid and it would contain nothing but the PID.
You'd then be able to use the contents of that file to kill or restart your process. Something alone the lines of
kill -HUP $(cat /var/run/nginx.pid) could be used to restart the nginx process.
As I said above, by default BitTorrent sync doesn't log the PID in a file, so it's up to me to fix that.
I opened up a new file with vim (my personal favorite CLI text editor)
$ vim /usr/local/bin/btsync
Then I wrote the following script in it
#!/bin/bash if [[ $1 = "start" ]]; then /BTSync/btsync --config /BTSync/sync.conf 2>/dev/null & PID=$! PID=$(($PID+1)) echo $PID > /var/run/btsync.pid elif [[ $1 = "stop" ]]; then kill -KILL $(cat /var/run/btsync.pid) elif [[ $1 = "restart" ]]; then kill -HUP $(cat /var/run/btsync.pid) else echo "Invalid option. Use either start, stop, or restart." fi
If the script feels a little hack-y, that's because it is. For some reason upon starting btsync and retrieving the PID, it was always 1 behind the actual PID. So if it started with a PID of 420 it would end up logging 419 to the
/var/run/btsync.pid file. Strange, but I have other things I need to get done today, so doing a little bash-fu I was able to log the correct PID to the btsync.pid file. If it wasn't already obvious, you're also going to have to replace
/BTSync/btsync with the actual location of the binary. If you followed my previous guide for setting it up, then you can leave it as
The next step is making the wrapper an executable. This is easily done by running
chmod +x /usr/local/bin/btsync. Great.
So now we get to add in our check to the monitrc file. It's been more than easy to add in checks so far, so I expected nothing less when adding in another check for btsync.
$ vim /etc/monit/monitrc
I then added in the check like so
check process btsync with PIDfile /var/run/btsync.pid group utilities start program = "/usr/local/bin/btsync start" stop program = "/usr/local/bin/btsync stop" restart program = "/usr/local/bin/btsync restart"
After that, I ran a
monit reload and it started monitoring btsync immediately! I was also able to click into the process and use monit's GUI to stop/start/restart the process.