This post is an interlude between Gentoo-related posts. The reason is that I have one in drafts that requires me to produce some results that I have not yet, so it’ll have to wait for the weekend or so.
You might remember that my original IPMI plugin was written in POSIX sh and awk, rather than bash and gawk as the original one. Since then, the new plugin (that as it turns out might become part of the 2.1 series but not to replace both the old ones, since RHEL and Fedora don’t package a new enough version of Freeipmi) has been rewritten in Perl, so using neither sh nor awk. Similarly, I’ve written a new plugin for sensors which I also wrote in Perl (although in this case the original one also used it).
So why did I learn a new language (since I never programmed in Perl before six months ago) just to get these plugins running? Well, as I said in the other post, the problem was calling the same command so many times, which is why I wanted to go multigraph — but when dealing with variables, sticking to POSIX sh is a huge headache. One of the common ways to handle this is to save to a temporary directory the output of a command and parse that multiple times, but that’s quite a pain, as it might require I/O to disk, and it also means that you have to execute more and more commands. Doing the processing in Perl means that you can save things in variables, or even just parse it once and split it into multiple objects, to be later used for output, which is what I’ve been doing for parsing FreeIPMI’s output.
But why Perl? Well, Munin itself is written in Perl, so while my usual language of choice is Ruby, the plugins are much more usable if doing it in Perl. Yes, there are some alternative nodes written in C and shell, but in general it’s a safe bet that these plugins will be executed on a system that at least supports Perl — the only system I can think of that wouldn’t be able to do so would be OpenWRT, but that’s a whole different story.
There are a number of plugins written in Python and Ruby, some in the official package, but most in the contrib repository and they could use some rewriting. Especially those that use net-snmp
or other SNMP libraries, instead of Munin’s Net::SNMP wrapper.
But while the language is of slight concern, some of the plugins could use some rewriting simply to improve their behaviour. As I’ve said, using multigraphs it’s possible to reduce the number of times that the plugin is executed, and thus the number of calls to the backend, whatever that is (a program, or access to /sys
), so in many cases plugins that support multiple “modes” or targets through wildcarding can be improved by making them a single plugin. In some cases, it’s even possible to reduce multiple plugins into one, as I did to the various apache_*
plugins shipping with Munin itself, replaced on my system with apache_status
as provided by the contrib repository, that fetches the server status page only once and then parses it to produce the three graphs that were, before that, created by three different plugins with three different fetches.
Another important trick up our sleeves while working on Munin plugins is dirty config which basically means that (under indication from the node itself), you can make the plugin output the values as well as the configuration itself during the config execution — this saves you one full trip to the node (to fetch the data), and usually that also means it saves you from having to send one more call to the backend. In particular with these changes my IPMI plugin went from requiring six calls to ipmi-sensors
per update, for the three graphs, to just one. And since it’s either IPMI on the local bus (which might require some time to access) or over LAN (which takes more time), the difference is definitely visible both in timing, and in traffic — in particular one of the servers at my day job is monitoring another seven servers (which can’t be monitored through the plugin locally), which means that we went from 42 to 7 calls per update cycle.
So if you use Munin, and either have had timeout issues in the past or recently, or you have some time at hand to improve some plugins, you might want to follow what I’ve been doing, and start improving or re-writing plugins to support multigraph or dirtyconfig, and thus improve its performance.
It must have felt odd for you learning Perl in this day and age. With Ruby and C also being my primary languages, it certainly felt odd for me when I had to learn Perl for work recently. Here though, it’s for maintaining and rewriting legacy code. I was a little surprised to learn the other day that Munin is written in Perl while Nagios (which is older?) is written in PHP. If anything, I thought it was the other way round.
Learning bash and gawk would allow to acheive the same with less pain. It might not that portable to some iceage systems like HP-US or AIX, but who cares of them anyway.
Uhm, telling me to learn bash and gawk is a bit … shortsighted. Beside, there are plenty of systems that don’t run, or don’t want to run bash because of its slowness — in many cases it’s easily slower than Perl itself. Why limiting oneself, or writing encrypted shell script, when you still need Perl to run the node?James, well, mostly the problem for me was trying to find the correct resources — I should probably write something about it directly, but it seems like the last few years of Perl development started adding/removing features and that makes lots of the documentation pages out there obsolete. And of course it’s late in my career that I look into something that for most people is their starting point …
For small/minor applications, I often base my decision about what package to use based on whether or not it has Perl plugin support.Case in point is urxvt. 1-2 years ago there was an X.org-related bug that caused the cursor to stop blinking when typing and completely disappear when backspacing. That gave me some serious headaches and I tried out a bunch of other terminal emulators. I switched back to urxvt once the bug was fixed because I missed the features provided by Perl plugins such as clickable URLs and regex searches.@James Le CuirotPerl is well-suited to this sort of job.Perl was the first language I learned to program in and after years of using it I’ve come to associate it with system administration. The way that regular expressions are built into the language and the ease with which you can fork a process in a couple lines of code makes it a perfect tool for parsing logs and command line output. When I first started using Gentoo I came up with this one liner to search installed packages in each category:perl -e ‘for(@_=map{y/n *//d;$_}`emerge -s %@$ARGV[0]`){$i++;print”$_[$i-3]n”if/ed:d/}’Very succinct. Of course now I know about the eix tool. An even faster method (although it mixes up the gentoo tree with overlay packages) is to list the contents of /var/db/pkg/${category}. But back then this one line program was a life-saver.