Merge branch 'collectd-3.11'
authorFlorian Forster <octo@leeloo.lan.home.verplant.org>
Tue, 10 Apr 2007 15:21:49 +0000 (17:21 +0200)
committerFlorian Forster <octo@leeloo.lan.home.verplant.org>
Tue, 10 Apr 2007 15:21:49 +0000 (17:21 +0200)
Conflicts:

ChangeLog

16 files changed:
AUTHORS
ChangeLog
collectd.spec [deleted file]
configure.in
contrib/collection.cgi
contrib/fedora/collectd.spec [new file with mode: 0644]
contrib/fedora/init.d-collectd [new file with mode: 0644]
contrib/init.d-rh7 [deleted file]
contrib/iptables/accounting.sh [new file with mode: 0755]
src/Makefile.am
src/apache.c
src/collectd.conf.in
src/collectd.conf.pod
src/collectd.pod
src/iptables.c [new file with mode: 0644]
src/irq.c [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
index b123877..b10958b 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -4,7 +4,7 @@ This package was written by:
 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:
index e704b25..dbd6eca 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,6 @@
+       * apache plugin: Support for lighttpd's `BusyServers' (aka.
+       connections) field was added by Florent Monbillard.
+
 2007-04-10, Version 3.11.4
        * dns plugin: Change the order of includes to make the plugin compile
          under FreeBSD.
diff --git a/collectd.spec b/collectd.spec
deleted file mode 100644 (file)
index 6116ffd..0000000
+++ /dev/null
@@ -1,212 +0,0 @@
-Summary:       Statistics collection daemon for filling RRD files.
-Name:           collectd
-Version:       3.11.2
-Release:       0
-Source:                http://collectd.org/files/%{name}-%{version}.tar.gz
-License:       GPL
-Group:         System Environment/Daemons
-BuildRoot:     %{_tmppath}/%{name}-%{version}-root
-BuildPrereq:   lm_sensors-devel, mysql-devel, rrdtool-devel
-Requires:      rrdtool
-Packager:      Florian octo Forster <octo@verplant.org>
-Vendor:                Florian octo Forster <octo@verplant.org>
-
-%description
-collectd is a small daemon written in C for performance.  It reads various
-system  statistics  and updates  RRD files,  creating  them if neccessary.
-Since the daemon doesn't need to startup every time it wants to update the
-files it's very fast and easy on the system. Also, the statistics are very
-fine grained since the files are updated every 10 seconds.
-
-%package apache
-Summary:       apache-plugin for collectd.
-Group:         System Environment/Daemons
-Requires:      collectd = %{version}, libcurl3
-%description apache
-This plugin collectd data provided by Apache's `mod_status'.
-
-%package mysql
-Summary:       mysql-module for collectd.
-Group:         System Environment/Daemons
-Requires:      collectd = %{version}, mysql
-%description mysql
-MySQL  querying  plugin.  This plugins  provides data of  issued commands,
-called handlers and database traffic.
-
-%package sensors
-Summary:       libsensors-module for collectd.
-Group:         System Environment/Daemons
-Requires:      collectd = %{version}, lm_sensors
-%description sensors
-This  plugin  for  collectd  provides  querying  of sensors  supported  by
-lm_sensors.
-
-%prep
-rm -rf $RPM_BUILD_ROOT
-%setup
-
-%build
-./configure --prefix=%{_prefix} --sbindir=%{_sbindir} --mandir=%{_mandir} --libdir=%{_libdir} --sysconfdir=%{_sysconfdir}
-make
-
-%install
-make install DESTDIR=$RPM_BUILD_ROOT
-mkdir -p $RPM_BUILD_ROOT/etc/rc.d/init.d
-cp src/collectd.conf $RPM_BUILD_ROOT/etc/collectd.conf
-cp contrib/init.d-rh7 $RPM_BUILD_ROOT/etc/rc.d/init.d/collectd
-mkdir -p $RPM_BUILD_ROOT/var/lib/collectd
-rm -f $RPM_BUILD_ROOT%{_libdir}/%{name}/*.a
-rm -f $RPM_BUILD_ROOT%{_libdir}/%{name}/*.la
-
-%clean
-rm -rf $RPM_BUILD_ROOT
-
-%files
-%defattr(-,root,root)
-%doc AUTHORS COPYING ChangeLog INSTALL NEWS README
-%doc contrib
-%config /etc/collectd.conf
-%attr(0755,root,root) /etc/rc.d/init.d/collectd
-%attr(0755,root,root) %{_sbindir}/collectd
-%attr(0444,root,root) %{_mandir}/man1/*
-%attr(0444,root,root) %{_mandir}/man5/*
-%attr(0444,root,root) %{_libdir}/%{name}/apcups.so*
-%attr(0444,root,root) %{_libdir}/%{name}/apple_sensors.so*
-%attr(0444,root,root) %{_libdir}/%{name}/battery.so*
-%attr(0444,root,root) %{_libdir}/%{name}/cpu.so*
-%attr(0444,root,root) %{_libdir}/%{name}/cpufreq.so*
-%attr(0444,root,root) %{_libdir}/%{name}/df.so*
-%attr(0444,root,root) %{_libdir}/%{name}/disk.so*
-%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}/load.so*
-%attr(0444,root,root) %{_libdir}/%{name}/mbmon.so
-%attr(0444,root,root) %{_libdir}/%{name}/memory.so*
-%attr(0444,root,root) %{_libdir}/%{name}/multimeter.so*
-%attr(0444,root,root) %{_libdir}/%{name}/nfs.so*
-%attr(0444,root,root) %{_libdir}/%{name}/ntpd.so*
-%attr(0444,root,root) %{_libdir}/%{name}/ping.so*
-%attr(0444,root,root) %{_libdir}/%{name}/processes.so*
-%attr(0444,root,root) %{_libdir}/%{name}/serial.so*
-%attr(0444,root,root) %{_libdir}/%{name}/swap.so*
-%attr(0444,root,root) %{_libdir}/%{name}/tape.so*
-%attr(0444,root,root) %{_libdir}/%{name}/traffic.so*
-%attr(0444,root,root) %{_libdir}/%{name}/users.so*
-%attr(0444,root,root) %{_libdir}/%{name}/vserver.so*
-%attr(0444,root,root) %{_libdir}/%{name}/wireless.so*
-
-%dir /var/lib/collectd
-
-%files apache
-%attr(0444,root,root) %{_libdir}/%{name}/apache.so*
-
-%files mysql
-%attr(0444,root,root) %{_libdir}/%{name}/mysql.so*
-
-%files sensors
-%attr(0444,root,root) %{_libdir}/%{name}/sensors.so*
-
-%changelog
-* Sun Jul 09 2006 Florian octo Forster <octo@verplant.org> 3.10.0-1
-- New upstream version
-
-* Tue Jun 25 2006 Florian octo Forster <octo@verplant.org> 3.9.4-1
-- New upstream version
-
-* Tue Jun 01 2006 Florian octo Forster <octo@verplant.org> 3.9.3-1
-- New upstream version
-
-* Tue May 09 2006 Florian octo Forster <octo@verplant.org> 3.9.2-1
-- New upstream version
-
-* Tue May 09 2006 Florian octo Forster <octo@verplant.org> 3.8.5-1
-- New upstream version
-
-* Fri Apr 21 2006 Florian octo Forster <octo@verplant.org> 3.9.1-1
-- New upstream version
-
-* Fri Apr 14 2006 Florian octo Forster <octo@verplant.org> 3.9.0-1
-- New upstream version
-- Added the `apache' package.
-
-* Thu Mar 14 2006 Florian octo Forster <octo@verplant.org> 3.8.2-1
-- New upstream version
-
-* Thu Mar 13 2006 Florian octo Forster <octo@verplant.org> 3.8.1-1
-- New upstream version
-
-* Thu Mar 09 2006 Florian octo Forster <octo@verplant.org> 3.8.0-1
-- New upstream version
-
-* Sat Feb 18 2006 Florian octo Forster <octo@verplant.org> 3.7.2-1
-- Include `tape.so' so the build doesn't terminate because of missing files..
-- New upstream version
-
-* Sat Feb 04 2006 Florian octo Forster <octo@verplant.org> 3.7.1-1
-- New upstream version
-
-* Mon Jan 30 2006 Florian octo Forster <octo@verplant.org> 3.7.0-1
-- New upstream version
-- Removed the extra `hddtemp' package
-
-* Tue Jan 24 2006 Florian octo Forster <octo@verplant.org> 3.6.2-1
-- New upstream version
-
-* Fri Jan 20 2006 Florian octo Forster <octo@verplant.org> 3.6.1-1
-- New upstream version
-
-* Fri Jan 20 2006 Florian octo Forster <octo@verplant.org> 3.6.0-1
-- New upstream version
-- Added config file, `collectd.conf(5)', `df.so'
-- Added package `collectd-mysql', dependency on `mysqlclient10 | mysql'
-
-* Wed Dec 07 2005 Florian octo Forster <octo@verplant.org> 3.5.0-1
-- New upstream version
-
-* Sat Nov 26 2005 Florian octo Forster <octo@verplant.org> 3.4.0-1
-- New upstream version
-
-* Sat Nov 05 2005 Florian octo Forster <octo@verplant.org> 3.3.0-1
-- New upstream version
-
-* Tue Oct 26 2005 Florian octo Forster <octo@verplant.org> 3.2.0-1
-- New upstream version
-- Added statement to remove the `*.la' files. This fixes a problem when
-  `Unpackaged files terminate build' is in effect.
-- Added `processes.so*' to the main package
-
-* Fri Oct 14 2005 Florian octo Forster <octo@verplant.org> 3.1.0-1
-- New upstream version
-- Added package `collectd-hddtemp'
-
-* Fri Sep 30 2005 Florian octo Forster <octo@verplant.org> 3.0.0-1
-- New upstream version
-- Split the package into `collectd' and `collectd-sensors'
-
-* Fri Sep 16 2005 Florian octo Forster <octo@verplant.org> 2.1.0-1
-- New upstream version
-
-* Mon Sep 10 2005 Florian octo Forster <octo@verplant.org> 2.0.0-1
-- New upstream version
-
-* Mon Aug 29 2005 Florian octo Forster <octo@verplant.org> 1.8.0-1
-- New upstream version
-
-* Sun Aug 25 2005 Florian octo Forster <octo@verplant.org> 1.7.0-1
-- New upstream version
-
-* Sun Aug 21 2005 Florian octo Forster <octo@verplant.org> 1.6.0-1
-- New upstream version
-
-* Sun Jul 17 2005 Florian octo Forster <octo@verplant.org> 1.5.1-1
-- New upstream version
-
-* Sun Jul 17 2005 Florian octo Forster <octo@verplant.org> 1.5-1
-- New upstream version
-
-* Mon Jul 11 2005 Florian octo Forster <octo@verplant.org> 1.4.2-1
-- New upstream version
-
-* Sat Jul 09 2005 Florian octo Forster <octo@verplant.org> 1.4-1
-- Built on RedHat 7.3
index 0f6d3c0..2252e39 100644 (file)
@@ -329,7 +329,9 @@ AC_CHECK_HEADERS(netinet/if_ether.h, [], [],
 #endif
 ])
 
-dnl Checking for libraries
+#
+# Checking for libraries
+#
 AC_CHECK_LIB(m, ext)
 
 #
@@ -944,6 +946,45 @@ AC_DEFINE_UNQUOTED(COLLECT_LIBPCAP, [$collect_libpcap],
        [Wether or not to use the pcap library])
 AM_CONDITIONAL(BUILD_WITH_LIBPCAP, test "x$with_libpcap" = "xyes")
 
+AC_ARG_WITH(libiptc, [AS_HELP_STRING([--with-libiptc@<:@=PREFIX@:>@], [Path to libiptc.])],
+[
+       if test "x$withval" != "xno" && test "x$withval" != "xyes"
+       then
+               LDFLAGS="$LDFLAGS -L$withval/lib"
+               CPPFLAGS="$CPPFLAGS -I$withval/include"
+               with_libiptc="yes"
+       fi
+],
+[
+       if test "x$ac_system" = "xLinux"
+       then
+               with_libiptc="yes"
+       else
+               with_libiptc="no (Linux only)"
+       fi
+])
+if test "x$with_libiptc" = "xyes"
+then
+       AC_CHECK_LIB(iptc, iptc_init,
+       [
+               AC_DEFINE(HAVE_LIBIPTC, 1, [Define to 1 if you have the iptc library (-liptc).])
+       ], [with_libiptc="no (libiptc not found)"])
+fi
+if test "x$with_libiptc" = "xyes"
+then
+       AC_CHECK_HEADERS(libiptc/libiptc.h,
+       [
+               AC_DEFINE(HAVE_LIBIPTC_LIBIPTC_H, 1, [Define to 1 if you have the <libiptc/libiptc.h> header file.])
+       ], [with_libiptc="no (libiptc/libiptc.h not found)"])
+fi
+if test "x$with_libiptc" = "xyes"
+then
+       collect_libiptc=1
+else
+       collect_libiptc=0
+fi
+AM_CONDITIONAL(BUILD_WITH_LIBIPTC, test "x$with_libiptc" = "xyes")
+
 # Define `step' and `hearbeat' values..
 declare -i collectd_step=10
 declare -i collectd_heartbeat=25
@@ -1063,13 +1104,15 @@ AC_COLLECTD([dns],       [disable], [module], [dns statistics])
 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([iptables],  [disable], [module], [IPtables 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])
 AC_COLLECTD([multimeter],[disable], [module], [multimeter statistics])
 AC_COLLECTD([mysql],     [disable], [module], [mysql statistics])
 AC_COLLECTD([nfs],       [disable], [module], [nfs statistics])
-AC_COLLECTD([ntpd],      [disable], [module], [nfs statistics])
+AC_COLLECTD([ntpd],      [disable], [module], [ntpd statistics])
 AC_COLLECTD([ping],      [disable], [module], [ping statistics])
 AC_COLLECTD([processes], [disable], [module], [processes statistics])
 AC_COLLECTD([sensors],   [disable], [module], [lm_sensors statistics])
@@ -1096,6 +1139,7 @@ Configuration:
     libkstat  . . . . . $with_kstat
     libmysql  . . . . . $with_libmysql
     libpcap . . . . . . $with_libpcap
+    libiptc . . . . . . $with_libiptc
     libpthread  . . . . $with_libpthread
 
   Features:
@@ -1116,6 +1160,8 @@ Configuration:
     dns . . . . . . . . $enable_dns
     email . . . . . . . $enable_email
     hddtemp . . . . . . $enable_hddtemp
+    irq . . . . . . . . $enable_irq
+    iptables  . . . . . $enable_iptables
     load  . . . . . . . $enable_load
     mbmon . . . . . . . $enable_mbmon
     memory  . . . . . . $enable_memory
index 5c8bd4d..31f1b91 100755 (executable)
@@ -366,6 +366,16 @@ our $GraphDefs;
                        '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',
@@ -1185,6 +1195,7 @@ our $GraphArgs =
        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'],
@@ -1229,6 +1240,7 @@ our $GraphMulti =
        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,
@@ -1419,6 +1431,49 @@ sub output_graph_ping
        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 = @_;
@@ -1819,6 +1874,83 @@ Cache-Control: no-cache
        </head>
 
        <body>
+       <script type="text/javascript">
+         var lastUpdateHour = (new Date ()).getTime () / 1000;
+         var lastUpdateDay = lastUpdateHour;
+         var lastUpdateWeek = lastUpdateHour;
+         var lastUpdateMonth = lastUpdateHour;
+         var lastUpdateYear = lastUpdateHour;
+
+         function exchangeImages (origImg, newImg)
+         {
+           var parent = origImg.parentNode;
+
+           if (!newImg.complete)
+             setTimeout (function () { exchangeImages (origImg, newImg); }, 100);
+           else
+             parent.replaceChild (newImg, origImg);
+         }
+
+         function updateImage (origImg)
+         {
+           var imgSrc = origImg.src;
+           var newImg = new Image (origImg.width, origImg.height);
+           var now = (new Date ()).getTime () / 1000;
+
+           imgSrc = imgSrc.replace (/\\?.*/, "");
+           imgSrc = imgSrc + "?update=" + now;
+
+           newImg.className = origImg.className;
+           newImg.src = imgSrc;
+
+           exchangeImages (origImg, newImg);
+         } /* updateImage */
+
+         function updateImageClass (className)
+         {
+           var elems = document.getElementsByTagName ("img");
+           for (var i = 0; i < elems.length; i++)
+           {
+             var img = elems[i];
+             if (img.className != className)
+             continue;
+             updateImage (img);
+           }
+         } /* updateImageClass */
+
+         function doUpdate ()
+         {
+           var now = (new Date ()).getTime () / 1000;
+           if ((now - lastUpdateHour) >= 10)
+           {
+             updateImageClass ("hour");
+             lastUpdateHour = 0 + now;
+           }
+           if ((now - lastUpdateDay) >= 120)
+           {
+             updateImageClass ("day");
+             lastUpdateDay = now;
+           }
+           if ((now - lastUpdateWeek) >= 600)
+           {
+             updateImageClass ("week");
+             lastUpdateWeek = now;
+           }
+           if ((now - lastUpdateMonth) >= 3600)
+           {
+             updateImageClass ("month");
+             lastUpdateMonth = now;
+           }
+           if ((now - lastUpdateYear) >= 7200)
+           {
+             updateImageClass ("year");
+             lastUpdateYear = now;
+           }
+         } /* doUpdate */
+
+         /* It's important to save this variable */
+         var updateInterval = window.setInterval ("doUpdate ()", 10000);
+       </script>
 HEADER
 
        my $MySelf = defined ($ENV{'GATEWAY_INTERFACE'}) ? $ENV{'SCRIPT_NAME'} : $0;
@@ -1828,7 +1960,7 @@ HEADER
                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);
                }
@@ -1836,15 +1968,15 @@ HEADER
                </ul>
 
                <h3>Hourly</h3>
-               <div><img src="$MySelf$RelDir/$Type/hour" /></div>
+               <div><img src="$MySelf$RelDir/$Type/hour" class="hour" /></div>
                <h3>Daily</h3>
-               <div><img src="$MySelf$RelDir/$Type/day" /></div>
+               <div><img src="$MySelf$RelDir/$Type/day" class="day" /></div>
                <h3>Weekly</h3>
-               <div><img src="$MySelf$RelDir/$Type/week" /></div>
+               <div><img src="$MySelf$RelDir/$Type/week" class="week" /></div>
                <h3>Monthly</h3>
-               <div><img src="$MySelf$RelDir/$Type/month" /></div>
+               <div><img src="$MySelf$RelDir/$Type/month" class="month" /></div>
                <h3>Yearly</h3>
-               <div><img src="$MySelf$RelDir/$Type/year" /></div>
+               <div><img src="$MySelf$RelDir/$Type/year" class="year" /></div>
 HTML
        }
        elsif (length ($Type) != 0)
@@ -1862,15 +1994,15 @@ HTML
 
                print <<HTML;
                <h3>Hourly</h3>
-               <div><img src="$MySelf$RelDir/$ext/hour" /></div>
+               <div><img src="$MySelf$RelDir/$ext/hour" class="hour" /></div>
                <h3>Daily</h3>
-               <div><img src="$MySelf$RelDir/$ext/day" /></div>
+               <div><img src="$MySelf$RelDir/$ext/day" class="day" /></div>
                <h3>Weekly</h3>
-               <div><img src="$MySelf$RelDir/$ext/week" /></div>
+               <div><img src="$MySelf$RelDir/$ext/week" class="week" /></div>
                <h3>Monthly</h3>
-               <div><img src="$MySelf$RelDir/$ext/month" /></div>
+               <div><img src="$MySelf$RelDir/$ext/month" class="month" /></div>
                <h3>Yearly</h3>
-               <div><img src="$MySelf$RelDir/$ext/year" /></div>
+               <div><img src="$MySelf$RelDir/$ext/year" class="year" /></div>
 HTML
        }
        else
@@ -1898,7 +2030,7 @@ HTML
                        if (ref ($GraphMulti->{$type}) eq 'CODE')
                        {
                                print qq(\t\t<a href="$MySelf$RelDir/$type" />),
-                               qq(<img src="$MySelf$RelDir/$type/day" /></a>\n);
+                               qq(<img src="$MySelf$RelDir/$type/day" class="day" /></a>\n);
                                next;
                        }
 
@@ -1909,12 +2041,12 @@ HTML
                                if (length ($inst))
                                {
                                        print qq(\t\t<a href="$MySelf$RelDir/$type/$inst" />),
-                                       qq(<img src="$MySelf$RelDir/$type/$inst/day" /></a>\n);
+                                       qq(<img src="$MySelf$RelDir/$type/$inst/day" class="day" /></a>\n);
                                }
                                else
                                {
                                        print qq(\t\t<a href="$MySelf$RelDir/$type" />),
-                                       qq(<img src="$MySelf$RelDir/$type/day" /></a>\n);
+                                       qq(<img src="$MySelf$RelDir/$type/day" class="day" /></a>\n);
                                }
                        }
                }
diff --git a/contrib/fedora/collectd.spec b/contrib/fedora/collectd.spec
new file mode 100644 (file)
index 0000000..9cc9f2b
--- /dev/null
@@ -0,0 +1,238 @@
+Summary:       Statistics collection daemon for filling RRD files.
+Name:           collectd
+Version:       3.11.2
+Release:       0.fc0
+Source:                http://collectd.org/files/%{name}-%{version}.tar.gz
+License:       GPL
+Group:         System Environment/Daemons
+BuildRoot:     %{_tmppath}/%{name}-%{version}-root
+BuildPrereq:   lm_sensors-devel, mysql-devel, rrdtool-devel
+Requires:      rrdtool
+Packager:      Florian octo Forster <octo@verplant.org>
+Vendor:                Florian octo Forster <octo@verplant.org>
+
+%description
+collectd is a small daemon written in C for performance.  It reads various
+system  statistics  and updates  RRD files,  creating  them if neccessary.
+Since the daemon doesn't need to startup every time it wants to update the
+files it's very fast and easy on the system. Also, the statistics are very
+fine grained since the files are updated every 10 seconds.
+
+%package apache
+Summary:       apache-plugin for collectd.
+Group:         System Environment/Daemons
+Requires:      collectd = %{version}, libcurl3
+%description apache
+This plugin collectd data provided by Apache's `mod_status'.
+
+#%package email
+#Summary:      email-plugin for collectd.
+#Group:                System Environment/Daemons
+#Requires:     collectd = %{version}, spamassassin
+#%description email
+#This plugin collectd data provided by spamassassin.
+
+%package mysql
+Summary:       mysql-module for collectd.
+Group:         System Environment/Daemons
+Requires:      collectd = %{version}, mysql
+%description mysql
+MySQL  querying  plugin.  This plugins  provides data of  issued commands,
+called handlers and database traffic.
+
+%package sensors
+Summary:       libsensors-module for collectd.
+Group:         System Environment/Daemons
+Requires:      collectd = %{version}, lm_sensors
+%description sensors
+This  plugin  for  collectd  provides  querying  of sensors  supported  by
+lm_sensors.
+
+%prep
+rm -rf $RPM_BUILD_ROOT
+%setup
+
+%build
+./configure --prefix=%{_prefix} --sbindir=%{_sbindir} --mandir=%{_mandir} --libdir=%{_libdir} --sysconfdir=%{_sysconfdir}
+make
+
+%install
+make install DESTDIR=$RPM_BUILD_ROOT
+mkdir -p $RPM_BUILD_ROOT/etc/rc.d/init.d
+mkdir -p $RPM_BUILD_ROOT/var/www/cgi-bin
+cp src/collectd.conf $RPM_BUILD_ROOT/etc/collectd.conf
+cp contrib/fedora/init.d-collectd $RPM_BUILD_ROOT/etc/rc.d/init.d/collectd
+cp contrib/collection.cgi $RPM_BUILD_ROOT/var/www/cgi-bin
+mkdir -p $RPM_BUILD_ROOT/var/lib/collectd
+rm -f $RPM_BUILD_ROOT%{_libdir}/%{name}/*.a
+rm -f $RPM_BUILD_ROOT%{_libdir}/%{name}/*.la
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%post
+/sbin/chkconfig --add collectd
+/sbin/chkconfig collectd on
+
+#%postun
+#/sbin/chkconfig collectd off
+#/sbin/chkconfig --del collectd
+
+%files
+%defattr(-,root,root)
+%doc AUTHORS COPYING ChangeLog INSTALL NEWS README
+%config /etc/collectd.conf
+%attr(0755,root,root) /etc/rc.d/init.d/collectd
+%attr(0755,root,root) /var/www/cgi-bin/collection.cgi
+%attr(0755,root,root) %{_sbindir}/collectd
+%attr(0444,root,root) %{_mandir}/man1/*
+%attr(0444,root,root) %{_mandir}/man5/*
+%attr(0444,root,root) %{_libdir}/%{name}/apcups.so*
+%attr(0444,root,root) %{_libdir}/%{name}/apple_sensors.so*
+%attr(0444,root,root) %{_libdir}/%{name}/battery.so*
+%attr(0444,root,root) %{_libdir}/%{name}/cpu.so*
+%attr(0444,root,root) %{_libdir}/%{name}/cpufreq.so*
+%attr(0444,root,root) %{_libdir}/%{name}/df.so*
+%attr(0444,root,root) %{_libdir}/%{name}/disk.so*
+%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*
+%attr(0444,root,root) %{_libdir}/%{name}/multimeter.so*
+%attr(0444,root,root) %{_libdir}/%{name}/nfs.so*
+%attr(0444,root,root) %{_libdir}/%{name}/ntpd.so*
+%attr(0444,root,root) %{_libdir}/%{name}/ping.so*
+%attr(0444,root,root) %{_libdir}/%{name}/processes.so*
+%attr(0444,root,root) %{_libdir}/%{name}/serial.so*
+%attr(0444,root,root) %{_libdir}/%{name}/swap.so*
+%attr(0444,root,root) %{_libdir}/%{name}/tape.so*
+%attr(0444,root,root) %{_libdir}/%{name}/traffic.so*
+%attr(0444,root,root) %{_libdir}/%{name}/users.so*
+%attr(0444,root,root) %{_libdir}/%{name}/vserver.so*
+%attr(0444,root,root) %{_libdir}/%{name}/wireless.so*
+
+%dir /var/lib/collectd
+
+%files apache
+%attr(0444,root,root) %{_libdir}/%{name}/apache.so*
+
+#%files email
+#%attr(0444,root,root) %{_libdir}/%{name}/email.so
+
+%files mysql
+%attr(0444,root,root) %{_libdir}/%{name}/mysql.so*
+
+%files sensors
+%attr(0444,root,root) %{_libdir}/%{name}/sensors.so*
+
+%changelog
+* Wed Jan 11 2007 Iain Lea <iain@bricbrac.de> 3.11.0-0
+- fixed spec file to build correctly on fedora core
+- added improved init.d script to work with chkconfig
+- added %post and %postun to call chkconfig automatically
+
+* Sun Jul 09 2006 Florian octo Forster <octo@verplant.org> 3.10.0-1
+- New upstream version
+
+* Tue Jun 25 2006 Florian octo Forster <octo@verplant.org> 3.9.4-1
+- New upstream version
+
+* Tue Jun 01 2006 Florian octo Forster <octo@verplant.org> 3.9.3-1
+- New upstream version
+
+* Tue May 09 2006 Florian octo Forster <octo@verplant.org> 3.9.2-1
+- New upstream version
+
+* Tue May 09 2006 Florian octo Forster <octo@verplant.org> 3.8.5-1
+- New upstream version
+
+* Fri Apr 21 2006 Florian octo Forster <octo@verplant.org> 3.9.1-1
+- New upstream version
+
+* Fri Apr 14 2006 Florian octo Forster <octo@verplant.org> 3.9.0-1
+- New upstream version
+- Added the `apache' package.
+
+* Thu Mar 14 2006 Florian octo Forster <octo@verplant.org> 3.8.2-1
+- New upstream version
+
+* Thu Mar 13 2006 Florian octo Forster <octo@verplant.org> 3.8.1-1
+- New upstream version
+
+* Thu Mar 09 2006 Florian octo Forster <octo@verplant.org> 3.8.0-1
+- New upstream version
+
+* Sat Feb 18 2006 Florian octo Forster <octo@verplant.org> 3.7.2-1
+- Include `tape.so' so the build doesn't terminate because of missing files..
+- New upstream version
+
+* Sat Feb 04 2006 Florian octo Forster <octo@verplant.org> 3.7.1-1
+- New upstream version
+
+* Mon Jan 30 2006 Florian octo Forster <octo@verplant.org> 3.7.0-1
+- New upstream version
+- Removed the extra `hddtemp' package
+
+* Tue Jan 24 2006 Florian octo Forster <octo@verplant.org> 3.6.2-1
+- New upstream version
+
+* Fri Jan 20 2006 Florian octo Forster <octo@verplant.org> 3.6.1-1
+- New upstream version
+
+* Fri Jan 20 2006 Florian octo Forster <octo@verplant.org> 3.6.0-1
+- New upstream version
+- Added config file, `collectd.conf(5)', `df.so'
+- Added package `collectd-mysql', dependency on `mysqlclient10 | mysql'
+
+* Wed Dec 07 2005 Florian octo Forster <octo@verplant.org> 3.5.0-1
+- New upstream version
+
+* Sat Nov 26 2005 Florian octo Forster <octo@verplant.org> 3.4.0-1
+- New upstream version
+
+* Sat Nov 05 2005 Florian octo Forster <octo@verplant.org> 3.3.0-1
+- New upstream version
+
+* Tue Oct 26 2005 Florian octo Forster <octo@verplant.org> 3.2.0-1
+- New upstream version
+- Added statement to remove the `*.la' files. This fixes a problem when
+  `Unpackaged files terminate build' is in effect.
+- Added `processes.so*' to the main package
+
+* Fri Oct 14 2005 Florian octo Forster <octo@verplant.org> 3.1.0-1
+- New upstream version
+- Added package `collectd-hddtemp'
+
+* Fri Sep 30 2005 Florian octo Forster <octo@verplant.org> 3.0.0-1
+- New upstream version
+- Split the package into `collectd' and `collectd-sensors'
+
+* Fri Sep 16 2005 Florian octo Forster <octo@verplant.org> 2.1.0-1
+- New upstream version
+
+* Mon Sep 10 2005 Florian octo Forster <octo@verplant.org> 2.0.0-1
+- New upstream version
+
+* Mon Aug 29 2005 Florian octo Forster <octo@verplant.org> 1.8.0-1
+- New upstream version
+
+* Sun Aug 25 2005 Florian octo Forster <octo@verplant.org> 1.7.0-1
+- New upstream version
+
+* Sun Aug 21 2005 Florian octo Forster <octo@verplant.org> 1.6.0-1
+- New upstream version
+
+* Sun Jul 17 2005 Florian octo Forster <octo@verplant.org> 1.5.1-1
+- New upstream version
+
+* Sun Jul 17 2005 Florian octo Forster <octo@verplant.org> 1.5-1
+- New upstream version
+
+* Mon Jul 11 2005 Florian octo Forster <octo@verplant.org> 1.4.2-1
+- New upstream version
+
+* Sat Jul 09 2005 Florian octo Forster <octo@verplant.org> 1.4-1
+- Built on RedHat 7.3
diff --git a/contrib/fedora/init.d-collectd b/contrib/fedora/init.d-collectd
new file mode 100644 (file)
index 0000000..2bf877c
--- /dev/null
@@ -0,0 +1,66 @@
+#!/bin/bash
+#
+# collectd    Startup script for the Collectd statistics gathering daemon
+# chkconfig: - 86 15
+# description: Collectd is a statistics gathering daemon used to collect \
+#   system information ie. cpu, memory, disk, network
+# processname: collectd
+# config: /etc/collectd.conf
+# config: /etc/sysconfig/collectd
+# pidfile: /var/run/collectd.pid
+
+# Source function library.
+. /etc/init.d/functions
+
+RETVAL=0
+ARGS=""
+prog="collectd"
+CONFIG=/etc/collectd.conf
+
+if [ -r /etc/default/$prog ]; then
+       . /etc/default/$prog
+fi
+
+start () {
+       echo -n $"Starting $prog: "
+       if [ -r "$CONFIG" ]
+       then
+               daemon /usr/sbin/collectd -C "$CONFIG"
+               RETVAL=$?
+               echo
+               [ $RETVAL -eq 0 ] && touch /var/lock/subsys/$prog
+       fi
+}
+stop () {
+       echo -n $"Stopping $prog: "
+       killproc $prog
+       RETVAL=$?
+       echo
+       [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$prog
+}
+# See how we were called.
+case "$1" in
+  start)
+       start
+       ;;
+  stop)
+       stop
+       ;;
+  status)
+       status $prog
+       ;;
+  restart|reload)
+       stop
+       start
+       ;;
+  condrestart)
+       [ -f /var/lock/subsys/$prog ] && restart || :
+       ;;
+  *)
+       echo $"Usage: $0 {start|stop|status|restart|reload|condrestart}"
+       exit 1
+esac
+
+exit $?
+
+# vim:syntax=sh
diff --git a/contrib/init.d-rh7 b/contrib/init.d-rh7
deleted file mode 100755 (executable)
index c7fe270..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-#!/bin/bash
-
-# Source function library.
-. /etc/init.d/functions
-
-RETVAL=0
-ARGS=""
-prog="collectd"
-CONFIG=/etc/collectd.conf
-
-if [ -r /etc/default/$prog ]; then
-       . /etc/default/$prog
-fi
-
-start () {
-       echo -n $"Starting $prog: "
-       if [ -r "$CONFIG" ]
-       then
-               daemon /usr/sbin/collectd -C "$CONFIG"
-               RETVAL=$?
-               echo
-               [ $RETVAL -eq 0 ] && touch /var/lock/subsys/$prog
-       fi
-}
-stop () {
-       echo -n $"Stopping $prog: "
-       killproc $prog
-       RETVAL=$?
-       echo
-       [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$prog
-}
-# See how we were called.
-case "$1" in
-  start)
-       start
-       ;;
-  stop)
-       stop
-       ;;
-  status)
-       status $prog
-       ;;
-  restart|reload)
-       stop
-       sleep 1
-       start
-       ;;
-  condrestart)
-       [ -f /var/lock/subsys/$prog ] && restart || :
-       ;;
-  *)
-       echo $"Usage: $0 {start|stop|status|restart|reload|condrestart}"
-       exit 1
-esac
-
-exit $?
-
-# vim:syntax=sh
diff --git a/contrib/iptables/accounting.sh b/contrib/iptables/accounting.sh
new file mode 100755 (executable)
index 0000000..71032f0
--- /dev/null
@@ -0,0 +1,29 @@
+#/bin/bash
+#Simple script that sets up some chains in mangle table to do global logging of all 
+#traffic going in and out of an interface
+#Could also use the regular input/output tree but this also catches the forwarded nat traffic
+
+IT="iptables -t mangle"
+
+#First clear the old stuff
+$IT -F incoming
+$IT -F outgoing
+$IT -N incoming
+$IT -N outgoing
+
+$IT -D PREROUTING -i eth0 -j incoming
+$IT -D POSTROUTING -o eth0 -j outgoing
+
+#should add some arg == stop exit here...
+
+$IT -A PREROUTING -i eth0 -j incoming
+$IT -A POSTROUTING -o eth0 -j outgoing
+
+$IT -A incoming -p tcp -m comment --comment "tcp"
+$IT -A incoming -p udp -m comment --comment "udp"
+$IT -A incoming -p icmp -m comment --comment "icmp"
+
+$IT -A outgoing -p tcp -m comment --comment "tcp"
+$IT -A outgoing -p udp -m comment --comment "udp"
+$IT -A outgoing -p icmp -m comment --comment "icmp"
+
index 58cc0fe..aee7479 100644 (file)
@@ -208,6 +208,25 @@ collectd_LDADD += "-dlopen" hddtemp.la
 collectd_DEPENDENCIES += hddtemp.la
 endif
 
+if BUILD_MODULE_IPTABLES
+pkglib_LTLIBRARIES += iptables.la
+iptables_la_SOURCES = iptables.c
+iptables_la_LDFLAGS = -module -avoid-version
+if BUILD_WITH_LIBIPTC
+iptables_la_LDFLAGS += -liptc
+endif
+collectd_LDADD += "-dlopen" iptables.la
+collectd_DEPENDENCIES += iptables.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
index 530481b..7c48f08 100644 (file)
@@ -1,6 +1,7 @@
 /**
  * collectd - src/apache.c
  * Copyright (C) 2006  Florian octo Forster
+ * Copyright (C) 2007  Florent EppO Monbillard
  *
  * 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
@@ -18,6 +19,8 @@
  *
  * Authors:
  *   Florian octo Forster <octo at verplant.org>
+ *   Florent EppO Monbillard <eppo at darox.net>
+ *   - connections/lighttpd extension
  **/
 
 #include "collectd.h"
@@ -75,6 +78,15 @@ static char *scoreboard_ds_def[] =
 };
 static int scoreboard_ds_num = 1;
 
+/* for lighttpd; Limit to 65536 active connections */
+static char *connections_file = "apache/apache_connections.rrd";
+static char *connections_ds_def[] =
+{
+       "DS:connections:GAUGE:"COLLECTD_HEARTBEAT":0:65536", 
+       NULL
+};
+static int connections_ds_num = 1;
+
 static char *config_keys[] =
 {
        "URL",
@@ -197,6 +209,12 @@ static void scoreboard_write (char *host, char *inst, char *val)
        rrd_update_file (host, buf, val, scoreboard_ds_def, scoreboard_ds_num);
 }
 
+static void connections_write (char *host, char *inst, char *val)
+{
+       rrd_update_file (host, connections_file, val, connections_ds_def,
+                       connections_ds_num);
+}
+
 #if APACHE_HAVE_READ
 static void submit (char *type, char *inst, long long value)
 {
@@ -319,6 +337,8 @@ static void apache_read (void)
                {
                        if (strcmp (fields[0], "Scoreboard:") == 0)
                                submit_scoreboard (fields[1]);
+                       else if (strcmp (fields[0], "BusyServers:") == 0)
+                               submit ("apache_connections", NULL, atol (fields[1]));
                }
        }
 
@@ -334,6 +354,7 @@ void module_register (void)
        plugin_register ("apache_requests",   NULL, NULL, requests_write);
        plugin_register ("apache_bytes",      NULL, NULL, bytes_write);
        plugin_register ("apache_scoreboard", NULL, NULL, scoreboard_write);
+       plugin_register ("apache_connections", NULL, NULL, connections_write);
        cf_register (MODULE_NAME, config, config_keys, config_keys_num);
 }
 
index 977dde2..b3f9963 100644 (file)
@@ -30,6 +30,8 @@
 @BUILD_MODULE_DISK_TRUE@LoadPlugin disk
 @BUILD_MODULE_DNS_TRUE@LoadPlugin dns
 @BUILD_MODULE_HDDTEMP_TRUE@LoadPlugin hddtemp
+@BUILD_MODULE_IPTABLES_TRUE@LoadPlugin iptables
+@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 iptables>
+#      Chain table chain
+#</Plugin>
+
+#<Plugin irq>
+#      Irq 7
+#      Irq 8
+#      Irq 9
+#      IgnoreSelected true
+#</Plugin>
+
 #<Plugin mbmon>
 #      Host 127.0.0.1
 #      Port 411
index cffb7ad..803df8b 100644 (file)
@@ -118,6 +118,10 @@ the following snipped to base your Apache config upon:
     </Location>
   </IfModule>
 
+Since it's C<mod_status> module is very similar to Apache's, B<lighttpd> is
+also supported. It introduces a new field, called C<BusyServers>, to count the
+number of currently connected clients. This field is also supported.
+
 The following options are accepted by the C<apache>-plugin:
 
 =over 4
@@ -240,6 +244,27 @@ TCP-Port to connect to. Defaults to B<7634>.
 
 =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
index 8ee77ea..96c3fcd 100644 (file)
@@ -16,7 +16,7 @@ settings. The following features may be available:
 
 =item
 
-Apache server stats (I<apache>)
+Apache and lighttpd server statistics (I<apache>)
 
 =item
 
@@ -52,6 +52,10 @@ Harddisk temperatures (I<hddtemp>)
 
 =item
 
+Irq (I<irq>)
+
+=item
+
 System load averages (I<load>)
 
 =item
@@ -170,10 +174,10 @@ values.
 
 =head2 apache
 
-This module connects to an Apache webserver and expects the output produced by
-B<mod_status.c>. If requires B<libcurl> to set up the HTTP connection and issue
-the request(s). The following is a sample config for the Apache webserver. The
-use of C<ExtendedStatus on> is mandatory.
+This module connects to an Apache or lighttpd webserver and expects the output
+produced by B<mod_status.c>. If requires B<libcurl> to set up the HTTP
+connection and issue the request(s). The following is a sample config for the
+Apache webserver. Under Apache, the use of C<ExtendedStatus on> is mandatory.
 
   ExtendedStatus on
   <IfModule mod_status.c>
@@ -387,6 +391,10 @@ The DS'es depend on the module creating the RRD files:
 
   DS:value:GAUGE:HEARTBEAT:U:U
 
+=item Irq (F<irq-I<E<lt>irqnumberE<gt>>.rrd>)
+
+  DS:value:COUNTER:HEARTBEAT:0:65535
+
 =item System load (F<load.rrd>)
 
   DS:shortterm:GAUGE:HEARTBEAT:0:100
diff --git a/src/iptables.c b/src/iptables.c
new file mode 100644 (file)
index 0000000..84878fd
--- /dev/null
@@ -0,0 +1,396 @@
+/**
+ * collectd - src/iptables.c
+ * Copyright (C) 2007 Sjoerd van der Berg
+ *
+ * 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:
+ *  Sjoerd van der Berg <harekiet at users.sourceforge.net>
+ **/
+
+#include "collectd.h"
+#include "common.h"
+#include "plugin.h"
+#include "configfile.h"
+#include "utils_debug.h"
+
+#if HAVE_LIBIPTC_LIBIPTC_H
+# include <libiptc/libiptc.h>
+#endif
+
+#if HAVE_LIBIPTC_LIBIPTC_H
+# define IPTABLES_HAVE_READ 1
+#else
+# define IPTABLES_HAVE_READ 0
+#endif
+
+#define MODULE_NAME "iptables"
+#define BUFSIZE 512
+
+/*
+ * (Module-)Global variables
+ */
+
+/*
+ * Removed packet count for now, should have config option if you want to save
+ * them Although other collectd models don't seem to care much for options
+ * eitherway for what to log
+ */
+/* Limit to ~125MByte/s (~1GBit/s) */
+static char *ds_def[] =
+{
+       "DS:value:COUNTER:"COLLECTD_HEARTBEAT":0:134217728",
+       NULL
+};
+static int ds_num = 1;
+
+#if IPTABLES_HAVE_READ
+/*
+ * Config format should be `Chain table chainname',
+ * e. g. `Chain mangle incoming'
+ */
+static char *config_keys[] =
+{
+       "Chain",
+       NULL
+};
+static int config_keys_num = 1;
+/*
+    Each table/chain combo that will be queried goes into this list
+*/
+#ifndef XT_TABLE_MAXNAMELEN
+# define XT_TABLE_MAXNAMELEN 32
+#endif
+typedef struct {
+    char table[XT_TABLE_MAXNAMELEN];
+    char chain[XT_TABLE_MAXNAMELEN];
+    union
+    {
+       int   num;
+       char *comment;
+    } rule;
+    enum
+    {
+       RTYPE_NUM,
+       RTYPE_COMMENT,
+       RTYPE_COMMENT_ALL
+    } rule_type;
+    char name[64];
+} ip_chain_t;
+
+static ip_chain_t **chain_list = NULL;
+static int chain_num = 0;
+
+static int iptables_config (char *key, char *value)
+{
+       if (strcasecmp (key, "Chain") == 0)
+       {
+               ip_chain_t temp, *final, **list;
+               char *table;
+               int   table_len;
+               char *chain;
+               int   chain_len;
+
+               char *value_copy;
+               char *fields[4];
+               int   fields_num;
+               
+               memset (&temp, 0, sizeof (temp));
+
+               value_copy = strdup (value);
+               if (value_copy == NULL)
+               {
+                   syslog (LOG_ERR, "strdup failed: %s", strerror (errno));
+                   return (1);
+               }
+
+               /* Chain <table> <chain> [<comment|num> [name]] */
+               fields_num = strsplit (value_copy, fields, 4);
+               if (fields_num < 2)
+               {
+                   free (value_copy);
+                   return (1);
+               }
+
+               table = fields[0];
+               chain = fields[1];
+
+               table_len = strlen (table);
+               if (table_len >= sizeof(temp.table))
+               {
+                       syslog (LOG_ERR, "Table `%s' too long.", table);
+                       free (value_copy);
+                       return (1);
+               }
+               strncpy (temp.table, table, table_len);
+               temp.table[table_len] = '\0';
+
+               chain_len = strlen (chain);
+               if (chain_len >= sizeof(temp.chain))
+               {
+                       syslog (LOG_ERR, "Chain `%s' too long.", chain);
+                       free (value_copy);
+                       return (1);
+               }
+               strncpy (temp.chain, chain, chain_len);
+               temp.chain[chain_len] = '\0'; 
+
+               if (fields_num >= 3)
+               {
+                   char *comment = fields[2];
+                   int   rule = atoi (comment);
+
+                   if (rule)
+                   {
+                       temp.rule.num = rule;
+                       temp.rule_type = RTYPE_NUM;
+                   }
+                   else
+                   {
+                       strncpy (temp.rule.comment, comment,
+                               sizeof (temp.rule.comment) - 1);
+                       temp.rule_type = RTYPE_COMMENT;
+                   }
+               }
+               else
+               {
+                   temp.rule_type = RTYPE_COMMENT_ALL;
+               }
+
+               if (fields_num >= 4)
+                   strncpy (temp.name, fields[3], sizeof (temp.name) - 1);
+
+               free (value_copy);
+               value_copy = NULL;
+               table = NULL;
+               chain = NULL;
+
+               list = (ip_chain_t **) realloc (chain_list, (chain_num + 1) * sizeof (ip_chain_t *));
+               if (list == NULL)
+               {
+                       syslog (LOG_ERR, "realloc failed: %s", strerror (errno));
+                       return (1);
+               }
+
+               chain_list = list;
+               final = (ip_chain_t *) malloc( sizeof(temp) );
+               if (final == NULL) 
+               {
+                       syslog (LOG_ERR, "malloc failed: %s", strerror (errno));
+                       return (1);
+               }
+               memcpy (final, &temp, sizeof (temp));
+               chain_list[chain_num] = final;
+               chain_num++;
+
+               DBG ("Chain #%i: table = %s; chain = %s;", chain_num, final->table, final->chain);
+       }
+       else 
+       {
+               return (-1);
+       }
+
+       return (0);
+}
+#endif /* IPTABLES_HAVE_READ */
+
+static void iptables_write (char *host, char *orig_inst, char *val, char *type) 
+{
+    char *table;
+    char *inst;
+    char file[256];
+    int status;
+
+    table = strdup (orig_inst);
+    if (table == NULL)
+       return;
+    inst = strchr (table, ',');
+    if (inst == NULL)
+    {
+       free (table);
+       return;
+    }
+
+    *inst = '\0';
+    inst++;
+    if (*inst == '\0')
+    {
+       free (table);
+       return;
+    }
+
+    status = snprintf (file, sizeof (file), "iptables-%s/%s-%s.rrd",
+           table, type, inst);
+    free (table);
+    if ((status >= sizeof (file)) || (status < 1))
+       return;
+
+    rrd_update_file (host, file, val, ds_def, ds_num);
+} /* void iptables_write */
+
+static void iptables_write_bytes (char *host, char *inst, char *val)
+{
+    iptables_write (host, inst, val, "ipt_bytes");
+}
+
+static void iptables_write_packets (char *host, char *inst, char *val)
+{
+    iptables_write (host, inst, val, "ipt_packets");
+}
+
+#if IPTABLES_HAVE_READ
+static int submit_match (const struct ipt_entry_match *match,
+               const struct ipt_entry *entry,
+               const ip_chain_t *chain,
+               int rule_num) 
+{
+    char inst[64];
+    char value[64];
+    int status;
+
+    /* Only log rules that have a comment, although could probably also do
+     * numerical targets sometime */
+    if (chain->rule_type == RTYPE_NUM)
+    {
+       if (chain->rule.num != rule_num)
+           return (0);
+    }
+    else
+    {
+       if (strcmp (match->u.user.name, "comment") != 0)
+           return 0;
+       if ((chain->rule_type == RTYPE_COMMENT)
+               && (strcmp (chain->rule.comment, (char *) match->data) != 0))
+           return (0);
+    }
+
+    if (chain->name[0] != '\0')
+    {
+       status = snprintf (inst, sizeof (inst), "%s-%s,%s",
+               chain->table, chain->chain, chain->name);
+    }
+    else
+    {
+       if (chain->rule_type == RTYPE_NUM)
+           status = snprintf (inst, sizeof (inst), "%s-%s,%i",
+               chain->table, chain->chain, chain->rule.num);
+       else
+           status = snprintf (inst, sizeof (inst), "%s-%s,%s",
+               chain->table, chain->chain, match->data);
+
+       if ((status >= sizeof (inst)) || (status < 1))
+           return (0);
+    }
+
+    status = snprintf (value, sizeof (value), "%u:%lld",
+           (unsigned int) curtime,
+           entry->counters.bcnt);
+    if ((status >= sizeof (value)) || (status < 1))
+       return 0;
+    plugin_submit ("ipt_bytes", inst, value);
+
+    status = snprintf (value, sizeof (value), "%u:%lld",
+           (unsigned int) curtime,
+           entry->counters.pcnt);
+    if ((status >= sizeof (value)) || (status < 1))
+       return 0;
+    plugin_submit ("ipt_packets", inst, value);
+
+    return 0;
+} /* int submit_match */
+
+static void submit_chain( iptc_handle_t *handle, ip_chain_t *chain ) {
+    const struct ipt_entry *entry;
+    int rule_num;
+
+    /* Find first rule for chain and use the iterate macro */    
+    entry = iptc_first_rule( chain->chain, handle );
+    if (entry == NULL)
+    {
+       DBG ("iptc_first_rule failed: %s", iptc_strerror (errno));
+       return;
+    }
+
+    rule_num = 1;
+    while (entry)
+    {
+       if (chain->rule_type == RTYPE_NUM)
+       {
+           submit_match (NULL, entry, chain, rule_num);
+       }
+       else
+       {
+           IPT_MATCH_ITERATE( entry, submit_match, entry, chain, rule_num );
+       }
+
+       entry = iptc_next_rule( entry, handle );
+       rule_num++;
+    } /* while (entry) */
+}
+
+
+static void iptables_read (void)
+{
+    int i;
+    static complain_t complaint;
+
+    /* Init the iptc handle structure and query the correct table */    
+    for (i = 0; i < chain_num; i++)
+    {
+       iptc_handle_t handle;
+       ip_chain_t *chain;
+       
+       chain = chain_list[i];
+       if (!chain)
+       {
+           DBG ("chain == NULL");
+           continue;
+       }
+
+       handle = iptc_init( chain->table );
+       if (!handle)
+       {
+           DBG ("iptc_init (%s) failed: %s", chain->table, iptc_strerror (errno));
+           plugin_complain (LOG_ERR, &complaint, "iptc_init (%s) failed: %s",
+                   chain->table, iptc_strerror (errno));
+           continue;
+       }
+       plugin_relief (LOG_INFO, &complaint, "iptc_init (%s) succeeded",
+               chain->table);
+
+       submit_chain (&handle, chain);
+       iptc_free (&handle);
+    }
+}
+#else /* !IPTABLES_HAVE_READ */
+# define iptables_read NULL
+#endif
+
+void module_register (void)
+{
+    plugin_register ("ipt_bytes", NULL, NULL, iptables_write_bytes);
+    plugin_register ("ipt_packets", NULL, NULL, iptables_write_packets);
+#if IPTABLES_HAVE_READ
+    plugin_register (MODULE_NAME, NULL, iptables_read, NULL);
+    cf_register (MODULE_NAME, iptables_config, config_keys, config_keys_num);
+#endif
+}
+
+#undef BUFSIZE
+#undef MODULE_NAME
+
+/*
+ * vim:shiftwidth=4:softtabstop=4:tabstop=8
+ */
diff --git a/src/irq.c b/src/irq.c
new file mode 100644 (file)
index 0000000..69a3196
--- /dev/null
+++ b/src/irq.c
@@ -0,0 +1,238 @@
+/**
+ * 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/irq-%s.rrd";
+
+static char *config_keys[] =
+{
+       "Irq",
+       "IgnoreSelected",
+       NULL
+};
+static int config_keys_num = 2;
+
+static char *ds_def[] =
+{
+       "DS:value:COUNTER:"COLLECTD_HEARTBEAT":0:65535",
+       NULL
+};
+static int ds_num = 1;
+
+static unsigned int *irq_list;
+static unsigned int irq_list_num;
+
+/* 
+ * 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)
+{
+       if (strcasecmp (key, "Irq") == 0)
+       {
+               unsigned int *temp;
+               unsigned int irq;
+               char *endptr;
+
+               temp = (unsigned int *) realloc (irq_list, (irq_list_num + 1) * sizeof (unsigned int *));
+               if (temp == NULL)
+               {
+                       fprintf (stderr, "irq plugin: Cannot allocate more memory.\n");
+                       syslog (LOG_ERR, "irq plugin: Cannot allocate more memory.");
+                       return (1);
+               }
+               irq_list = temp;
+
+               /* Clear errno, because we need it to see if an error occured. */
+               errno = 0;
+
+               irq = strtol(value, &endptr, 10);
+               if ((endptr == value) || (errno != 0))
+               {
+                       fprintf (stderr, "irq plugin: Irq value is not a "
+                                       "number: `%s'\n", value);
+                       syslog (LOG_ERR, "irq plugin: Irq value is not a "
+                                       "number: `%s'", value);
+                       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 value_str[32];
+       char type_str[16];
+       int  status;
+
+       if (check_ignore_irq (irq))
+               return;
+
+       status = snprintf (value_str, 32, "%u:%u",
+                               (unsigned int) curtime, value);
+       if ((status >= 32) || (status < 1))
+               return;
+
+       status = snprintf (type_str, 16, "%u", irq);
+       if ((status >= 16) || (status < 1))
+               return;
+
+       plugin_submit (MODULE_NAME, type_str, value_str);
+} /* void irq_submit */
+
+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 *endptr;
+       int i;
+
+       char *fields[64];
+       int fields_num;
+
+       if ((fh = fopen ("/proc/interrupts", "r")) == NULL)
+       {
+               syslog (LOG_WARNING, "irq plugin: fopen (/proc/interrupts): %s",
+                               strerror (errno));
+               return;
+       }
+       while (fgets (buffer, BUFSIZE, fh) != NULL)
+       {
+               fields_num = strsplit (buffer, fields, 64);
+               if (fields_num < 2)
+                       continue;
+
+               errno = 0;    /* To distinguish success/failure after call */
+               irq = strtol (fields[0], &endptr, 10);
+
+               if ((endptr == fields[0]) || (errno != 0) || (*endptr != ':'))
+                       continue;
+
+               irq_value = 0;
+               for (i = 1; i < fields_num; i++)
+               {
+                       errno = 0;
+                       value = strtol (fields[i], &endptr, 10);
+
+                       if ((*endptr != '\0') || (errno != 0))
+                               break;
+
+                       irq_value += value;
+               } /* for (i) */
+
+               irq_submit (irq, irq_value);
+       }
+       fclose (fh);
+#endif /* KERNEL_LINUX */
+} /* void irq_read */
+#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