This page describes how to write a simple Perl plugin for collectd
It fetches the numbers from a HTML page.
I needed this when I wanted to graph the line quality information from my
Speedport 200 DSL Modem, but was fed up with my
home-grown RRD graphing solution. The graphs (at least some of them) look
as pretty as they can be, generating and drawing use the same config – but the configuration,
almost pure RRD, is a pain. So I looked at collectd, which I wanted to do for a long time anyway.
The example plugin
If you just want a quick example without reading all this stuff, have a look at tecom.pm
The Modem identifies itself as "Tiny Bridge DSL Modem" and is manufactured by
It only has one page, the status page. Login and pass are “admin”. Neither passord nor IP
can be changed.
The plugin is named “tecom”. It loads the status page and extracts
SN-ratio, attenuation and rate
by using a simple regexp. In the HTML the numbers are found in the two lines below the title of the searched value.
How it works
The explanation below looks more complicated than it really is. So here's the end result first.
- An own types.db defines two RRD databases
# the default must be explicitly defined again if an additional TypesDB is present
# not needed, but the default is 10 seconds, and that seems a bit excessive to me
# Changing the interval per perl plugin is not possible AFAICT
# Interval 30
- And finally: /path/to/plugin/dir/Collectd/Plugins/tecom.pm
- To actually see something, collection3 can be used. collection.conf:
RRDTitle "Tecom DSL-Modem - line quality"
DataSources snr_down snr_up att_down att_up
Order att_down att_up
DSName att_down attenuation download \t
DSName att_up attenuation upload \t
DSName snr_down Signal-to-noise download\t
DSName snr_up Signal-to-noise upload \t
Color snr_down 00C77A
Color snr_up 008DC7
Color att_down 94D943
Color att_up 0012C7
RRDTitle "Tecom DSL-Modem - rates"
DataSources rate_down rate_up
Order rate_down rate_up
DSName rate_down Rate download\t
DSName rate_up Rate upload \t
Color rate_down 22902A
Color rate_up 0098C7
And this is how it looks like.
The gritty details
- The Perl plugin must be enabled in /etc/collectd.conf
- A type must be specified in one of the files defined in TypesDB.
- Alternatively an existing type
from /usr/share/collectd/types.db (at least that's what my default was) can be
used. A good candidate is gauge. But gauge can only hold one value per RRD, so
that's only good for testing in most cases.
- There can be more than one TypesDB
- A TypesDB directive overwrites the default. So the default directory must
explicitly be added back if you want to have an additional types database.
- The format of the TypesDB file is
name rrd_name:RRD_TYPE:min:max [,rrd_name:RRD_TYPE:min:max]
defines a database that holds two GAUGE values named “rate_down” and
“rate_up”. The allowed values for both are minimum 0, maximum unlimited.
- In previous versions it was possible to register the type directly from the plugin
via plugin_register(TYPE_DATASET, $plugin_name, $dataset_aref). I really
don't understand why this was axed. Isn't it a good thing that every plugin can
automatically define suitable databases? Nevertheless, it's deprecated now.
- The plugin is a .pm that gets used or required by collectd.
- IncludeDir must be set to a directory where the plugins should be searched. The
value will be added to @INC
This is not the final path, however: the plugin needs to be a
therefore the file must be saved in Collectd/Plugins/ within IncludeDir.
- The plugin must use Collectd qw( :all ); to be able to use the exported functions,
variables and constants.
- The plugin must register a callback function for "read" with
plugin_register(TYPE_READ, $plugin_name, "callback_function").
The registered function will be called once in every Interval (the global Option in
/etc/collectd.conf. It seems the Interval Option does not work within <Plugin perl>,
and I couldn't get it work within the Plugin configuration section).
- The callback function in turn has to call plugin_dispatch_values() to give the data
The only parameter is a hash reference, called the value list by the man page. It can contain
the following keys
||The name of the plugin. This will determine the subdirectory
where the RRD graphs will be saved.
||The UNIX time under which the data should be saved in the
||No (default is now)
||A name of a RRD description, defined in a TypesDB
||An array reference containing the values to be inserted. The order
is defined by the type.
||No clue. Setting this value doesn't change how often the read
function will be called.
||Can be set to a specific host, which in turn defines the
subdirectory where the RRD file will be saved.
||No. The default host (also accessible via $hostname_g) will
be used if this value is not set.
||Every plugin instance generates its own directory
||Every type instance generates its own RRD file
- Another useful callback functionality is the init callback function, which is called
directly after loading the plugin. It is set with
plugin_register(TYPE_READ, $plugin_name, "tecom_read");
collectd -t can be used to test the configuration and the syntax of the plugin.
It doesn't catch runtime errors, in which case collectd silently dies.
- The daemon doesn't start without further explanation if the plugin dies of runtime error.
Compile-time errors are shown in the logs.
- If the interval is changed for a database, the database must be deleted (so that it is
automatically re-created) to get databases with a new heartbeat value. For example, after
changing Interval from the default of 10 seconds to 60 seconds, all updates were
invalid, because there were too many datapoints missing.
- Perl plugins don't work in OpenSuSE 12.1. The message is
perl: init_pi: Unable to
bootstrap Collectd: Can't load
'/usr/lib/perl5/5.14.2/x86_64-linux-thread-multi/auto/threads/threads.so' for module
undefined symbol: PL_thr_key at /usr/lib/perl5/5.14.2/XSLoader.pm line 71.
at /usr/lib/perl5/5.14.2/x86_64-linux-thread-multi/threads.pm line 32
Compilation failed in require at /usr/lib/perl5/vendor_perl/5.14.2/Collectd.pm line
is to start collectd with
- collectdCollectd::Plugins::PluginName does not define
$Collectd::Plugins::PluginName::VERSION--version check failed.
BEGIN failed--compilation aborted..
This was only a problem on OpenSuSE, it didn't happen on Gentoo. After adding
$Collectd::Plugins::PluginName::VERSION = 1; to the plugin it began to work. But I doubt this
is the correct solution (at least I don't know what I did with this variable definition).
collection3 from the contrib-directory of the distribution is a quick way to see the graphs. In fact,
it's a very nice solution to have a quick look at any RRD file! Except for the destination directory
there's no configuration neccessary to do this.
The time span can be changed with the scroll wheel, and there's a button to apply the timespan to all
the rest of the graphs for better comparison.
Just throw it in a directory where .htaccess is allowed. The CGI-directory does not
work, because ExecCGI can't be disabled by .htaccess. collection3 needs this to access its CSS-, js- and
config-files. The DataDir in etc/collection.conf must be set to the directory which
contains the hostname-directories.