summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: d51a376)
raw | patch | inline | side by side (parent: d51a376)
author | Peter Holik <peter@holik.at> | |
Tue, 27 Feb 2007 08:51:59 +0000 (09:51 +0100) | ||
committer | Florian Forster <octo@leeloo.lan.home.verplant.org> | |
Tue, 27 Feb 2007 08:51:59 +0000 (09:51 +0100) |
-- 8< --
Hi!
This plugin collects interrupts from /proc/interrupts
Usually all interrupts are collected but
you can configure what interruptnumbers are collected or not.
Example:
collect only wanted irqs:
<Plugin irq>
Irq 0
Irq 14
IgnoreSelected false
</Plugin>
collect all but no these irqs:
<Plugin irq>
Irq 7
Irq 8
Irq 9
IgnoreSelected true
</Plugin>
cu Peter
-- >8 --
Hi!
This plugin collects interrupts from /proc/interrupts
Usually all interrupts are collected but
you can configure what interruptnumbers are collected or not.
Example:
collect only wanted irqs:
<Plugin irq>
Irq 0
Irq 14
IgnoreSelected false
</Plugin>
collect all but no these irqs:
<Plugin irq>
Irq 7
Irq 8
Irq 9
IgnoreSelected true
</Plugin>
cu Peter
-- >8 --
AUTHORS | patch | blob | history | |
collectd.spec | patch | blob | history | |
configure.in | patch | blob | history | |
contrib/collection.cgi | patch | blob | history | |
src/Makefile.am | patch | blob | history | |
src/collectd.conf.in | patch | blob | history | |
src/collectd.conf.pod | patch | blob | history | |
src/collectd.pod | patch | blob | history | |
src/irq.c | [new file with mode: 0644] | patch | blob |
index b12387799f9a41782a7548c995f9c4dcab1374c0..b10958b1106fac9e2afbd33f306a4cf112b79df1 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
apcups plugin by:
Anthony Gialluca <tonyabg at charter.net>
-cpufreq and multimeter module by:
+cpufreq, multimeter and irq module by:
Peter Holik <peter at holik.at>
hddtemp module by:
diff --git a/collectd.spec b/collectd.spec
index 6116ffd667624107075b53e504d40124967a896f..b69d27a6c211b7912ffbffb4ab475cb0d7184516 100644 (file)
--- a/collectd.spec
+++ b/collectd.spec
%attr(0444,root,root) %{_libdir}/%{name}/dns.so
%attr(0444,root,root) %{_libdir}/%{name}/email.so
%attr(0444,root,root) %{_libdir}/%{name}/hddtemp.so*
+%attr(0444,root,root) %{_libdir}/%{name}/irq.so*
%attr(0444,root,root) %{_libdir}/%{name}/load.so*
%attr(0444,root,root) %{_libdir}/%{name}/mbmon.so
%attr(0444,root,root) %{_libdir}/%{name}/memory.so*
diff --git a/configure.in b/configure.in
index 602d0faa2db85fa242a138dff5dcbfac2a8ca65e..bebacd56eb50f8d5a09f94e18680e17f3ce3a13f 100644 (file)
--- a/configure.in
+++ b/configure.in
AC_COLLECTD([email], [disable], [module], [email statistics])
AC_COLLECTD([quota], [enable], [module], [quota statistics (experimental)])
AC_COLLECTD([hddtemp], [disable], [module], [hdd temperature statistics])
+AC_COLLECTD([irq], [disable], [module], [irq statistics])
AC_COLLECTD([load], [disable], [module], [system load statistics])
AC_COLLECTD([mbmon], [disable], [module], [motherboard monitor statistics])
AC_COLLECTD([memory], [disable], [module], [memory statistics])
dns . . . . . . . . $enable_dns
email . . . . . . . $enable_email
hddtemp . . . . . . $enable_hddtemp
+ irq . . . . . . . . $enable_irq
load . . . . . . . $enable_load
mbmon . . . . . . . $enable_mbmon
memory . . . . . . $enable_memory
diff --git a/contrib/collection.cgi b/contrib/collection.cgi
index 5c8bd4dd1050ae4cdeb01d6a92fe1adc0f0ee012..2eb36722edc194f548455cb2066876f3b1b62431 100755 (executable)
--- a/contrib/collection.cgi
+++ b/contrib/collection.cgi
'GPRINT:temp_max:MAX:%4.1lf Max,',
'GPRINT:temp_avg:LAST:%4.1lf Last\l'
],
+ irq => ['DEF:irq_avg={file}:irq:AVERAGE',
+ 'DEF:irq_min={file}:irq:MIN',
+ 'DEF:irq_max={file}:irq:MAX',
+ "AREA:irq_max#$HalfBlue",
+ "AREA:irq_min#$Canvas",
+ "LINE1:irq_avg#$FullBlue:Interrupts",
+ 'GPRINT:irq_min:MIN:%5.1lf Min,',
+ 'GPRINT:irq_avg:AVERAGE:%5.1lf Avg,',
+ 'GPRINT:irq_max:MAX:%5.1lf Max,',
+ 'GPRINT:irq_avg:LAST:%5.1lf Last'],
if_packets => ['DEF:tx_min={file}:tx:MIN',
'DEF:tx_avg={file}:tx:AVERAGE',
'DEF:tx_max={file}:tx:MAX',
fanspeed => ['-t', '{host} fanspeed {inst}', '-v', 'RPM'],
frequency_offset => ['-t', 'NTPd frequency offset ({inst})', '-v', 'Parts per million'],
hddtemp => ['-t', '{host} hdd temperature {inst}', '-v', '°Celsius'],
+ irq => ['-t', '{host} Interrupts {inst}', '-v', 'Ints/s'],
if_errors => ['-t', '{host} {inst} errors', '-v', 'Errors/s'],
if_packets => ['-t', '{host} {inst} packets', '-v', 'Packets/s'],
load => ['-t', '{host} load average', '-v', 'System load', '-X', '0'],
disk => 1,
email => \&output_graph_email_count,
email_size => \&output_graph_email_size,
+ irq => \&output_graph_irq,
spam_score => 1,
spam_check => \&output_graph_spam_check,
load => 0,
return (@ret);
}
+sub output_graph_irq
+{
+ my @inst = sort { $a <=> $b } @_;
+ my @ret = ();
+
+ die if (@inst < 2);
+
+ my @colors = get_n_colors (scalar (@inst));
+
+ for (my $i = 0; $i < scalar (@inst); $i++)
+ {
+ my $inst = $inst[$i];
+ push (@ret,
+ "DEF:avg_$i=$AbsDir/irq-$inst.rrd:irq:AVERAGE",
+ "DEF:min_$i=$AbsDir/irq-$inst.rrd:irq:MIN",
+ "DEF:max_$i=$AbsDir/irq-$inst.rrd:irq:MAX");
+ }
+
+ for (my $i = 0; $i < scalar (@inst); $i++)
+ {
+ my $inst = $inst[$i];
+ my $color = $colors[$i];
+
+ if (length ($inst) > 15)
+ {
+ $inst = substr ($inst, 0, 12) . '...';
+ }
+ else
+ {
+ $inst = sprintf ('%-15s', $inst);
+ }
+
+ push (@ret,
+ "LINE1:avg_$i#$color:$inst",
+ "GPRINT:min_$i:MIN:%5.1lf Min,",
+ "GPRINT:avg_$i:AVERAGE:%5.1lf Avg,",
+ "GPRINT:max_$i:MAX:%5.1lf Max,",
+ "GPRINT:avg_$i:LAST:%5.1lf Last\\l");
+ }
+
+ return (@ret);
+}
+
sub output_graph_email_count
{
my @inst = @_;
print qq(\t\t<div><a href="$MySelf$RelDir">Go up</a></div>\n);
print "\t\t<ul>\n";
- for (@{$files->{$Type}})
+ for (sort { $a <=> $b } @{$files->{$Type}})
{
print qq(\t\t\t<li><a href="$MySelf$RelDir/$Type/$_">$_</a></li>\n);
}
diff --git a/src/Makefile.am b/src/Makefile.am
index 58cc0fe2a6ed845c9c19f7df10a50f0d4c5189b9..2e2d63716ca08c9c08e28eb36731011da08c6c31 100644 (file)
--- a/src/Makefile.am
+++ b/src/Makefile.am
collectd_DEPENDENCIES += hddtemp.la
endif
+if BUILD_MODULE_IRQ
+pkglib_LTLIBRARIES += irq.la
+irq_la_SOURCES = irq.c
+irq_la_LDFLAGS = -module -avoid-version
+collectd_LDADD += "-dlopen" irq.la
+collectd_DEPENDENCIES += irq.la
+endif
+
if BUILD_MODULE_LOAD
pkglib_LTLIBRARIES += load.la
load_la_SOURCES = load.c
diff --git a/src/collectd.conf.in b/src/collectd.conf.in
index 977dde2ff9818c6da8cb8fd91974493c8c0892f0..fcceb5412b5b407f70ddb32b29737a2b30c77e0f 100644 (file)
--- a/src/collectd.conf.in
+++ b/src/collectd.conf.in
@BUILD_MODULE_DISK_TRUE@LoadPlugin disk
@BUILD_MODULE_DNS_TRUE@LoadPlugin dns
@BUILD_MODULE_HDDTEMP_TRUE@LoadPlugin hddtemp
+@BUILD_MODULE_IRQ_TRUE@LoadPlugin irq
@BUILD_MODULE_LOAD_TRUE@LoadPlugin load
@BUILD_MODULE_MBMON_TRUE@LoadPlugin mbmon
@BUILD_MODULE_MEMORY_TRUE@LoadPlugin memory
# Port 7634
#</Plugin>
+#<Plugin irq>
+# Irq 7
+# Irq 8
+# Irq 9
+# IgnoreSelected true
+#</Plugin>
+
#<Plugin mbmon>
# Host 127.0.0.1
# Port 411
diff --git a/src/collectd.conf.pod b/src/collectd.conf.pod
index cffb7ad3ad31a1d1820b50bd9b6e2233ca3a03a1..1fba214ed48126d1e9ecaa81c6a75e7b435c465e 100644 (file)
--- a/src/collectd.conf.pod
+++ b/src/collectd.conf.pod
=back
+=head2 Plugin C<irq>
+
+=over 4
+
+=item B<Irq> I<Irq>
+
+Select this irq. By default these irqs will then be collected. For a more
+detailed description see B<IgnoreSelected> below.
+
+=item B<IgnoreSelected> I<true>|I<false>
+
+If no configuration if given, the B<irq>-plugin will collect data from all
+irqs. This may not be practical, especially if no interrupts happen. Thus, you
+can use the B<Irq>-option to pick the interupt you're interested in.
+Sometimes, however, it's easier/prefered to collect all interupts I<except> a
+few ones. This option enables you to do that: By setting B<IgnoreSelected> to
+I<true> the effect of B<Irq> is inversed: All selected interupts are ignored
+and all other interupts are collected.
+
+=back
+
=head2 Plugin C<mbmon>
=over 4
diff --git a/src/collectd.pod b/src/collectd.pod
index 8ee77ea26a8fec042a49d33eed80e0e99bf14f3b..ec235197b60c147609c8aed8ea403bf50a56d1ab 100644 (file)
--- a/src/collectd.pod
+++ b/src/collectd.pod
=item
+Irq (I<irq>)
+
+=item
+
System load averages (I<load>)
=item
The B<hddtemp> homepage can be found at
L<http://www.guzu.net/linux/hddtemp.php>.
+=head2 irq
+
+The B<irq> modules uses F</proc/interrupts> to retrieve interrupts per second.
+If there is more than one CPU all counters are added for each interrupt.
+
=head2 vserver
B<VServer> support is only available for Linux. It cannot yet be found in a
DS:value:GAUGE:HEARTBEAT:U:U
+=item Irq (F<irq-I<E<lt>irqnumberE<gt>>-I<E<lt>descriptionE<gt>>.rrd>)
+
+ DS:value:COUNTER:HEARTBEAT:U:U
+
=item System load (F<load.rrd>)
DS:shortterm:GAUGE:HEARTBEAT:0:100
diff --git a/src/irq.c b/src/irq.c
--- /dev/null
+++ b/src/irq.c
@@ -0,0 +1,250 @@
+/**
+ * collectd - src/irq.c
+ * Copyright (C) 2007 Peter Holik
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors:
+ * Peter Holik <peter at holik.at>
+ **/
+
+#include "collectd.h"
+#include "common.h"
+#include "plugin.h"
+#include "configfile.h"
+
+#define MODULE_NAME "irq"
+
+#if KERNEL_LINUX
+# define IRQ_HAVE_READ 1
+#else
+# define IRQ_HAVE_READ 0
+#endif
+
+#define BUFSIZE 128
+
+/*
+ * (Module-)Global variables
+ */
+static char *irq_file = "irq-%s.rrd";
+
+static char *config_keys[] =
+{
+ "Irq",
+ "IgnoreSelected",
+ NULL
+};
+static int config_keys_num = 2;
+
+static char *ds_def[] =
+{
+ "DS:irq:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ NULL
+};
+static int ds_num = 1;
+
+static unsigned int *irq_list;
+static unsigned int irq_list_num;
+
+static int base = 10;
+
+/*
+ * irq_list_action:
+ * 0 => default is to collect selected irqs
+ * 1 => ignore selcted irqs
+ */
+static int irq_list_action;
+
+static int irq_config (char *key, char *value)
+{
+ unsigned int *temp;
+ unsigned int irq;
+ char *endptr;
+
+ if (strcasecmp (key, "Irq") == 0)
+ {
+ temp = (unsigned int *) realloc (irq_list, (irq_list_num + 1) * sizeof (unsigned int *));
+ if (temp == NULL)
+ {
+ syslog (LOG_EMERG, "Cannot allocate more memory.");
+ return (1);
+ }
+ irq_list = temp;
+
+ irq = strtol(value, &endptr, base);
+
+ if (endptr == value ||
+ (errno == ERANGE && (irq == LONG_MAX || irq == LONG_MIN)) ||
+ (errno != 0 && irq == 0))
+ {
+ syslog (LOG_EMERG, "Irq value is not a number.");
+ return (1);
+ }
+ irq_list[irq_list_num] = irq;
+ irq_list_num++;
+ }
+ else if (strcasecmp (key, "IgnoreSelected") == 0)
+ {
+ if ((strcasecmp (value, "True") == 0)
+ || (strcasecmp (value, "Yes") == 0)
+ || (strcasecmp (value, "On") == 0))
+ irq_list_action = 1;
+ else
+ irq_list_action = 0;
+ }
+ else
+ {
+ return (-1);
+ }
+ return (0);
+}
+
+/*
+ * Check if this interface/instance should be ignored. This is called from
+ * both, `submit' and `write' to give client and server the ability to
+ * ignore certain stuff..
+ */
+static int check_ignore_irq (const unsigned int irq)
+{
+ int i;
+
+ if (irq_list_num < 1)
+ return (0);
+
+ for (i = 0; i < irq_list_num; i++)
+ if (irq == irq_list[i])
+ return (irq_list_action);
+
+ return (1 - irq_list_action);
+}
+
+static void irq_write (char *host, char *inst, char *value)
+{
+ char file[BUFSIZE];
+ int status;
+
+ if (check_ignore_irq (atoi(inst)))
+ return;
+
+ status = snprintf (file, BUFSIZE, irq_file, inst);
+ if (status < 1)
+ return;
+ else if (status >= BUFSIZE)
+ return;
+
+ rrd_update_file (host, file, value, ds_def, ds_num);
+}
+
+#if IRQ_HAVE_READ
+static void irq_submit (unsigned int irq, unsigned int value, char *devices)
+{
+ char buf[BUFSIZE];
+ char desc[BUFSIZE];
+ int status;
+
+ if (check_ignore_irq (irq))
+ return;
+
+ status = snprintf (buf, BUFSIZE, "%u:%u",
+ (unsigned int) curtime, value);
+
+ if ((status >= BUFSIZE) || (status < 1))
+ return;
+
+ status = snprintf (desc, BUFSIZE, "%d-%s", irq, devices);
+
+ if ((status >= BUFSIZE) || (status < 1))
+ return;
+
+ plugin_submit (MODULE_NAME, desc, buf);
+}
+
+static void irq_read (void)
+{
+#if KERNEL_LINUX
+
+#undef BUFSIZE
+#define BUFSIZE 256
+
+ FILE *fh;
+ char buffer[BUFSIZE];
+ unsigned int irq;
+ unsigned int irq_value;
+ long value;
+ char *ptr, *endptr;
+
+ if ((fh = fopen ("/proc/interrupts", "r")) == NULL)
+ {
+ syslog (LOG_WARNING, "irq: fopen: %s", strerror (errno));
+ return;
+ }
+ while (fgets (buffer, BUFSIZE, fh) != NULL)
+ {
+ errno = 0; /* To distinguish success/failure after call */
+ irq = strtol(buffer, &endptr, base);
+
+ if (endptr == buffer ||
+ (errno == ERANGE && (irq == LONG_MAX || irq == LONG_MIN)) ||
+ (errno != 0 && irq == 0)) continue;
+
+ if (*endptr != ':') continue;
+
+ ptr = ++endptr;
+
+ irq_value = 0;
+ /* sum irq's for all CPUs */
+ while (1)
+ {
+ errno = 0;
+ value = strtol(ptr, &endptr, base);
+
+ if (endptr == ptr ||
+ (errno == ERANGE &&
+ (value == LONG_MAX || value == LONG_MIN)) ||
+ (errno != 0 && value == 0)) break;
+
+ irq_value += value;
+ ptr = endptr;
+ }
+ while (*ptr == ' ') ptr++;
+ while (*ptr && *ptr != ' ') ptr++;
+ while (*ptr == ' ') ptr++;
+
+ if (!*ptr) continue;
+
+ endptr = ptr;
+
+ while (*(++endptr))
+ if (!isalnum(*endptr)) *endptr='_';
+
+ ptr[strlen(ptr)-1] = '\0';
+
+ irq_submit (irq, irq_value, ptr);
+ }
+ fclose (fh);
+#endif /* KERNEL_LINUX */
+}
+#else
+#define irq_read NULL
+#endif /* IRQ_HAVE_READ */
+
+void module_register (void)
+{
+ plugin_register (MODULE_NAME, NULL, irq_read, irq_write);
+ cf_register (MODULE_NAME, irq_config, config_keys, config_keys_num);
+}
+
+#undef BUFSIZE
+#undef MODULE_NAME