Hello 👋 I'm Dan.

I write PHP, Go, and JavaScript. I also care about web performance.

Folder Size Monitoring with Nagios and RRDtool

The RRDtool graph in GroundWork.

The RRDtool graph in GroundWork.

Recently at my place of employment we’ve had a few customers have their log folders explode in size and crash their servers. Since we already monitor OS X Servers using GroundWork, I decided to write my own folder size Nagios plugin checks folder sizes that alerts if they get too large, and returns performance data for use with RRDtool.

Bash Hokery

The Bash script called check_folder_size.sh (which can be obtained at the GitHub repo) should be uploaded to any folder on the OS X Server you want to monitor.

To test the script, cd into the directory where the Bash script is, then you can test it doing ./check_folder_size.sh -f /Library/Logs -w 1024 -c 2048.

Your required flags for the Bash script are:

  • f — the path for the folder you want to get the size for (wrap the path in “ double quotes if there’s a space)
  • w — the warning level (in MB).
  • c — the critical level (in MB).

And the one optional flag, which shouldn’t be used for this particular Nagios plugin, is:

  • m — block size for the folder (e.g. k for KB, m for MB and g for GB)

For your service check command line, enter something like this: check_by_ssh_folder_size!/Library/Logs/!m!1024!2048. See below:

  • check_by_ssh_folder_size — this is my command in Nagios for the check.
  • !/Library/Logs — the folder path for sizing up.
  • !m — we want return data in MB.
  • !1024 — the warning level in MB.
  • !2048 — the critical level in MB.

RRDtool Doo-Hickey

Below is the RRDtool create command (this is used in GroundWork, but may be used for other platforms)

$RRDTOOL$ create $RRDNAME$ --step 300 --start n-1yr $LISTSTART$ DS:$LABEL#$:GAUGE:95040:U:U DS:$LABEL#$_wn:GAUGE:95040:U:U DS:$LABEL#$_cr:GAUGE:95040:U:U $LISTEND$ RRA:AVERAGE:0.5:1:8640 RRA:AVERAGE:0.5:12:9480

And below is the RRDtool update command for each check that is performed. Here we update the RRD file with the last check time, the folder size in MB, the warning level and critical level.


Finally, we have the RRDtool graph command that generates a nice, custom graph for visual output of performance data.

rrdtool graph - \
--slope-mode \
--height 180 \
--grid-dash 1:2 \
--title="Folder Size" \
--base 1024 \
--units-exponent 0 \
--vertical-label "Size (in MB)" \
--imgformat=PNG \
DEF:a=rrd_source:ds_source_0:AVERAGE \
DEF:w=rrd_source:ds_source_1:AVERAGE \
DEF:c=rrd_source:ds_source_2:AVERAGE \
CDEF:cdefa=a \
CDEF:cdefw=w \
CDEF:cdefc=c \
AREA:a#54EC48:"Space Used" \
LINE:cdefa#24BC14: \
GPRINT:a:LAST:"Current\: %.0lf MB" \
GPRINT:a:AVERAGE:"Average\: %.0lf MB" \
GPRINT:a:MAX:"Maximum\: %.0lf MB\n" \
LINE2:cdefw#ECD748:"Warning Threshold\:" \
GPRINT:cdefw:LAST:"%.0lf MB" \
LINE2:cdefc#EA644A:"Critical Threshold\:" \
GPRINT:cdefc:LAST:"%.0lf MB\n" \
CDEF:cdefws=a,cdefw,GT,a,0,IF \
AREA:cdefws#ECD748 \
CDEF:cdefcs=a,cdefc,GT,a,0,IF \
AREA:cdefcs#EA644A \
-c GRID#C0C0C0 \
-c MGRID#404040 \

Explanation of the RRDtool graph

  • rrdtool graph - this will tell rrdtool that we’re making a graph, and the output will go to stdout (needed for GroundWork, otherwise you can put something like folder_size.png).
  • --slope-mode - this gives the graph a nice organic look, rather than the default step-like lines.
  • --height 180 - make the graph 180 pixels in height.
  • --grid-dash 1:2 - this will make the grid lines slightly dashed (1:3 ratio will make a dotted line).
  • --title "Folder Size" - gives the graph a nice large title.
  • --base 1024 - as we are graphing storage, we want the numbers in base 2.
  • --units-exponent 0 - this will prevent automatic y-axis scaling (it messes up my graph).
  • --vertical-label "Size (in MB)" - puts a label on the left-hand side of the graph (text is printed vertically).
  • --imgformat=PNG - format the output image as a PNG.
  • DEF:a=rrd_source:ds_source_0:AVERAGE - set a variable a with the value of the folder size in MB.
  • DEF:w=rrd_source:ds_source_1:AVERAGE - set a variable w (warning) with the warning level value.
  • DEF:c=rrd_source:ds_source_2:AVERAGE - set a variable c (critical) with the critical level value.
  • CDEF:cdefa/w/c=a/w/c - define more variables for later calculations.
  • AREA:a#54EC48:"Space Used" - define an area on the graph with the variable (a), and the colour (#54EC48) (colour is made with rgb components) and a legend “Space Used”.
  • LINE:cdefa#24BC14: - graph a line at the top of the main area.
  • GPRINT:a:LAST:"Current\: %.0lf MB" - print the text “Current: XXX MB” to the graph (on the same line as the text “Space Used”) which has the most recent rrd entry.
  • GPRINT:a:AVERAGE:"Average\: %.0lf MB" - print the text “Average: XXX MB” to the graph (on the same lines as the other text so far), which displays the average in MB.
  • GPRINT:a:MAX:"Maximum\: %.0lf MB\n" - print the text “Maximum: XXX MB” to the graph, along with a newline character at the end.
  • LINE2:cdefw#ECD748:"Warning Threshold\:" - draw a warning level line on the graph, with the rgb colour.
  • GPRINT:cdefc:LAST:"%.0lf MB" - print the warning level in MB.
  • LINE2:cdefc#EA644A:"Critical Threshold\:" - draw the critical level line on the graph.
  • GPRINT:cdefc:LAST:"%.0lf MB\n" - print the critical level in MB, along with a newline character.
  • CDEF:cdefws=a,cdefw,GT,a,0,IF - using a calculated define, we can work out if the folder size is larger than the folder size, and if it is, we’ll change the graph colour on the next line.
  • AREA:cdefws#ECD748 - using the calculation above, change the colour of the graph.
  • CDEF:cdefcs=a,cdefc,GT,a,0,IF - like above, do another calculation to see if the folder size is larger than the critical level.
  • AREA:cdefc#EA644A - as above, colour the graph to the appropriate colour if it reaches or goes over the critical threshold.
  • -c BACK#FFFFFF - change the background colour of the graph to white (#FFFFFF).
  • -c CANVAS#FFFFFF - change the colour of the graph canvas to white.
  • -c GRID#C0C0C0 - change the grid colour to a light-ish grey.
  • -c ARROW#FFFFFF - change the colour of the graph arrows to white, to hide them all together.
  • -Y - scale the graph to integers dynamically on the graph’s Y axis.

Once you’ve got this all set up, you should be getting wonderful graphs (like the one above), along with performance data.

My Favourite Album: OutRun by Kavinsky

For the past few months I’ve been listening to the album OutRun by Kavinsky. This album is a great driving album, and a wonderful programming mix. As a fan of 80s and 80s inspired music, this album blends the best of modern French house music, with the classic sounds of 80s electro.

Kavinskyโ€™s production style is very visceral and reminiscent of video game music and film soundtracks of the 80s.

- Last.fm Profile Page

The first track, Prelude, introduces the main character, a young male along with a red Ferrari Testarossa. After the introduction track we get the track 2 in the album, Blizzard, a punchy track with awesome synth-guitar riffs. This is easily one of my favourite tracks of all time, and certainly my favourite of the album. The guitar riffs combined with the hard-hitting bass drum kicks help set the tone of the album and Kavinsky’s style. Next, we get Protovision, another punchy track with an epic bass kick and fantastic synth lines. To me, Protovision is very reminiscent of the first Justice album, the stiff micro-sampled sounds make me think of tracks like Newjack, Phantom and DVNO. Fourth on the album is Odd Look, the first proper song of the album with vocals. Like the two preceding tracks, this song follows the trend of strong bass kicks and epic synth chords that are guaranteed to get anyone moving on the dance floor, or the office.

Next up is my second favourite track on the album, Rampage. Combining the mid and high-range synths with the solid bass drum kick, along with a muffled-sounding piano in the background, this is a fun track. I can imagine this track would be really epic when tied with a tough mission in a game like Call of Duty. After Rampage we get the rap track… Suburbia. While I can appreciate rap and hip-hop, I don’t really like the blend of rap and the 80s electro-synth this album is. Having said that, the story in the rap track does follow the theme of the album, talking about the character and his fast “Mars Red” Testarossa. After the rap track we have another punchy synth track, Testarossa Autodrive. I love the powerful synth riffs in this track, combined with the high-pitched synth that kicks in throughout the track, it’s a winner.

Nightcall, the eighth track in the album has great vocals and a sequenced synth. The robotic vocal doing the first part of each verse reminds me of Daft Punk’s robo-voice. I also find the female voice in the chorus to be hauntingly beautiful, combining great lyrics with a fantastic voice, I get chills every time I hear the chorus. Next up is Deadcrusier, a great warpy synth track with great deep synth riffs proving a nice bassey edge to the track. The warpy sounding synth hits home an epic track. Next is Grand Canyon, another of my favourite tracks. The super hard-hitting high-hats and synth lines make this track and epic track to listen to. I could easily listen to this track over and over again, the repetition of the track is catchy as heck!

After Grand Canyon is the track First Blood, an almost Van Halen influenced track with epic guitar lines. With a rock-themed vocalist and synth-guitar sounds this track is a rock epic. I have a feeling the solo was very Eddie Van Halen inspired. Next up is Roadgame which starts off with a great violin loop which changes pitch throughout the loops in the song. Combined with great synths and bass kicks, this is a fantastic track to bring us near the end of the album. Finally is Endless, the last track of the album brings the poignant story to a close with a nice piano loop and soft synths with a slow kick drum beat. The album is over :(

Oh yeah, and there’s a video game.

Please note that this is my first album review, my writing is sure to get better!

Working with OS X Caching Server's Max Cache Size Limits

The Caching Server pane in Server.app

The Caching Server pane in Server.app

Added in a recent version of OS X Server was the ability to provide an advanced software update feature called Caching Server. This enhanced the previous Software Update server features by including content from iTunes (i.e. iOS app updates and iBooks), along with providing an easy way for automatic server update selection (for those who are unfamiliar with Caching Server’s nifty features, check out the PDF on this page).

During setup you are required to select a volume for the cached updates to be stored. Depending on the size of this volume, the maximum size used slider can be rather useless. For example, when configuring my RAID enclosure (which has 8.8TB of useable space), the slider went from 30GB to 580GB in one step! This kind of limited selection is very frustrating. I want more than 30GB of cached updates, but I don’t want 580GB! Unfortunately, the current GUI slider steps in very high increments. Thankfully for us, using serveradmin through the terminal will save us.

If you want to see what limit Caching Server has set via the command line, you can do sudo serveradmin fullstatus caching then check out the line caching:CacheLimit. This number is shown in bytes and will convert nicely to a base 10 unit (otherwise known as SI), rather than the normal base 2.

For example, if you wanted to set a limit of 100GB, you would use the number 100000000000. That’s a lot of zeroes. Alternatively, 250GB would be 250000000000. To work out your storage conversion needs, I’d recommend checking out this converter here and use the Byte SI Decimal Prefix to convert to bytes.

Now that we’ve decided on how much space we’d like to use for Caching Server, lets tell it what we want. Open up a new Terminal window and using the command serveradmin settings caching:CacheLimit we can specify (in bytes) how much space we want to use. In my case, I wanted to use a maximum of 100GB for Caching Server. To do this, I enter the following:

sudo serveradmin settings caching:CacheLimit = 100000000000

After pressing return and running fullstatus on Caching Server (or opening the Caching tab in the Server app), you can now see that a maximum of 100GB will be used. Naturally, entering a different number will yield a different result in Server app (or the Terminal), but you get the picture.

SABnzbd+ for Status Board

Since making the iStat Server for Status Board script I’ve wanted to make more graphs for Status Board. Lo and behold, I use SABnzbd+ and it has an API. A graph is born:

SABnzbd Categories.

SABnzbd Categories.

The above graph collates all the downloads in the queue and counts them up then graphs them out, it’s pretty self explanatory really. Along side those bar graphs is the total of all items in the queue. Also available is a custom “Do-it-yourself” panel with core information about your SABnzbd+ server.

SABnzbd Info.

SABnzbd Info.

This pane is also pretty self explanatory. At the top you’ve got the version number of SABnzbd+, the current speed of your downloads, the status of the server (i.e. paused, downloading etc), and the size (in GBs) of what’s left to download in the queue. At this point in time, the info pane is only suitable for a 4x4 panel.

Jump over to the GitHub page to take a gander at the code and download it. Getting it set up is pretty easy, but if you’re stuck, I can provide limited support on the GitHub page, or via Twitter.

Please take a look and let me know if you find it useful!

iStat Server Graphs for Status Board (Updated)

Ever since Panic’s Status Board for iPad app came out I’ve wanted to have data from iStat Server appear in Status Board.

After finding that iStat Server stores its data in /Library/Application Support/iStat Server/databases/local.db and that the SQLite database and all its data is not encrypted/obfuscated in any way, I figured it wouldn’t be too difficult to get the juicy data into some sexy Status Board graphs.

Using the PDO and SQLite libraries included with Mac OS X 10.8.3 I was able to get a connection to the database and pull out rows. Simply store this file anywhere on your Mac that’s accessible by the built-in web server.

Lo and behold, a graph is born:

iStat Server for Status Board - CPU Graph.

iStat Server for Status Board - CPU Graph.

The project is still in its infancy, with only a few different graphs. I plan on slowly adding more and more graphs and types. As of this post, the following graphs are possible:

  • ram_hour - RAM usage for the past 60 minutes
  • ram_day - RAM usage for the past 24 hours
  • cpu_hour - CPU usage for the past 60 minutes
  • cpu_day - CPU usage for the past 24 hours
  • load_hour - CPU load for the past 60 minutes
  • load_day - CPU load for the past 24 hours
  • temp_hour - Temp sensors for the past 60 minutes *new*

Take a look at the GitHub repo for more details and the download link to get this puppy running. Limited support can be provided on GitHub or on Twitter at @yesdevnull.

Update - 05/06/2013

Todays big update includes temp sensor monitoring so you can get more pretty graphs, like below.

iStat Server for Status Board - Temperature Graph.

iStat Server for Status Board - Temperature Graph.

If you’re checking 1 sensor, make your query string &temps=TC0D, or for multiple sensors, do &temps=TC0D,TC0H. If you have multiple temp sensors, they must be comma delimited. For the most up-to-date list of sensors, check the README in the GitHub repo.

Head over to the GitHub repo (linked above) to check out the new changes and get it set up on your Mac!

Mac NetBoot Bash Scripts

Recently Iโ€™ve been working on some bash scripts for a NetBoot system we have at work for diagnosis and troubleshooting Macs.

Currently the collection only includes a script for the command-line utility memtest, and a simple CPU workhorse yes. Also included is a few bash aliases you can add to your bash profile.

To view the collection, or fork et al,ย visit GitHub now!


Welcome to my new site yes > /dev/null!

Here I’ll be writing about code I’ve written, technical experiences I’ve had, music I work to, and maybe even other things unrelated to computers and programming.

I’m planning on doing a couple posts per month, so check back soon for some nifty content.