Developing Qnotifier plugins

Qnotifier is a combination of a daemon that runs on your Unix system (Linux or OSX), and an iPhone/iPad app to provide a dashboard-like view of data collected from your system. It can report text-based information, time-based graphs, or alerts which can be delivered to you in a variety of ways—for example, when your CPU usage gets too high. Qnotifier is free right now while in beta, but no word yet on whether it will switch to a paid model in the future.

One of the things I like about Qnotifier is that the daemon is a Ruby gem, and supports user-developed plug-ins to collect and report new kinds of information. I just finished setting up a Squid cache to sit in front of a Rails site to improve performance, and decided to see what it would take to add Squid statistics to my Qnotifier dashboard. It turns out, getting the Squid statistics was the hard part—delivering them to Qnotifier was easy!

Getting Squid statistics

I couldn’t find much information on how to retrieve statistics. Every web page said to install and use the Squid cachemgr.cgi tool to get a GUI into viewing stats. This wasn’t what I wanted, but it got me there eventually. The CGI is compiled C code, and quick look through the source gave some hints. Using tcpdump to observe it in action gave away the answer: send the following request to the running Squid server, and get back a ton of information:
GET cache_object://localhost/info HTTP/1.0

Writing the Qnotifier plugin

Qnotifier was just released a week ago, fairly stealthily, and thus there’s no documentation at all yet. Even looking through the plugins shipped with the package, half of them are non-functional yet (apache, iostat, etc.).

Fortunately, it was pretty easy to figure out the general plugin architecture from reading the working plugins (Ruby, system, Passenger, etc.):

  • Create a new plugin file in /var/lib/qnotifier/plugins
  • Create a new Class, and inherit from Qnotifier::Plugin
  • Collect your metrics in whatever way is appropriate.
  • Call stat(key, message) to deliver text-based metrics to the “Stats” dashboard in the app.
  • Call report(key, val) to deliver one time-series data point for a graph in the “Charts” dashboard.
  • Call alert(key, message) to send a real-time alert, and reset_alert(key, message) to clear one.

Here’s the short Ruby plugin I wrote to retrieve the Squid statistics (using netcat) and push them to Qnotifier. This is an hour’s proof-of-concept work, and just gathers a couple metrics without error checking. If Qnotifier comes out of beta and is free (or cheap), I’ll clean it up some more since I see a lot of potential here.

module Qnotifier
class Squid < Qnotifier::Plugin def initialize @defaults = { } end def main status = `echo "GET cache_object://localhost/info HTTP/1.0\n" | nc -q 2 localhost 3128` if status data = # Convert all the key: value lines into a Hash status.split("\n").each do |line| s = line.split(':', 2) data[s[0].strip] = s[1].strip if s.length == 2 end # How much space is used in the disk cache # Looks like "7126 KB" d = data['Storage Swap size'].split(" ") disk_space_used = d[0].to_i / 1024 if d[1] == 'KB' disk_space_used = d[0].to_i if d[1] == 'MB' # What's the 5-minute request cache hit rate # Looks like "5min: 93.5%, 60min: 97.4%" req_hit_rate = data['Request Hit Ratios'].match(/5min: ([^%]+)/)[1] # Send data to the service report("Disk cache used (MB)", disk_space_used) report("Request cache hit ratio %", req_hit_rate) stat("R hit rate", data['Request Hit Ratios']) stat("B hit rate", data['Byte Hit Ratios']) else Qnotifier.log.error "Can't access squid status" end end end end

Comments are closed.