octo@leeloo:~/collectd $ svn merge -r773:777 branches/collectd-3.9 trunk
authorocto <octo>
Thu, 1 Jun 2006 20:53:20 +0000 (20:53 +0000)
committerocto <octo>
Thu, 1 Jun 2006 20:53:20 +0000 (20:53 +0000)
20 files changed:
AUTHORS
ChangeLog
collectd.spec
configure.in
contrib/README [new file with mode: 0644]
contrib/add_rra.sh [new file with mode: 0755]
contrib/collection.cgi
debian/changelog
src/Makefile.am
src/apache.c
src/apcups.c [new file with mode: 0644]
src/battery.c
src/collectd.c
src/collectd.conf.pod
src/collectd.pod
src/hddtemp.c
src/liboping/liboping.c
src/libping/ping.c [deleted file]
src/swap.c
src/traffic.c

diff --git a/AUTHORS b/AUTHORS
index 84e313d..7fbc743 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,6 +1,9 @@
 This package was written by:
   Florian octo Forster <octo at verplant.org>
 
+apcups plugin by:
+  Anthony Gialluca <tonyabg at charter.net>
+
 cpufreq module by:
   Peter Holik <peter at holik.at>
 
index 871acf0..5d421db 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+       * The `disk' plugin has been ported to Darwin.
+       * The `battery' plugin should work on many Apple computers now.
+       * The `traffic' plugin can now ignore certain interfaces. Also,
+         statistics for sent/received packets and errors have been added.
+
 2006-06-01, Version 3.9.3
        * Fixed the ping-plugin under FreeBSD and Mac OS X. Potentially other
          operating systems also profit from the changes, but I wasn't able to
          sequence checking the `ping' plugin stopped working after
          approximately 7.6 days.
 
+2006-05-09, Version 3.8.5
+       * Applied a patch to the `liboping' library. Due to a bug in the
+         sequence checking the `ping' plugin stopped working after
+         approximately 7.6 days.
+
 2006-04-21, Version 3.9.1
        * Build issues with Solaris and possible other architectures have been
          resolved.
@@ -17,7 +27,7 @@
          been resolved.
        * A bug in the `ping' plugin has been fixed. Sorry folks.
 
-2006-04-15, Version 3.9.0
+2006-04-02, Version 3.9.0
        * A plugin to monitor the Apache webserver has been added.
          <http://httpd.apache.org/>
        * A plugin to collect statistics about virtual servers using VServer.
index bcc1cd1..a08608d 100644 (file)
@@ -107,6 +107,9 @@ rm -rf $RPM_BUILD_ROOT
 * 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
 
index 3ac7fc5..592423b 100644 (file)
@@ -189,6 +189,10 @@ AC_CHECK_HEADERS(IOKit/ps/IOPowerSources.h, [], [],
 ])
 AC_CHECK_HEADERS(IOKit/ps/IOPSKeys.h)
 
+# For the `disk' plugin
+AC_CHECK_HEADERS(IOKit/IOBSD.h)
+AC_CHECK_HEADERS(IOKit/storage/IOBlockStorageDriver.h)
+
 # For load module
 AC_CHECK_HEADERS(sys/loadavg.h)
 
@@ -384,7 +388,7 @@ if test "x$fu_cv_getmntent2" = "xyes"; then
 fi
 
 # Check for structures
-AC_CHECK_MEMBERS([struct if_data.ifi_ibytes, struct if_data.ifi_obytes],
+AC_CHECK_MEMBERS([struct if_data.ifi_ibytes, struct if_data.ifi_opackets, struct if_data.ifi_ierrors],
        [AC_DEFINE(HAVE_STRUCT_IF_DATA, 1, [Define if struct if_data exists and is usable.])],
        [],
        [
@@ -392,7 +396,7 @@ AC_CHECK_MEMBERS([struct if_data.ifi_ibytes, struct if_data.ifi_obytes],
        #include <sys/socket.h>
        #include <net/if.h>
        ])
-AC_CHECK_MEMBERS([struct net_device_stats.rx_bytes, struct net_device_stats.tx_bytes],
+AC_CHECK_MEMBERS([struct net_device_stats.rx_bytes, struct net_device_stats.tx_packets, struct net_device_stats.rx_errors],
        [AC_DEFINE(HAVE_STRUCT_NET_DEVICE_STATS, 1, [Define if struct net_device_stats exists and is usable.])],
        [],
        [
@@ -598,6 +602,9 @@ AC_CHECK_LIB(IOKit, IOServiceGetMatchingServices,
 AC_DEFINE_UNQUOTED(COLLECT_LIBIOKIT, [$collect_libiokit], [Wether or not to use the IOKit library])
 AM_CONDITIONAL(BUILD_WITH_LIBIOKIT, test "x$with_libiokit" = "xyes")
 
+with_libstatgrab="yes"
+with_libdevstat="no"
+with_libkvm="no"
 AC_ARG_WITH(libstatgrab, [AS_HELP_STRING([--with-libstatgrab@<:@=PREFIX@:>@], [Path to libstatgrab.])],
 [
        if test "x$withval" != "xno" -a "x$withval" != "xyes"
@@ -617,9 +624,7 @@ AC_ARG_WITH(libstatgrab, [AS_HELP_STRING([--with-libstatgrab@<:@=PREFIX@:>@], [P
 ])
 if test "x$with_libstatgrab" = "xyes"
 then
-       AC_CHECK_LIB(devstat, getdevs)
-       AC_CHECK_LIB(kvm, kvm_getargv)
-       AC_CHECK_LIB(statgrab, sg_init,, [with_libstatgrab="no (libstatgrab not found)"])
+       AC_CHECK_LIB(statgrab, sg_init, [with_libstatgrab="yes"], [with_libstatgrab="no (libstatgrab not found)"])
 fi
 if test "x$with_libstatgrab" = "xyes"
 then
@@ -627,6 +632,11 @@ then
 fi
 if test "x$with_libstatgrab" = "xyes"
 then
+       AC_CHECK_LIB(devstat, getdevs, [with_libdevstat="yes"], [with_libdevstat="no"])
+       AC_CHECK_LIB(kvm, kvm_getargv, [with_libkvm="yes"],     [with_libkvm="no"])
+fi
+if test "x$with_libstatgrab" = "xyes"
+then
        collect_libstatgrab=1
 else
        collect_libstatgrab=0
@@ -634,6 +644,8 @@ fi
 AC_DEFINE_UNQUOTED(COLLECT_LIBSTATGRAB, [$collect_libstatgrab],
        [Wether or not to use statgrab library])
 AM_CONDITIONAL(BUILD_WITH_LIBSTATGRAB, test "x$with_libstatgrab" = "xyes")
+AM_CONDITIONAL(BUILD_WITH_LIBDEVSTAT,  test "x$with_libdevstat"  = "xyes")
+AM_CONDITIONAL(BUILD_WITH_LIBKVM,      test "x$with_libkvm"      = "xyes")
 
 AC_ARG_WITH(lm-sensors, [AS_HELP_STRING([--with-lm-sensors@<:@=PREFIX@:>@], [Path to lm_sensors.])],
 [
@@ -818,10 +830,12 @@ m4_divert_once([HELP_ENABLE], [
 collectd features:])
 AC_COLLECTD([debug],     [enable],  [feature], [debugging])
 AC_COLLECTD([daemon],    [disable], [feature], [daemon mode])
+AC_COLLECTD([getifaddrs],[enable],  [feature], [getifaddrs under Linux])
 
 m4_divert_once([HELP_ENABLE], [
 collectd modules:])
 AC_COLLECTD([apache],    [disable], [module], [Apache httpd statistics])
+AC_COLLECTD([apcups],    [disable], [module], [Statistics of UPSes by APC])
 AC_COLLECTD([apple_sensors], [disable], [module], [Apple's hardware sensors])
 AC_COLLECTD([battery],   [disable], [module], [battery statistics])
 AC_COLLECTD([cpu],       [disable], [module], [cpu usage statistics])
@@ -845,222 +859,6 @@ AC_COLLECTD([users],     [disable], [module], [user count statistics])
 AC_COLLECTD([vserver],   [disable], [module], [vserver statistics])
 AC_COLLECTD([wireless],  [disable], [module], [wireless link statistics])
 
-#m4_divert_once([HELP_ENABLE], [
-#collectd modules:])
-#AC_ARG_ENABLE(cpu, AC_HELP_STRING([--disable-cpu], [Disable CPU usage statistics]),, [enable_cpu="yes"])
-#if test "x$enable_cpu" != "xno"
-#then
-#      if test "x$ac_system" = "xLinux" -o "x$with_kstat" = "xyes" -o "x$have_sysctlbyname" = "xyes"
-#      then
-#              enable_cpu="yes"
-#      else
-#              enable_cpu="no"
-#      fi
-#fi
-#if test "x$enable_cpu" = "xno"
-#then
-#      AC_DEFINE(COLLECT_CPU, 0, [Wether or not to collect CPU usage statistics])
-#fi
-#AM_CONDITIONAL(BUILD_MODULE_CPU, test "x$enable_cpu" = "xyes")
-
-#AC_ARG_ENABLE(cpufreq, AC_HELP_STRING([--disable-cpufreq], [Disable system cpu frequency statistics]),, [enable_cpufreq="yes"])
-#if test "x$enable_cpufreq" != "xno"
-#then
-#      if test "x$ac_system" = "xLinux"
-#      then
-#              enable_cpufreq="yes"
-#      else
-#              enable_cpufreq="no"
-#      fi
-#fi
-#if test "x$enable_cpufreq" = "xno"
-#then
-#      AC_DEFINE(COLLECT_CPUFREQ, 0, [Wether or not to collect cpu frequency statistics])
-#fi
-#AM_CONDITIONAL(BUILD_MODULE_CPUFREQ, test "x$enable_cpufreq" = "xyes")
-
-#AC_ARG_ENABLE(disk, AC_HELP_STRING([--disable-disk], [Disable disk/partition statistics]),, [enable_disk="yes"])
-#if test "x$enable_disk" != "xno"
-#then
-#      if test "x$ac_system" = "xLinux" -o "x$with_kstat" = "xyes"
-#      then
-#              enable_disk="yes"
-#      else
-#              enable_disk="no"
-#      fi
-#fi
-#if test "x$enable_disk" = "xno"
-#then
-#      AC_DEFINE(COLLECT_DISK, 0, [Wether or not to collect diskstats])
-#fi
-#AM_CONDITIONAL(BUILD_MODULE_DISK, test "x$enable_disk" = "xyes")
-
-#AC_ARG_ENABLE(hddtemp, AC_HELP_STRING([--disable-hddtemp], [Disable hdd temperature statistics]),, [enable_hddtemp="yes"])
-#if test "x$enable_hddtemp" = "xno"
-#then
-#      AC_DEFINE(COLLECT_HDDTEMP, 0, [Wether or not to collect hdd temperature statistics])
-#fi
-#AM_CONDITIONAL(BUILD_MODULE_HDDTEMP, test "x$enable_hddtemp" = "xyes")
-
-#AC_ARG_ENABLE(load, AC_HELP_STRING([--disable-load], [Disable system load statistics]),, [enable_load="yes"])
-#if test "x$enable_load" != "xno"
-#then
-#      if test "x$have_getloadavg" = "xyes" -o "x$ac_system" = "xLinux" -o "x$with_libstatgrab" = "xyes"
-#      then
-#              enable_load="yes"
-#      else
-#              enable_load="no"
-#      fi
-#fi
-#if test "x$enable_load" = "xno"
-#then
-#      AC_DEFINE(COLLECT_LOAD, 0, [Wether or not to collect system load statistics])
-#fi
-#AM_CONDITIONAL(BUILD_MODULE_LOAD, test "x$enable_load" = "xyes")
-
-#AC_ARG_ENABLE(memory, AC_HELP_STRING([--disable-memory], [Disable memory statistics]),, [enable_memory="yes"])
-#if test "x$enable_memory" != "xno"
-#then
-#      if test "x$ac_system" = "xLinux" -o "x$with_kstat" = "xyes" -o "x$with_libstatgrab" = "xyes"
-#      then
-#              enable_memory="yes"
-#      else
-#              enable_memory="no"
-#      fi
-#fi
-#if test "x$enable_memory" = "xno"
-#then
-#      AC_DEFINE(COLLECT_MEMORY, 0, [Wether or not to collect memory statistics])
-#fi
-#AM_CONDITIONAL(BUILD_MODULE_MEMORY, test "x$enable_memory" = "xyes")
-
-#AC_ARG_ENABLE(nfs, AC_HELP_STRING([--disable-nfs], [Disable nfs statistics]),, [enable_nfs="yes"])
-#if test "x$enable_nfs" != "xno"
-#then
-#      if test "x$ac_system" = "xLinux"
-#      then
-#              enable_nfs="yes"
-#      else
-#              enable_nfs="no"
-#      fi
-#fi
-#if test "x$enable_nfs" = "xno"
-#then
-#      AC_DEFINE(COLLECT_NFS, 0, [Wether or not to collect nfs statistics])
-#fi
-#AM_CONDITIONAL(BUILD_MODULE_NFS, test "x$enable_nfs" = "xyes")
-
-#AC_ARG_ENABLE(ping, AC_HELP_STRING([--disable-ping], [Disable ping statistics]),, [enable_ping="yes"])
-#if test "x$enable_ping" != "xno"
-#then
-#      enable_ping="yes"
-#fi
-#if test "x$enable_ping" = "xno"
-#then
-#      AC_DEFINE(COLLECT_PING, 0, [Wether or not to collect ping statistics])
-#fi
-#AM_CONDITIONAL(BUILD_MODULE_PING, test "x$enable_ping" = "xyes")
-
-#AC_ARG_ENABLE(processes, AC_HELP_STRING([--disable-processes], [Disable processes statistics]),, [enable_processes="yes"])
-#if test "x$enable_processes" != "xno"
-#then
-#      if test "x$ac_system" = "xLinux" 
-#      then
-#              enable_processes="yes"
-#      else
-#              enable_processes="no"
-#      fi
-#fi
-#if test "x$enable_processes" = "xno"
-#then
-#      AC_DEFINE(COLLECT_PROCESSES, 0, [Wether or not to collect processes statistics])
-#fi
-#AM_CONDITIONAL(BUILD_MODULE_PROCESSES, test "x$enable_processes" = "xyes")
-
-##AC_COLLECTD([quota],     [enable],  [module], [quota statistics (experimental)])
-
-#AC_ARG_ENABLE(sensors, AC_HELP_STRING([--disable-sensors], [Disable lm_sensors statistics]),, [enable_sensors=$with_lm_sensors])
-#if test "x$enable_sensors" != "xno"
-#then
-#      if test "x$with_lm_sensors" = "xyes"
-#      then
-#              enable_sensors="yes"
-#      else
-#              enable_sensors="no"
-#      fi
-#fi
-#if test "x$enable_sensors" = "xno"
-#then
-#      AC_DEFINE(COLLECT_SENSORS, 0, [Wether or not to collect lm_sensors statistics])
-#fi
-#AM_CONDITIONAL(BUILD_MODULE_SENSORS, test "x$enable_sensors" = "xyes")
-
-#AC_ARG_ENABLE(serial, AC_HELP_STRING([--disable-serial], [Disable serial statistics]),, [enable_serial="yes"])
-#if test "x$enable_serial" != "xno"
-#then
-#      if test "x$ac_system" = "xLinux"
-#      then
-#              enable_serial="yes"
-#      else
-#              enable_serial="no"
-#      fi
-#fi
-#if test "x$enable_serial" = "xno"
-#then
-#      AC_DEFINE(COLLECT_SERIAL, 0, [Wether or not to collect serial statistics])
-#fi
-#AM_CONDITIONAL(BUILD_MODULE_SERIAL, test "x$enable_serial" = "xyes")
-
-#AC_ARG_ENABLE(swap, AC_HELP_STRING([--disable-swap], [Disable swap statistics]),, [enable_swap="yes"])
-#if test "x$enable_swap" != "xno"
-#then
-#      if test "x$ac_system" = "xLinux" -o "x$with_kstat" = "xyes" -o "x$with_libstatgrab" = "xyes"
-#      then
-#              enable_swap="yes"
-#      else
-#              enable_swap="no"
-#      fi
-#fi
-#if test "x$enable_swap" = "xno"
-#then
-#      AC_DEFINE(COLLECT_SWAP, 0, [Wether or not to collect swap statistics])
-#fi
-#AM_CONDITIONAL(BUILD_MODULE_SWAP, test "x$enable_swap" = "xyes")
-
-#AC_ARG_ENABLE(tape, AC_HELP_STRING([--disable-tape], [Disable tape statistics]),, [enable_tape="yes"])
-#if test "x$enable_tape" != "xno"
-#then
-#      if test "x$with_kstat" = "xyes"
-#      then
-#              enable_tape="yes"
-#      else
-#              enable_tape="no"
-#      fi
-#fi
-#if test "x$enable_tape" = "xno"
-#then
-#      AC_DEFINE(COLLECT_TAPE, 0, [Wether or not to collect tape statistics])
-#fi
-#AM_CONDITIONAL(BUILD_MODULE_TAPE, test "x$enable_tape" = "xyes")
-
-#AC_ARG_ENABLE(traffic, AC_HELP_STRING([--disable-traffic], [Disable system traffic statistics]),, [enable_traffic="yes"])
-#if test "x$enable_traffic" != "xno"
-#then
-#      if test "x$ac_system" = "xLinux" -o "x$with_kstat" = "xyes" -o "x$with_libstatgrab" = "xyes"
-#      then
-#              enable_traffic="yes"
-#      else
-#              enable_traffic="no"
-#      fi
-#fi
-#if test "x$enable_traffic" = "xno"
-#then
-#      AC_DEFINE(COLLECT_TRAFFIC, 0, [Wether or not to collect network traffic statistics])
-#fi
-#AM_CONDITIONAL(BUILD_MODULE_TRAFFIC, test "x$enable_traffic" = "xyes")
-
-#AC_COLLECTD([users],     [disable], [module], [user count statistics])
-
 AC_OUTPUT(Makefile src/libconfig/Makefile src/liboping/Makefile src/Makefile)
 
 cat <<EOF;
@@ -1083,6 +881,7 @@ Configuration:
 
   Modules:
     apache  . . . . . . $enable_apache
+    apcups  . . . . . . $enable_apcups
     apple_sensors . . . $enable_apple_sensors
     battery . . . . . . $enable_battery
     cpu . . . . . . . . $enable_cpu
diff --git a/contrib/README b/contrib/README
new file mode 100644 (file)
index 0000000..7f21040
--- /dev/null
@@ -0,0 +1,31 @@
+The files in this directory may be used to perform common tasks that aren't
+exactly `collectd's job. They may or may not require in-depth knowlege of RRD
+files and/or `collectd's inner workings. Use at your own risk.
+
+add_rra.sh
+----------
+  Before version 3.9.0 collectd used to create a different set of RRAs. The
+most detailed of these old RRAs hat a one minute resolution. This script can be
+used to add three more RRAs: minimum, maximum and average with a ten second
+resolution and 2200 rows (~6 hours). This will make houly statistics much more
+interesting. Please note that no sanity- checking whatsoever is performed. You
+can seriously fuck up your RRD files if you don't know what you're doing.
+
+collectd2html.pl
+----------------
+  This script by Vincent Stehlé will search for RRD files in
+`/var/lib/collectd/' and generate an HTML file and a directory containing
+several PNG files which are graphs of the RRD files found.
+
+collectd.conf
+-------------
+  A sample config file. Used by the Debian package.
+
+collection.cgi
+--------------
+  Sample CGI script that creates graphs on the fly. The Perl module `RRDs' is
+needed (Debian package `librrds-perl').
+
+init.d-rh7
+----------
+  Sample init script. Used by the RPM specfile.
diff --git a/contrib/add_rra.sh b/contrib/add_rra.sh
new file mode 100755 (executable)
index 0000000..c9306b0
--- /dev/null
@@ -0,0 +1,67 @@
+#!/bin/bash
+
+INPUT=$1
+OUTPUT=$2
+
+if [ -z "$INPUT" -o -z "$OUTPUT" ]
+then
+       cat <<USAGE
+Usage: $0 <input> <output>
+USAGE
+       exit 1
+fi
+
+if [ ! -e "$INPUT" ]
+then
+       echo "No such file: $INPUT"
+       exit 1
+fi
+
+if [ -e "$OUTPUT" ]
+then
+       echo "File exists: $OUTPUT"
+       exit 1
+fi
+
+NUM_DS=0
+rrdtool dump "$INPUT" | while read LINE
+do
+       echo "$LINE"
+
+       if [ "$LINE" = "<ds>" ]
+       then
+               NUM_DS=$(($NUM_DS + 1))
+       fi
+       
+       if [ "$LINE" = "<!-- Round Robin Archives -->" ]
+       then
+               for CF in MIN MAX AVERAGE
+               do
+                       cat <<RRA
+       <rra>
+               <cf> $CF </cf>
+               <pdp_per_row> 1 </pdp_per_row>
+               <xff> 0.0000000000e+00 </xff>
+
+               <cdp_prep>
+RRA
+                       for ((i=0; i < $NUM_DS; i++))
+                       do
+                               echo "                  <ds><value> NaN </value>  <unknown_datapoints> 1 </unknown_datapoints></ds>"
+                       done
+                       echo "          </cdp_prep>"
+                       echo "          <database>"
+
+                       DS_VALUES=`for ((i=0; i < $NUM_DS; i++)); do echo -n "<v> NaN </v>"; done`
+                       for ((i=0; i < 2200; i++))
+                       do
+                               echo "                  <!-- $i --> <row>$DS_VALUES</row>"
+                       done
+                       echo "          </database>"
+                       echo "  </rra>"
+               done
+       fi
+done >"$OUTPUT.xml"
+
+rrdtool restore "$OUTPUT.xml" "$OUTPUT" -r >/dev/null
+rm -f "$OUTPUT.xml"
index 54cde20..a398286 100755 (executable)
@@ -235,6 +235,18 @@ our $GraphDefs;
                        'GPRINT:total_max_ms:MAX:%5.1lf%s Max,',
                        'GPRINT:total_avg_ms:LAST:%5.1lf%s Last'
                ],
+               fanspeed => [
+                       'DEF:temp_avg={file}:value:AVERAGE',
+                       'DEF:temp_min={file}:value:MIN',
+                       'DEF:temp_max={file}:value:MAX',
+                       "AREA:temp_max#$HalfBlue",
+                       "AREA:temp_min#$Canvas",
+                       "LINE1:temp_avg#$FullBlue:RPM",
+                       'GPRINT:temp_min:MIN:%4.1lf Min,',
+                       'GPRINT:temp_avg:AVERAGE:%4.1lf Avg,',
+                       'GPRINT:temp_max:MAX:%4.1lf Max,',
+                       'GPRINT:temp_avg:LAST:%4.1lf Last\l'
+               ],
                hddtemp => [
                        'DEF:temp_avg={file}:value:AVERAGE',
                        'DEF:temp_min={file}:value:MIN',
@@ -635,18 +647,6 @@ our $GraphDefs;
                        'GPRINT:sleeping_max:MAX:%5.1lf Max,',
                        'GPRINT:sleeping_avg:LAST:%5.1lf Last\l'
                ],
-               sensors => [
-                       'DEF:temp_avg={file}:value:AVERAGE',
-                       'DEF:temp_min={file}:value:MIN',
-                       'DEF:temp_max={file}:value:MAX',
-                       "AREA:temp_max#$HalfBlue",
-                       "AREA:temp_min#$Canvas",
-                       "LINE1:temp_avg#$FullBlue:Value",
-                       'GPRINT:temp_min:MIN:%4.1lf Min,',
-                       'GPRINT:temp_avg:AVERAGE:%4.1lf Avg,',
-                       'GPRINT:temp_max:MAX:%4.1lf Max,',
-                       'GPRINT:temp_avg:LAST:%4.1lf Last\l'
-               ],
                swap => [
                        'DEF:used_avg={file}:used:AVERAGE',
                        'DEF:used_min={file}:used:MIN',
@@ -691,6 +691,18 @@ our $GraphDefs;
                        'GPRINT:used_max:MAX:%5.1lf%s Max,',
                        'GPRINT:used_avg:LAST:%5.1lf%s Last\l'
                ],
+               temperature => [
+                       'DEF:temp_avg={file}:value:AVERAGE',
+                       'DEF:temp_min={file}:value:MIN',
+                       'DEF:temp_max={file}:value:MAX',
+                       "AREA:temp_max#$HalfBlue",
+                       "AREA:temp_min#$Canvas",
+                       "LINE1:temp_avg#$FullBlue:Value",
+                       'GPRINT:temp_min:MIN:%4.1lf Min,',
+                       'GPRINT:temp_avg:AVERAGE:%4.1lf Avg,',
+                       'GPRINT:temp_max:MAX:%4.1lf Max,',
+                       'GPRINT:temp_avg:LAST:%4.1lf Last\l'
+               ],
                traffic => ['DEF:out_min_raw={file}:outgoing:MIN',
                        'DEF:out_avg_raw={file}:outgoing:AVERAGE',
                        'DEF:out_max_raw={file}:outgoing:MAX',
@@ -762,7 +774,7 @@ our $GraphDefs;
                        'GPRINT:max:MAX:%5.1lf%sV Max,',
                        'GPRINT:avg:LAST:%5.1lf%sV Last\l'
                ],
-               threads => [
+               vs_threads => [
                        "DEF:total_avg={file}:total:AVERAGE",
                        "DEF:total_min={file}:total:MIN",
                        "DEF:total_max={file}:total:MAX",
@@ -845,6 +857,7 @@ our $GraphDefs;
        };
        $GraphDefs->{'disk'} = $GraphDefs->{'partition'};
        $GraphDefs->{'meminfo'} = $GraphDefs->{'memory'};
+       $GraphDefs->{'sensors'} = $GraphDefs->{'temperature'};
 }
 
 our $GraphArgs =
@@ -859,6 +872,7 @@ our $GraphArgs =
        #disk => ['-t', '{host} disk {inst} IO wait', '-v', 'Seconds'],
        df => ['-t', '{host}:{inst} usage', '-v', 'Percent', '-l', '0'],
        disk => ['-t', '{host} disk {inst} usage', '-v', 'Byte/s'],
+       fanspeed => ['-t', '{host} fanspeed {inst}', '-v', 'rpm'],
        hddtemp => ['-t', '{host} hdd temperature {inst}', '-v', '°Celsius'],
        load => ['-t', '{host} load average', '-v', 'System load', '-X', '0'],
        mails   => ['-t', '{host} mail count', '-v', 'Amount', '-X', '0'],
@@ -873,10 +887,11 @@ our $GraphArgs =
        processes => ['-t', '{host} processes', '-v', 'Processes'],
        sensors => ['-t', '{host} sensor {inst}', '-v', '°Celsius'],
        swap => ['-t', '{host} swap usage', '-v', 'Bytes', '-b', '1024', '-l', '0'],
+       temperature => ['-t', '{host} temperature {inst}', '-v', '°Celsius'],
        traffic => ['-t', '{host} {inst} traffic', '-v', 'Bit/s'],
        users => ['-t', '{host} users', '-v', 'Users'],
        voltage => ['-t', '{host} voltage', '-v', 'Volts'],
-       threads => ['-t', '{host} threads', '-v', 'Threads'],
+       vs_threads => ['-t', '{host} threads', '-v', 'Threads'],
        vs_memory => ['-t', '{host} memory usage', '-v', 'Bytes'],
        vs_processes => ['-t', '{host} processes', '-v', 'Processes'],
 };
index eb2e4bd..9ea2758 100644 (file)
@@ -10,6 +10,12 @@ collectd (3.9.2-1) unstable; urgency=low
 
  -- Florian Forster <octo@verplant.org>  Tue,  9 May 2006 11:12:00 +0200
 
+collectd (3.8.5-1) unstable; urgency=low
+
+  * New upstream version
+
+ -- Florian Forster <octo@verplant.org>  Tue,  9 May 2006 10:56:00 +0200
+
 collectd (3.9.1-1) unstable; urgency=low
 
   * New upstream version
index 9cafbbf..5646a06 100644 (file)
@@ -48,6 +48,17 @@ if BUILD_WITH_LIBDEVINFO
 collectd_LDFLAGS += -ldevinfo
 endif
 
+if BUILD_WITH_LIBSTATGRAB
+if BUILD_WITH_LIBKVM
+collectd_LDFLAGS += -lkvm
+endif
+if BUILD_WITH_LIBDEVSTAT
+collectd_LDFLAGS += -ldevstat
+endif
+collectd_LDFLAGS += -lstatgrab
+endif
+
+
 collectd_LDADD = $(LIBLTDL) libconfig/libconfig.la "-dlopen" self
 collectd_DEPENDENCIES = $(LIBLTDL) libconfig/libconfig.la
 
@@ -64,6 +75,17 @@ collectd_LDADD += "-dlopen" apache.la
 collectd_DEPENDENCIES += apache.la
 endif
 
+if BUILD_MODULE_APCUPS
+pkglib_LTLIBRARIES += apcups.la
+apcups_la_SOURCES = apcups.c
+apcups_la_LDFLAGS = -module -avoid-version
+if BUILD_WITH_LIBSOCKET
+apcups_la_LDFLAGS += -lsocket
+endif
+collectd_LDADD += "-dlopen" apcups.la
+collectd_DEPENDENCIES += apcups.la
+endif
+
 if BUILD_MODULE_APPLE_SENSORS
 pkglib_LTLIBRARIES += apple_sensors.la
 apple_sensors_la_SOURCES = apple_sensors.c
@@ -126,6 +148,9 @@ endif
 if BUILD_WITH_LIBDEVINFO
 disk_la_LDFLAGS += -ldevinfo
 endif
+if BUILD_WITH_LIBIOKIT
+disk_la_LDFLAGS += -lIOKit
+endif
 collectd_LDADD += "-dlopen" disk.la
 collectd_DEPENDENCIES += disk.la
 endif
@@ -158,20 +183,38 @@ load_la_SOURCES = load.c
 load_la_LDFLAGS = -module -avoid-version
 collectd_LDADD += "-dlopen" load.la
 collectd_DEPENDENCIES += load.la
+if BUILD_WITH_LIBSTATGRAB
+if BUILD_WITH_LIBKVM
+load_la_LDFLAGS += -lkvm
+endif
+if BUILD_WITH_LIBDEVSTAT
+load_la_LDFLAGS += -ldevstat
+endif
+load_la_LDFLAGS += -lstatgrab
+endif
 endif
 
 if BUILD_MODULE_MEMORY
 pkglib_LTLIBRARIES += memory.la
 memory_la_SOURCES = memory.c
 memory_la_LDFLAGS = -module -avoid-version
+collectd_LDADD += "-dlopen" memory.la
+collectd_DEPENDENCIES += memory.la
 if BUILD_WITH_LIBKSTAT
 memory_la_LDFLAGS += -lkstat
 endif
 if BUILD_WITH_LIBDEVINFO
 memory_la_LDFLAGS += -ldevinfo
 endif
-collectd_LDADD += "-dlopen" memory.la
-collectd_DEPENDENCIES += memory.la
+if BUILD_WITH_LIBSTATGRAB
+if BUILD_WITH_LIBKVM
+memory_la_LDFLAGS += -lkvm
+endif
+if BUILD_WITH_LIBDEVSTAT
+memory_la_LDFLAGS += -ldevstat
+endif
+memory_la_LDFLAGS += -lstatgrab
+endif
 endif
 
 if BUILD_MODULE_MYSQL
@@ -234,14 +277,23 @@ if BUILD_MODULE_SWAP
 pkglib_LTLIBRARIES += swap.la
 swap_la_SOURCES = swap.c
 swap_la_LDFLAGS = -module -avoid-version
+collectd_LDADD += "-dlopen" swap.la
+collectd_DEPENDENCIES += swap.la
 if BUILD_WITH_LIBKSTAT
 swap_la_LDFLAGS += -lkstat
 endif
 if BUILD_WITH_LIBDEVINFO
 swap_la_LDFLAGS += -ldevinfo
 endif
-collectd_LDADD += "-dlopen" swap.la
-collectd_DEPENDENCIES += swap.la
+if BUILD_WITH_LIBSTATGRAB
+if BUILD_WITH_LIBKVM
+swap_la_LDFLAGS += -lkvm
+endif
+if BUILD_WITH_LIBDEVSTAT
+swap_la_LDFLAGS += -ldevstat
+endif
+swap_la_LDFLAGS += -lstatgrab
+endif
 endif
 
 if BUILD_MODULE_TAPE
@@ -262,14 +314,23 @@ if BUILD_MODULE_TRAFFIC
 pkglib_LTLIBRARIES += traffic.la
 traffic_la_SOURCES = traffic.c
 traffic_la_LDFLAGS = -module -avoid-version
+collectd_LDADD += "-dlopen" traffic.la
+collectd_DEPENDENCIES += traffic.la
 if BUILD_WITH_LIBKSTAT
 traffic_la_LDFLAGS += -lkstat
 endif
 if BUILD_WITH_LIBDEVINFO
 traffic_la_LDFLAGS += -ldevinfo
 endif
-collectd_LDADD += "-dlopen" traffic.la
-collectd_DEPENDENCIES += traffic.la
+if BUILD_WITH_LIBSTATGRAB
+if BUILD_WITH_LIBKVM
+traffic_la_LDFLAGS += -lkvm
+endif
+if BUILD_WITH_LIBDEVSTAT
+traffic_la_LDFLAGS += -ldevstat
+endif
+traffic_la_LDFLAGS += -lstatgrab
+endif
 endif
 
 if BUILD_MODULE_USERS
index c731908..156ad5d 100644 (file)
 #  define APACHE_HAVE_READ 0
 #endif
 
-static char *url  = NULL;
-static char *user = NULL;
-static char *pass = NULL;
+static char *url    = NULL;
+static char *user   = NULL;
+static char *pass   = NULL;
+static char *cacert = NULL;
 
 #if HAVE_LIBCURL
 static CURL *curl = NULL;
@@ -78,9 +79,10 @@ static char *config_keys[] =
        "URL",
        "User",
        "Password",
+       "CACert",
        NULL
 };
-static int config_keys_num = 3;
+static int config_keys_num = 4;
 
 #if HAVE_LIBCURL
 static size_t apache_curl_callback (void *buf, size_t size, size_t nmemb, void *stream)
@@ -125,6 +127,8 @@ static int config (char *key, char *value)
                return (config_set (&user, value));
        else if (strcasecmp (key, "password") == 0)
                return (config_set (&pass, value));
+       else if (strcasecmp (key, "cacert") == 0)
+               return (config_set (&cacert, value));
        else
                return (-1);
 }
@@ -164,6 +168,11 @@ static void init (void)
        {
                curl_easy_setopt (curl, CURLOPT_URL, url);
        }
+
+       if (cacert != NULL)
+       {
+               curl_easy_setopt (curl, CURLOPT_CAINFO, cacert);
+       }
 #endif /* HAVE_LIBCURL */
 }
 
@@ -275,6 +284,7 @@ static void apache_read (void)
        if (url == NULL)
                return;
 
+       apache_buffer_len = 0;
        if (curl_easy_perform (curl) != 0)
        {
                syslog (LOG_WARNING, "apache: curl_easy_perform failed: %s", apache_curl_error);
diff --git a/src/apcups.c b/src/apcups.c
new file mode 100644 (file)
index 0000000..049383d
--- /dev/null
@@ -0,0 +1,736 @@
+/*
+ * collectd - src/apcups.c
+ * Copyright (C) 2006 Anthony Gialluca <tonyabg at charter.net>
+ * Copyright (C) 2000-2004 Kern Sibbald
+ * Copyright (C) 1996-99 Andre M. Hedrick <andre at suse.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General
+ * Public License as published by the Free Software Foundation.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ *
+ * Authors:
+ *   Anthony Gialluca <tonyabg at charter.net>
+ **/
+
+#include "collectd.h"
+#include "common.h" /* rrd_update_file */
+#include "plugin.h" /* plugin_register, plugin_submit */
+#include "configfile.h" /* cf_register */
+
+/* FIXME: Check defines before including anything! */
+#include <stdarg.h>
+#include <unistd.h>
+#include <string.h>
+#include <strings.h>
+#include <signal.h>
+#include <ctype.h>
+#include <syslog.h>
+#include <limits.h>
+#include <pwd.h>
+#include <time.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <setjmp.h>
+#include <termios.h>
+#include <netdb.h>
+#include <sys/ioctl.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>
+#include <sys/shm.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+#include <sys/wait.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#define NISPORT 3551
+#define _(String) (String)
+#define N_(String) (String)
+#define MAXSTRING               256
+#define MODULE_NAME "apcups"
+
+
+/* Prototypes */
+static void generic_error_out(const char *, int , const char *, ...);
+
+/* Default values for contacting daemon */
+static char *host = "localhost";
+static int port = NISPORT;
+
+static struct sockaddr_in tcp_serv_addr;  /* socket information */
+static char *net_errmsg = NULL;           /* pointer to error message */
+static char net_errbuf[256];              /* error message buffer for messages */
+
+/* 
+ * The following are only if not compiled to test the module with its own main.
+*/
+/* FIXME: Rename DSes to be more generic and follow established conventions. */
+#ifndef APCMAIN
+static char *volt_file_template = "apcups_volt-%s.rrd";
+static char *volt_ds_def[] = 
+{
+       "DS:linev:GAUGE:"COLLECTD_HEARTBEAT":0:250",
+       "DS:outputv:GAUGE:"COLLECTD_HEARTBEAT":0:250",
+       NULL
+};
+static int volt_ds_num = 2;
+
+static char *bvolt_file_template = "apcups_bvolt-%s.rrd";
+static char *bvolt_ds_def[] = 
+{
+       "DS:battv:GAUGE:"COLLECTD_HEARTBEAT":0:100",
+};
+static int bvolt_ds_num = 1;
+
+static char *load_file_template = "apcups_load-%s.rrd";
+static char *load_ds_def[] = 
+{
+       "DS:loadpct:GAUGE:"COLLECTD_HEARTBEAT":0:120",
+};
+static int load_ds_num = 1;
+
+static char *charge_file_template = "apcups_charge-%s.rrd";
+static char *charge_ds_def[] = 
+{
+       "DS:bcharge:GAUGE:"COLLECTD_HEARTBEAT":0:100",
+};
+static int charge_ds_num = 1;
+
+static char *time_file_template = "apcups_time-%s.rrd";
+static char *time_ds_def[] = 
+{
+       "DS:timeleft:GAUGE:"COLLECTD_HEARTBEAT":0:100",
+};
+static int time_ds_num = 1;
+
+static char *temp_file_template = "apcups_temp-%s.rrd";
+static char *temp_ds_def[] = 
+{
+       "DS:itemp:GAUGE:"COLLECTD_HEARTBEAT":0:100",
+};
+static int temp_ds_num = 1;
+
+static char *freq_file_template = "apcups_freq-%s.rrd";
+static char *freq_ds_def[] = 
+{
+       "DS:linefreq:GAUGE:"COLLECTD_HEARTBEAT":0:65",
+};
+static int freq_ds_num = 1;
+
+static char *config_keys[] =
+{
+       "Host",
+       "Port",
+       NULL
+};
+static int config_keys_num = 2;
+
+#endif /* ifndef APCMAIN */
+
+struct apc_detail_s
+{
+       float linev;
+       float loadpct;
+       float bcharge;
+       float timeleft;
+       float outputv;
+       float itemp;
+       float battv;
+       float linefreq;
+};
+
+#define BIG_BUF 4096
+
+/*
+ * Subroutine normally called by macro error_abort() to print
+ * FATAL ERROR message and supplied error message
+ */
+static void generic_error_out(const char *file, int line, const char *fmt, ...)
+{
+       char buf[256];
+       va_list arg_ptr;
+       int i;
+
+       snprintf(buf, sizeof(buf), _("FATAL ERROR in %s at line %d\n"), file, line);
+       i = strlen(buf);
+       va_start(arg_ptr, fmt);
+       vsnprintf((char *)&buf[i], sizeof(buf) - i, (char *)fmt, arg_ptr);
+       va_end(arg_ptr);
+       fprintf(stdout, "%s", buf);
+
+       exit(1);
+}
+
+/*
+ * Read nbytes from the network.
+ * It is possible that the total bytes require in several
+ * read requests
+ */
+static int read_nbytes(int fd, char *ptr, int nbytes)
+{
+       int nleft, nread;
+
+       nleft = nbytes;
+
+       while (nleft > 0) {
+               do {
+                       nread = read(fd, ptr, nleft);
+               } while (nread == -1 && (errno == EINTR || errno == EAGAIN));
+
+               if (nread <= 0) {
+                       return (nread);           /* error, or EOF */
+               }
+
+               nleft -= nread;
+               ptr += nread;
+       }
+
+       return (nbytes - nleft);        /* return >= 0 */
+}
+
+/*
+ * Write nbytes to the network.
+ * It may require several writes.
+ */
+static int write_nbytes(int fd, void *buf, int buflen)
+{
+       int nleft;
+       int nwritten;
+       char *ptr;
+
+       ptr = (char *) buf;
+
+       nleft = buflen;
+       while (nleft > 0)
+       {
+               nwritten = write(fd, ptr, nleft);
+
+               if (nwritten <= 0)
+               {
+                       syslog (LOG_ERR, "Writing to socket failed: %s", strerror (errno));
+                       return (nwritten);
+               }
+
+               nleft -= nwritten;
+               ptr += nwritten;
+       }
+
+       /* If we get here, (nleft <= 0) is true */
+       return (buflen);
+}
+
+/* Close the network connection */
+static void net_close (int sockfd)
+{
+       short pktsiz = 0;
+
+       /* send EOF sentinel */
+       write_nbytes (sockfd, &pktsiz, sizeof(short));
+       close (sockfd);
+}
+
+
+/*     
+ * Open a TCP connection to the UPS network server
+ * Returns -1 on error
+ * Returns socket file descriptor otherwise
+ */
+static int net_open(char *host, char *service, int port)
+{
+       int sockfd;
+       struct hostent *hp;
+       unsigned int inaddr; /* Careful here to use unsigned int for */
+                            /* compatibility with Alpha */
+
+       /* 
+        * Fill in the structure serv_addr with the address of the server that
+        * we want to connect with.
+        */
+       memset((char *)&tcp_serv_addr, 0, sizeof(tcp_serv_addr));
+       tcp_serv_addr.sin_family = AF_INET;
+       tcp_serv_addr.sin_port = htons(port);
+
+       if ((inaddr = inet_addr(host)) != INADDR_NONE) {
+               tcp_serv_addr.sin_addr.s_addr = inaddr;
+       } else {
+               if ((hp = gethostbyname(host)) == NULL) {
+                       net_errmsg = "tcp_open: hostname error\n";
+                       return -1;
+               }
+
+               if (hp->h_length != sizeof(inaddr) || hp->h_addrtype != AF_INET) {
+                       net_errmsg = "tcp_open: funny gethostbyname value\n";
+                       return -1;
+               }
+
+               tcp_serv_addr.sin_addr.s_addr = *(unsigned int *)hp->h_addr;
+       }
+
+       /* Open a TCP socket */
+       if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+               net_errmsg = "tcp_open: cannot open stream socket\n";
+               return -1;
+       }
+
+       /* connect to server */
+#if defined HAVE_OPENBSD_OS || defined HAVE_FREEBSD_OS
+       /* 
+        * Work around a bug in OpenBSD & FreeBSD userspace pthreads
+        * implementations. Rationale is the same as described above.
+        */
+       fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL));
+#endif
+
+       if (connect(sockfd, (struct sockaddr *)&tcp_serv_addr, sizeof(tcp_serv_addr)) < 0) {
+               snprintf(net_errbuf, sizeof(net_errbuf),
+                               _("tcp_open: cannot connect to server %s on port %d.\n"
+                                       "ERR=%s\n"), host, port, strerror(errno));
+               net_errmsg = net_errbuf;
+               close(sockfd);
+               return -1;
+       }
+
+       return sockfd;
+} /* int net_open(char *host, char *service, int port) */
+
+/* 
+ * Receive a message from the other end. Each message consists of
+ * two packets. The first is a header that contains the size
+ * of the data that follows in the second packet.
+ * Returns number of bytes read
+ * Returns 0 on end of file
+ * Returns -1 on hard end of file (i.e. network connection close)
+ * Returns -2 on error
+ */
+static int net_recv(int sockfd, char *buff, int maxlen)
+{
+       int nbytes;
+       short pktsiz;
+
+       /* get data size -- in short */
+       if ((nbytes = read_nbytes(sockfd, (char *)&pktsiz, sizeof(short))) <= 0) {
+               /* probably pipe broken because client died */
+               return -1;                   /* assume hard EOF received */
+       }
+       if (nbytes != sizeof(short))
+               return -2;
+
+       pktsiz = ntohs(pktsiz);         /* decode no. of bytes that follow */
+       if (pktsiz > maxlen) {
+               net_errmsg = "net_recv: record length too large\n";
+               return -2;
+       }
+       if (pktsiz == 0)
+               return 0;                    /* soft EOF */
+
+       /* now read the actual data */
+       if ((nbytes = read_nbytes(sockfd, buff, pktsiz)) <= 0) {
+               net_errmsg = "net_recv: read_nbytes error\n";
+               return -2;
+       }
+       if (nbytes != pktsiz) {
+               net_errmsg = "net_recv: error in read_nbytes\n";
+               return -2;
+       }
+
+       return (nbytes);                /* return actual length of message */
+}
+
+/*
+ * Send a message over the network. The send consists of
+ * two network packets. The first is sends a short containing
+ * the length of the data packet which follows.
+ * Returns zero on success
+ * Returns non-zero on error
+ */
+static int net_send(int sockfd, char *buff, int len)
+{
+       int rc;
+       short packet_size;
+
+       /* send short containing size of data packet */
+       packet_size = htons ((short) len);
+
+       rc = write_nbytes(sockfd, &packet_size, sizeof (packet_size));
+       if (rc != sizeof(packet_size))
+               return (-1);
+
+       /* send data packet */
+       rc = write_nbytes (sockfd, buff, len);
+       if (rc != len)
+               return (-1);
+
+       return (0);
+}
+
+/* Get and print status from apcupsd NIS server */
+static int do_pthreads_status(char *host, int port, struct apc_detail_s *apcups_detail)
+{
+       int     sockfd;
+       int     n;
+       char    recvline[MAXSTRING + 1];
+       char   *tokptr;
+       char   *key;
+       double  value;
+#if APCMAIN
+# define PRINT_VALUE(name, val) printf("  Found property: name = %s; value = %f;\n", name, val)
+#else
+# define PRINT_VALUE(name, val) /**/
+#endif
+
+       /* TODO: Keep the socket open, if possible */
+       if ((sockfd = net_open (host, NULL, port)) < 0)
+       {
+               syslog (LOG_ERR, "apcups plugin: Connecting to the apcupsd failed.");
+               return (-1);
+       }
+
+       net_send (sockfd, "status", 6);
+
+       while ((n = net_recv (sockfd, recvline, sizeof (recvline))) > 0)
+       {
+               recvline[n] = '\0';
+#if APCMAIN
+               printf ("net_recv = `%s';\n", recvline);
+#endif /* if APCMAIN */
+
+               tokptr = strtok (recvline, ":");
+               while (tokptr != NULL)
+               {
+                       key = tokptr;
+                       if ((tokptr = strtok (NULL, " \t")) == NULL)
+                               continue;
+                       value = atof (tokptr);
+                       PRINT_VALUE (key, value);
+
+                       if (strcmp ("LINEV", key) == 0)
+                               apcups_detail->linev = value;
+                       else if (strcmp ("BATTV", tokptr) == 0)
+                               apcups_detail->battv = value;
+                       else if (strcmp ("ITEMP", tokptr) == 0)
+                               apcups_detail->itemp = value;
+                       else if (strcmp ("LOADPCT", tokptr) == 0)
+                               apcups_detail->loadpct = value;
+                       else if (strcmp ("BCHARGE", tokptr) == 0)
+                               apcups_detail->bcharge = value;
+                       else if (strcmp ("OUTPUTV", tokptr) == 0)
+                               apcups_detail->outputv = value;
+                       else if (strcmp ("LINEFREQ", tokptr) == 0)
+                               apcups_detail->linefreq = value;
+                       else if (strcmp ("TIMELEFT", tokptr) == 0)
+                               apcups_detail->timeleft = value;
+                       else
+                       {
+                               syslog (LOG_WARNING, "apcups plugin: Received unknown property from apcupsd: `%s' = %f",
+                                               key, value);
+                       }
+
+                       tokptr = strtok (NULL, ":");
+               } /* while (tokptr != NULL) */
+       }
+
+       net_close (sockfd);
+
+       if (n < 0)
+       {
+               syslog (LOG_WARNING, "apcups plugin: Error reading from socket");
+               return (-1);
+       }
+
+       return (0);
+}
+
+#ifdef APCMAIN
+int main(int argc, char **argv)
+{
+       /* we are not really going to use this */
+       struct apc_detail_s apcups_detail;
+
+       if (!*host || strcmp(host, "0.0.0.0") == 0)
+               host = "localhost";
+
+       do_pthreads_status(host, port, &apcups_detail);
+
+       return 0;
+}
+#else
+static void apcups_init (void)
+{
+       return;
+}
+
+static int apcups_config (char *key, char *value)
+{
+  static char lhost[126];
+  
+  if (strcasecmp (key, "host") == 0)
+    {
+      lhost[0] = '\0';
+      strcpy(lhost,key);
+      host = lhost;
+    }
+  else if (strcasecmp (key, "Port") == 0)
+    {
+      int port_tmp = atoi (value);
+      if(port_tmp < 1 || port_tmp > 65535) {
+       syslog (LOG_WARNING, "apcups: `port' failed: %s",
+               value);
+       return (1);
+      } else {
+       port = port_tmp;
+      }
+    }
+  else
+    {
+      return (-1);
+    }
+  return(0);
+}
+
+#define BUFSIZE 256
+static void apcups_submit (char *host,
+                          struct apc_detail_s *apcups_detail)
+{
+       char buf[BUFSIZE];
+
+       if (snprintf (buf, BUFSIZE, "%u:%f:%f",
+                     (unsigned int) curtime,
+                     apcups_detail->linev,
+                     apcups_detail->outputv) >= BUFSIZE)
+         return;
+       
+       plugin_submit (MODULE_NAME, host, buf);
+}
+
+static void apc_bvolt_submit (char *host,
+                          struct apc_detail_s *apcups_detail)
+{
+       char buf[BUFSIZE];
+
+       if (snprintf (buf, BUFSIZE, "%u:%f",
+                     (unsigned int) curtime,
+                     apcups_detail->battv) >= BUFSIZE)
+         return;
+       
+       plugin_submit ("apcups_bvolt", host, buf);
+}
+
+static void apc_load_submit (char *host,
+                          struct apc_detail_s *apcups_detail)
+{
+       char buf[BUFSIZE];
+
+       if (snprintf (buf, BUFSIZE, "%u:%f",
+                     (unsigned int) curtime,
+                     apcups_detail->loadpct) >= BUFSIZE)
+         return;
+       
+       plugin_submit ("apcups_load", host, buf);
+}
+
+static void apc_charge_submit (char *host,
+                          struct apc_detail_s *apcups_detail)
+{
+       char buf[BUFSIZE];
+
+       if (snprintf (buf, BUFSIZE, "%u:%f",
+                     (unsigned int) curtime,
+                     apcups_detail->bcharge) >= BUFSIZE)
+         return;
+       
+       plugin_submit ("apcups_charge", host, buf);
+}
+
+static void apc_temp_submit (char *host,
+                          struct apc_detail_s *apcups_detail)
+{
+       char buf[BUFSIZE];
+
+       if (snprintf (buf, BUFSIZE, "%u:%f",
+                     (unsigned int) curtime,
+                     apcups_detail->itemp) >= BUFSIZE)
+         return;
+       
+       plugin_submit ("apcups_temp", host, buf);
+}
+
+static void apc_time_submit (char *host,
+                          struct apc_detail_s *apcups_detail)
+{
+       char buf[BUFSIZE];
+
+       if (snprintf (buf, BUFSIZE, "%u:%f",
+                     (unsigned int) curtime,
+                     apcups_detail->timeleft) >= BUFSIZE)
+         return;
+       
+       plugin_submit ("apcups_time", host, buf);
+}
+
+static void apc_freq_submit (char *host,
+                          struct apc_detail_s *apcups_detail)
+{
+       char buf[BUFSIZE];
+
+       if (snprintf (buf, BUFSIZE, "%u:%f",
+                     (unsigned int) curtime,
+                     apcups_detail->linefreq) >= BUFSIZE)
+         return;
+       
+       plugin_submit ("apcups_freq", host, buf);
+}
+#undef BUFSIZE
+
+static void apcups_read (void)
+{
+  struct apc_detail_s apcups_detail;
+       
+  apcups_detail.linev = 0.0;
+  apcups_detail.loadpct = 0.0;
+  apcups_detail.bcharge = 0.0;
+  apcups_detail.timeleft = 0.0;
+  apcups_detail.outputv = 0.0;
+  apcups_detail.itemp = 0.0;
+  apcups_detail.battv = 0.0;
+  apcups_detail.linefreq = 0.0;
+
+  
+  if (!*host || strcmp(host, "0.0.0.0") == 0)
+    host = "localhost";
+  
+  do_pthreads_status(host, port, &apcups_detail);
+  apcups_submit (host, &apcups_detail);
+  apc_bvolt_submit (host, &apcups_detail);
+  apc_load_submit (host, &apcups_detail);
+  apc_charge_submit (host, &apcups_detail);
+  apc_temp_submit (host, &apcups_detail);
+  apc_time_submit (host, &apcups_detail);
+  apc_freq_submit (host, &apcups_detail);
+}
+
+
+static void apcups_write (char *host, char *inst, char *val)
+{
+  char file[512];
+  int status;
+  
+  status = snprintf (file, 512, volt_file_template, inst);
+  if (status < 1)
+    return;
+  else if (status >= 512)
+    return;
+  
+  rrd_update_file (host, file, val, volt_ds_def, volt_ds_num);
+}
+
+static void apc_bvolt_write (char *host, char *inst, char *val)
+{
+  char file[512];
+  int status;
+  
+  status = snprintf (file, 512, bvolt_file_template, inst);
+  if (status < 1)
+    return;
+  else if (status >= 512)
+    return;
+  
+  rrd_update_file (host, file, val, bvolt_ds_def, bvolt_ds_num);
+}
+
+static void apc_load_write (char *host, char *inst, char *val)
+{
+  char file[512];
+  int status;
+  
+  status = snprintf (file, 512, load_file_template, inst);
+  if (status < 1)
+    return;
+  else if (status >= 512)
+    return;
+  
+  rrd_update_file (host, file, val, load_ds_def, load_ds_num);
+}
+
+static void apc_charge_write (char *host, char *inst, char *val)
+{
+  char file[512];
+  int status;
+  
+  status = snprintf (file, 512, charge_file_template, inst);
+  if (status < 1)
+    return;
+  else if (status >= 512)
+    return;
+  
+  rrd_update_file (host, file, val, charge_ds_def, charge_ds_num);
+}
+
+static void apc_temp_write (char *host, char *inst, char *val)
+{
+  char file[512];
+  int status;
+  
+  status = snprintf (file, 512, temp_file_template, inst);
+  if (status < 1)
+    return;
+  else if (status >= 512)
+    return;
+  
+  rrd_update_file (host, file, val, temp_ds_def, temp_ds_num);
+}
+
+static void apc_time_write (char *host, char *inst, char *val)
+{
+  char file[512];
+  int status;
+  
+  status = snprintf (file, 512, time_file_template, inst);
+  if (status < 1)
+    return;
+  else if (status >= 512)
+    return;
+  
+  rrd_update_file (host, file, val, time_ds_def, time_ds_num);
+}
+
+static void apc_freq_write (char *host, char *inst, char *val)
+{
+  char file[512];
+  int status;
+  
+  status = snprintf (file, 512, freq_file_template, inst);
+  if (status < 1)
+    return;
+  else if (status >= 512)
+    return;
+  
+  rrd_update_file (host, file, val, freq_ds_def, freq_ds_num);
+}
+
+void module_register (void)
+{
+       plugin_register (MODULE_NAME, apcups_init, apcups_read, apcups_write);
+       plugin_register ("apcups_bvolt", NULL, NULL, apc_bvolt_write);
+       plugin_register ("apcups_load", NULL, NULL, apc_load_write);
+       plugin_register ("apcups_charge", NULL, NULL, apc_charge_write);
+       plugin_register ("apcups_temp", NULL, NULL, apc_temp_write);
+       plugin_register ("apcups_time", NULL, NULL, apc_time_write);
+       plugin_register ("apcups_freq", NULL, NULL, apc_freq_write);
+       cf_register (MODULE_NAME, apcups_config, config_keys, config_keys_num);
+}
+
+#endif /* ifdef APCMAIN */
+#undef MODULE_NAME
index 10e8c00..2141a58 100644 (file)
@@ -202,6 +202,7 @@ static void battery_submit (char *inst, double current, double voltage, double c
        }
 }
 
+#if HAVE_IOKIT_PS_IOPOWERSOURCES_H || HAVE_IOKIT_IOKITLIB_H
 double dict_get_double (CFDictionaryRef dict, char *key_string)
 {
        double      val_double;
@@ -249,6 +250,7 @@ double dict_get_double (CFDictionaryRef dict, char *key_string)
 
        return (val_double);
 }
+#endif /* HAVE_IOKIT_PS_IOPOWERSOURCES_H || HAVE_IOKIT_IOKITLIB_H */
 
 #if HAVE_IOKIT_PS_IOPOWERSOURCES_H
 static void get_via_io_power_sources (double *ret_charge,
index b4ee504..2720590 100644 (file)
@@ -201,7 +201,7 @@ static int start_client (void)
 
                if (timeval_sub_timespec (&tv_next, &tv_now, &ts_wait) != 0)
                {
-                       syslog (LOG_WARNING, "No sleeping because `timeval_sub_timespec' returned non-zero!");
+                       syslog (LOG_WARNING, "Not sleeping because `timeval_sub_timespec' returned non-zero!");
                        continue;
                }
 
index a00bbb2..510af5c 100644 (file)
@@ -106,6 +106,20 @@ C<Plugin>-Section. Which options exist depends on the plugin used:
 
 =head2 Plugin C<apache>
 
+To configure the C<apache>-plugin you first need to configure the Apache
+webserver correctly. The Apache-plugin C<mod_status> needs to be loaded and
+working and the C<ExtendedStatus> directive needs to be B<enabled>. You can use
+the following snipped to base your Apache config upon:
+
+  ExtendedStatus on
+  <IfModule mod_status.c>
+    <Location /mod_status>
+      SetHandler server-status
+    </Location>
+  </IfModule>
+
+The following options are accepted by the C<apache>-plugin:
+
 =over 4
 
 =item B<URL> I<http://host/mod_status?auto>
@@ -122,6 +136,12 @@ Optional user name needed for authentication.
 
 Optional password needed for authentication.
 
+=item B<CACert> I<File>
+
+File that holds one or more SSL certificates. If you want to use HTTPS you will
+possibly need this option. What CA certificates come bundeled with C<libcurl>
+and are checked by default depends on the distribution you use.
+
 =back
 
 =head2 Plugin C<hddtemp>
@@ -176,6 +196,17 @@ Sets the Time-To-Live of generated ICMP packets.
 
 =back
 
+=head2 Plugin C<traffic>
+
+=over 4
+
+=item B<Ignore> I<Interface>
+
+Ignore the given interface. Use this to get rid of loopback- or
+IPv6-in-IPv4-tunnel-interface statistics.
+
+=back
+
 =head1 SEE ALSO
 
 L<collectd(1)>
index 488fbe2..fcad460 100644 (file)
@@ -252,209 +252,249 @@ The DS'es depend on the module creating the RRD files:
 
 =over 4
 
+=item Apache traffic (F<apache/apache_bytes.rrd>)
+
+  DS:count:COUNTER:HEARTBEAT:0:134217728
+
+=item Apache requests (F<apache/apache_requests.rrd>)
+
+  DS:count:COUNTER:HEARTBEAT:0:1048576
+
+=item Apache scoreboard (F<apache/apache_scoreboard-I<E<lt>nameE<gt>>.rrd>)
+
+  DS:count:GAUGE:HEARTBEAT:0:U
+
+=item Apple temperature sensor (F<apple_sensors/temperature-I<E<lt>nameE<gt>>.rrd>)
+
+  DS:value:GAUGE:HEARTBEAT:U:U
+
+=item Apple fanspeed sensor (F<apple_sensors/fanspeed-I<E<lt>nameE<gt>>.rrd>)
+
+  DS:value:GAUGE:HEARTBEAT:U:U
+
 =item Battery charge (F<battery-I<E<lt>nameE<gt>>/charge.rrd>)
 
-  DS:charge:GAUGE:25:0:U
+  DS:charge:GAUGE:HEARTBEAT:0:U
 
 =item Battery current (F<battery-I<E<lt>nameE<gt>>/current.rrd>)
 
-  DS:current:GAUGE:25:U:U
+  DS:current:GAUGE:HEARTBEAT:U:U
 
 =item Battery voltage (F<battery-I<E<lt>nameE<gt>>/voltage.rrd>)
 
-  DS:voltage:GAUGE:25:U:U
+  DS:voltage:GAUGE:HEARTBEAT:U:U
 
 =item CPU (F<cpu-I<E<lt>numE<gt>>.rrd>)
 
-  DS:user:COUNTER:25:0:100
-  DS:nice:COUNTER:25:0:100
-  DS:syst:COUNTER:25:0:100
-  DS:idle:COUNTER:25:0:100
-  DS:wait:COUNTER:25:0:100
+  DS:user:COUNTER:HEARTBEAT:0:100
+  DS:nice:COUNTER:HEARTBEAT:0:100
+  DS:syst:COUNTER:HEARTBEAT:0:100
+  DS:idle:COUNTER:HEARTBEAT:0:100
+  DS:wait:COUNTER:HEARTBEAT:0:100
+
+=item CPU frequency (F<cpufreq-I<E<lt>numE<gt>>.rrd>)
+
+  DS:value:GAUGE:HEARTBEAT:0:U
 
 =item Mountpoints (F<df-I<E<lt>pathE<gt>>.rrd>)
 
-  DS:used:GAUGE:25:0:U
-  DS:free:GAUGE:25:0:U
+  DS:used:GAUGE:HEARTBEAT:0:U
+  DS:free:GAUGE:HEARTBEAT:0:U
 
 =item Diskstats (F<disk-I<E<lt>majorE<gt>>-I<E<lt>minorE<gt>>.rrd>)
 
-  DS:rcount:COUNTER:25:0:U
-  DS:rmerged:COUNTER:25:0:U
-  DS:rbytes:COUNTER:25:0:U
-  DS:rtime:COUNTER:25:0:U
-  DS:wcount:COUNTER:25:0:U
-  DS:wmerged:COUNTER:25:0:U
-  DS:wbytes:COUNTER:25:0:U
-  DS:wtime:COUNTER:25:0:U
+  DS:rcount:COUNTER:HEARTBEAT:0:U
+  DS:rmerged:COUNTER:HEARTBEAT:0:U
+  DS:rbytes:COUNTER:HEARTBEAT:0:U
+  DS:rtime:COUNTER:HEARTBEAT:0:U
+  DS:wcount:COUNTER:HEARTBEAT:0:U
+  DS:wmerged:COUNTER:HEARTBEAT:0:U
+  DS:wbytes:COUNTER:HEARTBEAT:0:U
+  DS:wtime:COUNTER:HEARTBEAT:0:U
 
 =item Diskstats (F<partition-I<E<lt>majorE<gt>>-I<E<lt>minorE<gt>>.rrd>)
 
-  DS:rcount:COUNTER:25:0:U
-  DS:rbytes:COUNTER:25:0:U
-  DS:wcount:COUNTER:25:0:U
-  DS:wbytes:COUNTER:25:0:U
+  DS:rcount:COUNTER:HEARTBEAT:0:U
+  DS:rbytes:COUNTER:HEARTBEAT:0:U
+  DS:wcount:COUNTER:HEARTBEAT:0:U
+  DS:wbytes:COUNTER:HEARTBEAT:0:U
 
 =item HDD Temperature (F<hddtemp-I<E<lt>majorE<gt>>-I<E<lt>minorE<gt>>.rrd>)
 
-  DS:value:GAUGE:25:U:U
+  DS:value:GAUGE:HEARTBEAT:U:U
 
 =item System load (F<load.rrd>)
 
-  DS:shortterm:GAUGE:25:0:100
-  DS:midterm:GAUGE:25:0:100
-  DS:longterm:GAUGE:25:0:100
+  DS:shortterm:GAUGE:HEARTBEAT:0:100
+  DS:midterm:GAUGE:HEARTBEAT:0:100
+  DS:longterm:GAUGE:HEARTBEAT:0:100
 
 =item Memory usage (F<memory.rrd>)
 
-  DS:used:GAUGE:25:0:9223372036854775807
-  DS:free:GAUGE:25:0:9223372036854775807
-  DS:buffers:GAUGE:25:0:9223372036854775807
-  DS:cached:GAUGE:25:0:9223372036854775807
+  DS:used:GAUGE:HEARTBEAT:0:9223372036854775807
+  DS:free:GAUGE:HEARTBEAT:0:9223372036854775807
+  DS:buffers:GAUGE:HEARTBEAT:0:9223372036854775807
+  DS:cached:GAUGE:HEARTBEAT:0:9223372036854775807
 
 =item MySQL commands and handlers (F<mysql_commands-I<E<lt>commandE<gt>>.rrd> and F<mysql_handler-I<E<lt>handlerE<gt>>.rrd>)
 
-  DS:value:COUNTER:25:0:U
+  DS:value:COUNTER:HEARTBEAT:0:U
 
 =item MySQL query cache (F<mysql_qcache.rrd>)
 
-  DS:hits:COUNTER:25:0:U
-  DS:inserts:COUNTER:25:0:U
-  DS:not_cached:COUNTER:25:0:U
-  DS:lowmem_prunes:COUNTER:25:0:U
-  DS:queries_in_cache:GAUGE:25:0:U
+  DS:hits:COUNTER:HEARTBEAT:0:U
+  DS:inserts:COUNTER:HEARTBEAT:0:U
+  DS:not_cached:COUNTER:HEARTBEAT:0:U
+  DS:lowmem_prunes:COUNTER:HEARTBEAT:0:U
+  DS:queries_in_cache:GAUGE:HEARTBEAT:0:U
 
 =item MySQL threads (F<mysql_threads.rrd>)
 
-  DS:running:GAUGE:25:0:U
-  DS:connected:GAUGE:25:0:U
-  DS:cached:GAUGE:25:0:U
-  DS:created:COUNTER:25:0:U
+  DS:running:GAUGE:HEARTBEAT:0:U
+  DS:connected:GAUGE:HEARTBEAT:0:U
+  DS:cached:GAUGE:HEARTBEAT:0:U
+  DS:created:COUNTER:HEARTBEAT:0:U
 
 =item NFSv2 Procedures (F<nfs2_procedures-I<(client|server)>.rrd>)
 
-  DS:null:COUNTER:25:0:U
-  DS:getattr:COUNTER:25:0:U
-  DS:setattr:COUNTER:25:0:U
-  DS:root:COUNTER:25:0:U
-  DS:lookup:COUNTER:25:0:U
-  DS:readlink:COUNTER:25:0:U
-  DS:read:COUNTER:25:0:U
-  DS:wrcache:COUNTER:25:0:U
-  DS:write:COUNTER:25:0:U
-  DS:create:COUNTER:25:0:U
-  DS:remove:COUNTER:25:0:U
-  DS:rename:COUNTER:25:0:U
-  DS:link:COUNTER:25:0:U
-  DS:symlink:COUNTER:25:0:U
-  DS:mkdir:COUNTER:25:0:U
-  DS:rmdir:COUNTER:25:0:U
-  DS:readdir:COUNTER:25:0:U
-  DS:fsstat:COUNTER:25:0:U
+  DS:null:COUNTER:HEARTBEAT:0:U
+  DS:getattr:COUNTER:HEARTBEAT:0:U
+  DS:setattr:COUNTER:HEARTBEAT:0:U
+  DS:root:COUNTER:HEARTBEAT:0:U
+  DS:lookup:COUNTER:HEARTBEAT:0:U
+  DS:readlink:COUNTER:HEARTBEAT:0:U
+  DS:read:COUNTER:HEARTBEAT:0:U
+  DS:wrcache:COUNTER:HEARTBEAT:0:U
+  DS:write:COUNTER:HEARTBEAT:0:U
+  DS:create:COUNTER:HEARTBEAT:0:U
+  DS:remove:COUNTER:HEARTBEAT:0:U
+  DS:rename:COUNTER:HEARTBEAT:0:U
+  DS:link:COUNTER:HEARTBEAT:0:U
+  DS:symlink:COUNTER:HEARTBEAT:0:U
+  DS:mkdir:COUNTER:HEARTBEAT:0:U
+  DS:rmdir:COUNTER:HEARTBEAT:0:U
+  DS:readdir:COUNTER:HEARTBEAT:0:U
+  DS:fsstat:COUNTER:HEARTBEAT:0:U
 
 =item NFSv3 Procedures (F<nfs3_procedures-I<(client|server)>.rrd>)
 
-  DS:null:COUNTER:25:0:U
-  DS:getattr:COUNTER:25:0:U
-  DS:setattr:COUNTER:25:0:U
-  DS:lookup:COUNTER:25:0:U
-  DS:access:COUNTER:25:0:U
-  DS:readlink:COUNTER:25:0:U
-  DS:read:COUNTER:25:0:U
-  DS:write:COUNTER:25:0:U
-  DS:create:COUNTER:25:0:U
-  DS:mkdir:COUNTER:25:0:U
-  DS:symlink:COUNTER:25:0:U
-  DS:mknod:COUNTER:25:0:U
-  DS:remove:COUNTER:25:0:U
-  DS:rmdir:COUNTER:25:0:U
-  DS:rename:COUNTER:25:0:U
-  DS:link:COUNTER:25:0:U
-  DS:readdir:COUNTER:25:0:U
-  DS:readdirplus:COUNTER:25:0:U
-  DS:fsstat:COUNTER:25:0:U
-  DS:fsinfo:COUNTER:25:0:U
-  DS:pathconf:COUNTER:25:0:U
-  DS:commit:COUNTER:25:0:U
+  DS:null:COUNTER:HEARTBEAT:0:U
+  DS:getattr:COUNTER:HEARTBEAT:0:U
+  DS:setattr:COUNTER:HEARTBEAT:0:U
+  DS:lookup:COUNTER:HEARTBEAT:0:U
+  DS:access:COUNTER:HEARTBEAT:0:U
+  DS:readlink:COUNTER:HEARTBEAT:0:U
+  DS:read:COUNTER:HEARTBEAT:0:U
+  DS:write:COUNTER:HEARTBEAT:0:U
+  DS:create:COUNTER:HEARTBEAT:0:U
+  DS:mkdir:COUNTER:HEARTBEAT:0:U
+  DS:symlink:COUNTER:HEARTBEAT:0:U
+  DS:mknod:COUNTER:HEARTBEAT:0:U
+  DS:remove:COUNTER:HEARTBEAT:0:U
+  DS:rmdir:COUNTER:HEARTBEAT:0:U
+  DS:rename:COUNTER:HEARTBEAT:0:U
+  DS:link:COUNTER:HEARTBEAT:0:U
+  DS:readdir:COUNTER:HEARTBEAT:0:U
+  DS:readdirplus:COUNTER:HEARTBEAT:0:U
+  DS:fsstat:COUNTER:HEARTBEAT:0:U
+  DS:fsinfo:COUNTER:HEARTBEAT:0:U
+  DS:pathconf:COUNTER:HEARTBEAT:0:U
+  DS:commit:COUNTER:HEARTBEAT:0:U
 
 =item Network latency / Ping (F<ping-I<E<lt>hostnameE<gt>>.rrd>)
 
-  DS:ping:GAUGE:25:0:65535
+  DS:ping:GAUGE:HEARTBEAT:0:65535
 
 =item Processes (F<processes.rrd>)
 
-  DS:running:GAUGE:25:0:65535
-  DS:sleeping:GAUGE:25:0:65535
-  DS:zombies:GAUGE:25:0:65535
-  DS:stopped:GAUGE:25:0:65535
-  DS:paging:GAUGE:25:0:65535
-  DS:blocked:GAUGE:25:0:65535
+  DS:running:GAUGE:HEARTBEAT:0:65535
+  DS:sleeping:GAUGE:HEARTBEAT:0:65535
+  DS:zombies:GAUGE:HEARTBEAT:0:65535
+  DS:stopped:GAUGE:HEARTBEAT:0:65535
+  DS:paging:GAUGE:HEARTBEAT:0:65535
+  DS:blocked:GAUGE:HEARTBEAT:0:65535
 
 =item lm_sensors (F<sensors-I<E<lt>chipE<gt>>-I<E<lt>featureE<gt>>.rrd>)
 
-  DS:value:GAUGE:25:U:U
+  DS:value:GAUGE:HEARTBEAT:U:U
 
 =item Serial port traffic (F<serial-I<E<lt>numE<gt>>.rrd>)
 
-  DS:incoming:COUNTER:25:0:U
-  DS:outgoing:COUNTER:25:0:U
+  DS:incoming:COUNTER:HEARTBEAT:0:U
+  DS:outgoing:COUNTER:HEARTBEAT:0:U
 
 =item Swap usage (F<swap.rrd>)
 
-  DS:used:GAUGE:25:0:1099511627776
-  DS:free:GAUGE:25:0:1099511627776
-  DS:cached:GAUGE:25:0:1099511627776
-  DS:resv:GAUGE:25:0:1099511627776
+  DS:used:GAUGE:HEARTBEAT:0:1099511627776
+  DS:free:GAUGE:HEARTBEAT:0:1099511627776
+  DS:cached:GAUGE:HEARTBEAT:0:1099511627776
+  DS:resv:GAUGE:HEARTBEAT:0:1099511627776
 
 =item Tape drive usage (F<tape-I<E<lt>nameE<gt>>.rrd>)
 
-  DS:rcount:COUNTER:25:0:
-  DS:rmerged:COUNTER:25:0:U
-  DS:rbytes:COUNTER:25:0:U
-  DS:rtime:COUNTER:25:0:U
-  DS:wcount:COUNTER:25:0:U
-  DS:wmerged:COUNTER:25:0:U
-  DS:wbytes:COUNTER:25:0:U
-  DS:wtime:COUNTER:25:0:U
+  DS:rcount:COUNTER:HEARTBEAT:0:
+  DS:rmerged:COUNTER:HEARTBEAT:0:U
+  DS:rbytes:COUNTER:HEARTBEAT:0:U
+  DS:rtime:COUNTER:HEARTBEAT:0:U
+  DS:wcount:COUNTER:HEARTBEAT:0:U
+  DS:wmerged:COUNTER:HEARTBEAT:0:U
+  DS:wbytes:COUNTER:HEARTBEAT:0:U
+  DS:wtime:COUNTER:HEARTBEAT:0:U
+
+=item Network traffic (F<traffic-I<E<lt>interfaceE<gt>>.rrd>)
+
+  DS:incoming:COUNTER:HEARTBEAT:0:U
+  DS:outgoing:COUNTER:HEARTBEAT:0:U
 
-=item Network traffic (F<traffic-I<E<lt>nameE<gt>>.rrd>)
+=item Interface packets (F<if_packets-I<E<lt>interfaceE<gt>>.rrd>)
 
-  DS:incoming:COUNTER:25:0:U
-  DS:outgoing:COUNTER:25:0:U
+  DS:rx:COUNTER:HEARTBEAT:0:U
+  DS:tx:COUNTER:HEARTBEAT:0:U
+
+=item Interface errors (F<if_errors-I<E<lt>interfaceE<gt>>.rrd>)
+
+  DS:rx:COUNTER:HEARTBEAT:0:U
+  DS:tx:COUNTER:HEARTBEAT:0:U
 
 =item Users (F<users.rrd>)
 
-  DS:users:GAUGE:25:0:65535
+  DS:users:GAUGE:HEARTBEAT:0:65535
 
 =item VServer load (F<vserver-I<E<lt>xidE<gt>>/load.rrd>)
 
-  DS:shortterm:GAUGE:25:0:100
-  DS:midterm:GAUGE:25:0:100
-  DS:longterm:GAUGE:25:0:100
+  DS:shortterm:GAUGE:HEARTBEAT:0:100
+  DS:midterm:GAUGE:HEARTBEAT:0:100
+  DS:longterm:GAUGE:HEARTBEAT:0:100
 
 =item VServer threads (F<vserver-I<E<lt>xidE<gt>>/threads.rrd>)
 
-  DS:total:GAUGE:25:0:65535
-  DS:running:GAUGE:25:0:65535
-  DS:uninterruptible:GAUGE:25:0:65535
-  DS:onhold:GAUGE:25:0:65535
+  DS:total:GAUGE:HEARTBEAT:0:65535
+  DS:running:GAUGE:HEARTBEAT:0:65535
+  DS:uninterruptible:GAUGE:HEARTBEAT:0:65535
+  DS:onhold:GAUGE:HEARTBEAT:0:65535
 
 =item VServer network traffic (F<vserver-I<E<lt>xidE<gt>>/traffic-I<E<lt>nameE<gt>>.rrd>)
 
-  DS:incoming:COUNTER:25:0:9223372036854775807
-  DS:outgoing:COUNTER:25:0:9223372036854775807
-  DS:failed:COUNTER:25:0:9223372036854775807
+  DS:incoming:COUNTER:HEARTBEAT:0:9223372036854775807
+  DS:outgoing:COUNTER:HEARTBEAT:0:9223372036854775807
+  DS:failed:COUNTER:HEARTBEAT:0:9223372036854775807
 
 =item VServer processes (F<vserver-I<E<lt>xidE<gt>>/vs_processes.rrd>)
 
-  DS:total:GAUGE:25:0:65535
+  DS:total:GAUGE:HEARTBEAT:0:65535
 
 =item VServer memory usage (F<vserver-I<E<lt>xidE<gt>>/vs_memory.rrd>)
 
-  DS:vm:GAUGE:25:0:9223372036854775807
-  DS:vml:GAUGE:25:0:9223372036854775807
-  DS:rss:GAUGE:25:0:9223372036854775807
-  DS:anon:GAUGE:25:0:9223372036854775807
+  DS:vm:GAUGE:HEARTBEAT:0:9223372036854775807
+  DS:vml:GAUGE:HEARTBEAT:0:9223372036854775807
+  DS:rss:GAUGE:HEARTBEAT:0:9223372036854775807
+  DS:anon:GAUGE:HEARTBEAT:0:9223372036854775807
+
+=item Wireless link quality (F<wireless-I<E<lt>interfaceE<gt>>.rrd>)
+
+  DS:quality:GAUGE:HEARTBEAT:0:U
+  DS:power:GAUGE:HEARTBEAT:U:0
+  DS:noise:GAUGE:HEARTBEAT:U:0
 
 =back
 
index cbe6e80..08bbbc0 100644 (file)
@@ -158,6 +158,10 @@ static int hddtemp_query_daemon (char *buffer, int buffer_size)
                        fd = -1;
                        continue;
                }
+
+               /* A socket could be opened and connecting succeeded. We're
+                * done. */
+               break;
        }
 
        freeaddrinfo (ai_list);
index 1ee2393..17da3e7 100644 (file)
 # define dprintf(...) /**/
 #endif
 
+#define PING_ERRMSG_LEN 256
+
 #define PING_DATA "Florian Forster <octo@verplant.org> http://verplant.org/"
 
+struct pinghost
+{
+       char                    *hostname;
+       struct sockaddr_storage *addr;
+       socklen_t                addrlen;
+       int                      addrfamily;
+       int                      fd;
+       int                      ident;
+       int                      sequence;
+       struct timeval          *timer;
+       double                   latency;
+
+       struct pinghost         *next;
+};
+
+struct pingobj
+{
+       double      timeout;
+       int         ttl;
+       int         addrfamily;
+
+       char        errmsg[PING_ERRMSG_LEN];
+
+       pinghost_t *head;
+};
+
 /*
  * private (static) functions
  */
+static void ping_set_error (pingobj_t *obj, const char *function,
+               const char *message)
+{
+       snprintf (obj->errmsg, PING_ERRMSG_LEN, "%s: %s", function, message);
+       obj->errmsg[PING_ERRMSG_LEN - 1] = '\0';
+}
+
 static int ping_timeval_add (struct timeval *tv1, struct timeval *tv2,
                struct timeval *res)
 {
@@ -388,7 +423,10 @@ static int ping_receive_all (pingobj_t *obj)
                ptr->latency = -1.0;
 
        if (gettimeofday (&nowtime, NULL) == -1)
+       {
+               ping_set_error (obj, "gettimeofday", strerror (errno));
                return (-1);
+       }
 
        /* Set up timeout */
        timeout.tv_sec = (time_t) obj->timeout;
@@ -422,7 +460,10 @@ static int ping_receive_all (pingobj_t *obj)
                        break;
 
                if (gettimeofday (&nowtime, NULL) == -1)
+               {
+                       ping_set_error (obj, "gettimeofday", strerror (errno));
                        return (-1);
+               }
 
                if (ping_timeval_sub (&endtime, &nowtime, &timeout) == -1)
                        break;
@@ -434,7 +475,10 @@ static int ping_receive_all (pingobj_t *obj)
                status = select (max_readfds + 1, &readfds, NULL, NULL, &timeout);
 
                if (gettimeofday (&nowtime, NULL) == -1)
+               {
+                       ping_set_error (obj, "gettimeofday", strerror (errno));
                        return (-1);
+               }
                
                if ((status == -1) && (errno == EINTR))
                {
@@ -470,7 +514,7 @@ static int ping_receive_all (pingobj_t *obj)
  * +-> ping_send_one_ipv4                                                    *
  * `-> ping_send_one_ipv6                                                    *
  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-ssize_t ping_sendto (pinghost_t *ph, const void *buf, size_t buflen)
+static ssize_t ping_sendto (pinghost_t *ph, const void *buf, size_t buflen)
 {
        ssize_t ret;
 
@@ -714,6 +758,11 @@ static void ping_free (pinghost_t *ph)
 /*
  * public methods
  */
+const char *ping_get_error (pingobj_t *obj)
+{
+       return (obj->errmsg);
+}
+
 pingobj_t *ping_construct (void)
 {
        pingobj_t *obj;
@@ -851,6 +900,7 @@ int ping_host_add (pingobj_t *obj, const char *host)
        if ((ph->hostname = strdup (host)) == NULL)
        {
                dprintf ("Out of memory!\n");
+               ping_set_error (obj, "strdup", strerror (errno));
                ping_free (ph);
                return (-1);
        }
@@ -858,10 +908,17 @@ int ping_host_add (pingobj_t *obj, const char *host)
        if ((ai_return = getaddrinfo (host, NULL, &ai_hints, &ai_list)) != 0)
        {
                dprintf ("getaddrinfo failed\n");
+               ping_set_error (obj, "getaddrinfo",
+                               (ai_return == EAI_SYSTEM)
+                               ? strerror (errno)
+                               : gai_strerror (ai_return));
                ping_free (ph);
                return (-1);
        }
 
+       if (ai_list == NULL)
+               ping_set_error (obj, "getaddrinfo", "No hosts returned");
+
        for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
        {
                ph->fd = -1;
@@ -878,6 +935,7 @@ int ping_host_add (pingobj_t *obj, const char *host)
                        si->sin_port   = htons (ph->ident);
                        si->sin_addr.s_addr = htonl (INADDR_ANY);
 
+                       ai_ptr->ai_socktype = SOCK_RAW;
                        ai_ptr->ai_protocol = IPPROTO_ICMP;
                }
                else if (ai_ptr->ai_family == AF_INET6)
@@ -889,11 +947,18 @@ int ping_host_add (pingobj_t *obj, const char *host)
                        si->sin6_port   = htons (ph->ident);
                        si->sin6_addr   = in6addr_any;
 
+                       ai_ptr->ai_socktype = SOCK_RAW;
                        ai_ptr->ai_protocol = IPPROTO_ICMPV6;
                }
                else
                {
-                       dprintf ("Unknown `ai_family': %i\n", ai_ptr->ai_family);
+                       char errmsg[PING_ERRMSG_LEN];
+
+                       snprintf (errmsg, PING_ERRMSG_LEN, "Unknown `ai_family': %i", ai_ptr->ai_family);
+                       errmsg[PING_ERRMSG_LEN - 1] = '\0';
+
+                       dprintf (errmsg);
+                       ping_set_error (obj, "getaddrinfo", errmsg);
                        continue;
                }
 
@@ -901,6 +966,7 @@ int ping_host_add (pingobj_t *obj, const char *host)
                if (ph->fd == -1)
                {
                        dprintf ("socket: %s\n", strerror (errno));
+                       ping_set_error (obj, "socket", strerror (errno));
                        continue;
                }
 
@@ -908,6 +974,7 @@ int ping_host_add (pingobj_t *obj, const char *host)
                if (bind (ph->fd, (struct sockaddr *) &sockaddr, sockaddr_len) == -1)
                {
                        dprintf ("bind: %s\n", strerror (errno));
+                       ping_set_error (obj, "bind", strerror (errno));
                        close (ph->fd);
                        ph->fd = -1;
                        continue;
@@ -957,7 +1024,10 @@ int ping_host_remove (pingobj_t *obj, const char *host)
        }
 
        if (cur == NULL)
+       {
+               ping_set_error (obj, "ping_host_remove", "Host not found");
                return (-1);
+       }
 
        if (pre == NULL)
                obj->head = cur->next;
diff --git a/src/libping/ping.c b/src/libping/ping.c
deleted file mode 100644 (file)
index 8c6f9d7..0000000
+++ /dev/null
@@ -1,337 +0,0 @@
-/**
- * PING module
- *
- * Copyright (C) 2001 Jeffrey Fulmer <jdfulmer@armstrong.com>
- * This file is part of LIBPING
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-#include <ping.h>
-#include <util.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include <pthread.h>
-#include <stdlib.h>
-
-#define  MAXPACKET   65535
-#define  PKTSIZE     64 
-#define  HDRLEN      ICMP_MINLEN
-#define  DATALEN     (PKTSIZE-HDRLEN)
-#define  MAXDATA     (MAXPKT-HDRLEN-TIMLEN)
-#define  DEF_TIMEOUT 5
-
-#include "private.h"
-
-void
-JOEfreeprotoent( struct protoent *p )
-{
-  char **a;
-  free( p->p_name );
-  if( p->p_aliases != NULL ){
-    for( a = p->p_aliases; *a != NULL; a++ ){
-      free( *a );
-    }
-  }
-  free( p );
-}
-
-void
-JOEfreehostent( struct hostent *h )
-{
-  char **p;
-
-  free( h->h_name );
-  if( h->h_aliases != NULL ){
-    for( p = h->h_aliases; *p != NULL; ++p )
-      free( *p );
-    free( h->h_aliases );
-  }
-  if( h->h_addr_list != NULL ){
-    for( p = h->h_addr_list; *p != NULL; ++p )
-      free( *p );
-    free (h->h_addr_list);
-  }
-  free( h );
-}
-
-static int 
-in_checksum( u_short *buf, int len )
-{
-  register long sum = 0;
-  u_short  answer = 0;
-
-  while( len > 1 ){
-    sum += *buf++;
-    len -= 2;
-  }
-
-  if( len == 1 ){
-    *( u_char* )( &answer ) = *( u_char* )buf;
-    sum += answer;
-  }
-  sum = ( sum >> 16 ) + ( sum & 0xffff );
-  sum += ( sum >> 16 );     
-  answer = ~sum;     
-
-  return ( answer );
-
-} 
-
-static int
-send_ping( const char *host, struct sockaddr_in *taddr, struct ping_priv * datum )
-{
-  int len;
-  int ss;
-  unsigned char buf[ HDRLEN + DATALEN ];
-
-  const int proto_buf_len = 1024;
-  char   proto_buf[proto_buf_len];
-  struct protoent *proto = NULL;
-  struct protoent proto_datum;
-
-  struct hostent  *hp = NULL;
-  struct hostent  hent;
-  int herrno;
-  char hbf[9000];
-#if defined(_AIX)
-  char *aixbuf;
-  char *probuf;
-  int  rc;
-#endif/*_AIX*/
-
-  struct icmp     *icp;
-  unsigned short  last;
-
-  len = HDRLEN + DATALEN;
-
-#if defined(__GLIBC__)
-  /* for systems using GNU libc */
-  getprotobyname_r("icmp", &proto_datum, proto_buf, proto_buf_len, &proto);
-  if(( gethostbyname_r( host, &hent, hbf, sizeof(hbf), &hp, &herrno ) < 0 )){
-    hp = NULL;
-  }
-#elif defined(sun)
-  /* Solaris 5++ */
-  proto = getprotobyname_r("icmp", &proto_datum, proto_buf, proto_buf_len);
-  hp    = gethostbyname_r( host, &hent, hbf, sizeof(hbf), &herrno );
-#elif defined(_AIX)
-  aixbuf = (char*)xmalloc( 9000 );
-  probuf = (char*)xmalloc( 9000 );
-  rc  = getprotobyname_r( "icmp", &proto,
-                        ( struct protoent_data *)(probuf + sizeof( struct protoent)));
-  rc  = gethostbyname_r ( host, (struct hostent *)aixbuf,
-                        (struct hostent_data *)(aixbuf + sizeof(struct hostent)));
-  hp = (struct hostent*)aixbuf;
-#elif ( defined(hpux) || defined(__osf__) )
-  proto  = getprotobyname( "icmp" ); 
-  hp     = gethostbyname( host );
-  herrno = h_errno;
-#else
-  /* simply hoping that get*byname is thread-safe */
-  proto  = getprotobyname( "icmp" ); 
-  hp     = gethostbyname( host );
-  herrno = h_errno;
-#endif/*OS SPECIFICS*/
-  
-  if( proto == NULL ) {
-    return -1;
-  }
-
-  if(hp != NULL ){
-    memcpy( &taddr->sin_addr, hp->h_addr_list[0], sizeof( taddr->sin_addr ));
-    taddr->sin_port = 0;
-    taddr->sin_family = AF_INET;
-  }
-  else if( inet_aton( host, &taddr->sin_addr ) == 0 ){
-    return -1;
-  }
-
-  last = ntohl( taddr->sin_addr.s_addr ) & 0xFF;
-  if(( last == 0x00 ) || ( last == 0xFF )){
-    return -1;
-  }
-
-  if(( datum->sock = socket( AF_INET, SOCK_RAW, proto->p_proto )) < 0 ){
-#ifdef  DEBUG
-  perror( "sock" );
-#endif/*DEBUG*/
-    return -2;
-  }
-
-  memset(buf, 0, sizeof(buf));
-  icp = (struct icmp *)buf;
-  icp->icmp_type  = ICMP_ECHO;
-  icp->icmp_code  = 0;
-  icp->icmp_cksum = 0;
-  icp->icmp_id    = getpid() & 0xFFFF;
-  icp->icmp_seq   = icp->icmp_id; /* FIXME this is not nice.. */
-  icp->icmp_cksum = in_checksum((u_short *)icp, len );
-
-  if(( ss = sendto( datum->sock, buf, sizeof( buf ), 0, 
-     (struct sockaddr*)taddr, sizeof( *taddr ))) < 0 ){
-#ifdef  DEBUG
-  perror( "sock" );
-#endif/*DEBUG*/
-    return -2;
-  }
-  if( ss != len ){
-#ifdef  DEBUG
-  perror( "malformed packet" );
-#endif/*DEBUG*/
-    return -2;
-  }
-
-#if defined(_AIX)
-  free( aixbuf );
-  free( probuf );
-#endif 
-  /* JOEfreeprotoent( proto ); */
-  /* JOEfreeprotoent( &proto_datum ); */
-  /* JOEfreehostent( hp ); */
-  /* JOEfreehostent( &hent ); */
-  return 0;
-}
-
-static int 
-recv_ping( struct sockaddr_in *taddr, struct ping_priv * datum )
-{
-  int len;
-  socklen_t from;
-  int nf, cc;
-  unsigned char buf[ HDRLEN + DATALEN ];
-  struct icmp        *icp;
-  struct sockaddr_in faddr;
-  struct timeval to;
-  fd_set readset;
-
-  to.tv_sec = datum->timo / 100000;
-  to.tv_usec = ( datum->timo - ( to.tv_sec * 100000 ) ) * 10;
-
-  FD_ZERO( &readset );
-  FD_SET( datum->sock, &readset );
-  /* we use select to see if there is any activity
-     on the socket.  If not, then we've requested an
-     unreachable network and we'll time out here. */
-  if(( nf = select( datum->sock + 1, &readset, NULL, NULL, &to )) < 0 ){
-    datum->rrt = -4;
-#ifdef  DEBUG
-    perror( "select" );
-#endif/*DEBUG*/    
-    return 0;
-  }
-  if( nf == 0 ){ 
-    return -1; 
-  }
-
-  len = HDRLEN + DATALEN;
-  from = sizeof( faddr ); 
-
-  cc = recvfrom( datum->sock, buf, len, 0, (struct sockaddr*)&faddr, &from );
-  if( cc < 0 ){
-    datum->rrt = -4;
-#ifdef  DEBUG
-    perror( "recvfrom" );
-#endif/*DEBUG*/    
-    return 0;
-  }
-
-  icp = (struct icmp *)(buf + HDRLEN + DATALEN );
-  if( faddr.sin_addr.s_addr != taddr->sin_addr.s_addr ){
-    return 1;
-  }
-  /*****
-  if( icp->icmp_id   != ( getpid() & 0xFFFF )){
-    printf( "id: %d\n",  icp->icmp_id );
-    return 1; 
-  }
-  *****/
-  return 0;
-}
-
-int 
-myping( const char *hostname, int t , struct ping_priv * datum)
-{
-  int err;
-  int rrt;
-  struct sockaddr_in sa;
-  struct timeval mytime;
-  datum->ident = getpid() & 0xFFFF;
-
-  if( t == 0 ) datum->timo = 2; 
-  else         datum->timo = t;
-
-  datum->rrt = 0;
-  
-  (void) gettimeofday( &mytime, (struct timezone *)NULL); 
-  if(( err = send_ping( hostname, &sa, datum)) < 0 ){
-    close( datum->sock );
-    return err;
-  }
-  do {
-    rrt = elapsed_time( &mytime );
-    if (datum->rrt < 0)
-      return 0;
-    datum->rrt = rrt;
-    if (datum->rrt > datum->timo * 1000 ) {
-      close( datum->sock );
-      return 0;
-    }
-  } while( recv_ping( &sa, datum ));
-  close( datum->sock ); 
-  return 1;
-}
-
-int
-pinghost( const char *hostname )
-{
-  struct ping_priv datum = ping_priv_default();
-  return myping( hostname, 0, &datum );
-}
-
-int
-pingthost( const char *hostname, int t )
-{
-  struct ping_priv datum = ping_priv_default();
-  return myping( hostname, t, &datum );
-}
-
-int
-tpinghost( const char *hostname )
-{
-  int ret;
-  struct ping_priv datum = ping_priv_default();
-
-  ret = myping( hostname, 0, &datum );
-  if(ret > 0 )
-    ret = datum.rrt;
-  return ret;
-} 
-
-int
-tpingthost( const char *hostname, int t )
-{
-  int ret;
-  struct ping_priv datum = ping_priv_default();
-
-  ret = myping( hostname, t, &datum );
-  if(ret > 0 )
-    ret = datum.rrt;
-  return ret;
-}
-
index 0891503..7dd8d68 100644 (file)
 #include "common.h"
 #include "plugin.h"
 
+#if HAVE_SYS_SWAP_H
+# include <sys/swap.h>
+#endif
+#if HAVE_SYS_PARAM_H
+#  include <sys/param.h>
+#endif
+#if HAVE_SYS_SYSCTL_H
+#  include <sys/sysctl.h>
+#endif
+
 #define MODULE_NAME "swap"
 
-#if defined(KERNEL_LINUX) || defined(KERNEL_SOLARIS) || defined(HAVE_LIBSTATGRAB)
+#if KERNEL_LINUX || HAVE_LIBKSTAT || HAVE_SYS_SYSCTL_H || HAVE_LIBSTATGRAB
 # define SWAP_HAVE_READ 1
 #else
 # define SWAP_HAVE_READ 0
 #endif
 
-#if HAVE_SYS_SWAP_H
-# include <sys/swap.h>
-#endif
-
 #undef  MAX
 #define MAX(x,y) ((x) > (y) ? (x) : (y))
 
@@ -52,19 +58,43 @@ static char *ds_def[] =
 };
 static int ds_num = 4;
 
-#ifdef KERNEL_SOLARIS
+#if KERNEL_LINUX
+/* No global variables */
+/* #endif KERNEL_LINUX */
+
+#elif HAVE_LIBKSTAT
 static int pagesize;
 static kstat_t *ksp;
-#endif /* KERNEL_SOLARIS */
+/* #endif HAVE_LIBKSTAT */
+
+#elif HAVE_SYS_SYSCTL_H
+/* No global variables */
+/* #endif HAVE_SYS_SYSCTL_H */
+
+#elif HAVE_LIBSTATGRAB
+/* No global variables */
+#endif /* HAVE_LIBSTATGRAB */
 
 static void swap_init (void)
 {
-#ifdef KERNEL_SOLARIS
+#if KERNEL_LINUX
+       /* No init stuff */
+/* #endif KERNEL_LINUX */
+
+#elif HAVE_LIBKSTAT
        /* getpagesize(3C) tells me this does not fail.. */
        pagesize = getpagesize ();
        if (get_kstat (&ksp, "unix", 0, "system_pages"))
                ksp = NULL;
-#endif /* KERNEL_SOLARIS */
+/* #endif HAVE_LIBKSTAT */
+
+#elif HAVE_SYS_SYSCTL_H
+       /* No init stuff */
+/* #endif HAVE_SYS_SYSCTL_H */
+
+#elif HAVE_LIBSTATGRAB
+       /* No init stuff */
+#endif /* HAVE_LIBSTATGRAB */
 
        return;
 }
@@ -91,7 +121,7 @@ static void swap_submit (unsigned long long swap_used,
 
 static void swap_read (void)
 {
-#ifdef KERNEL_LINUX
+#if KERNEL_LINUX
        FILE *fh;
        char buffer[1024];
        
@@ -139,9 +169,9 @@ static void swap_read (void)
        swap_used = swap_total - (swap_free + swap_cached);
 
        swap_submit (swap_used, swap_free, swap_cached, -1LL);
-/* #endif defined(KERNEL_LINUX) */
+/* #endif KERNEL_LINUX */
 
-#elif defined(KERNEL_SOLARIS)
+#elif HAVE_LIBKSTAT
        unsigned long long swap_alloc;
        unsigned long long swap_resv;
        unsigned long long swap_avail;
@@ -182,9 +212,26 @@ static void swap_read (void)
        /* swap_free  = pagesize * (ai.ani_free + (availrmem - swapfs_minfree)); */
 
        swap_submit (swap_alloc, swap_avail, -1LL, swap_resv - swap_alloc);
-/* #endif defined(KERNEL_SOLARIS) */
+/* #endif HAVE_LIBKSTAT */
+
+#elif HAVE_SYS_SYSCTL_H
+       int mib[2];
+       struct xsw_usage sw_usage;
+       size_t           sw_usage_len;
+
+       mib[0] = CTL_VM;
+       mib[1] = VM_SWAPUSAGE;
+
+       sw_usage_len = sizeof (struct xsw_usage);
+
+       if (sysctl (mib, 2, &sw_usage, &sw_usage_len, NULL, 0) != 0)
+               return;
+
+       /* The returned values are bytes. */
+       swap_submit (sw_usage.xsu_used, sw_usage.xsu_avail, -1LL, -1LL);
+/* #endif HAVE_SYS_SYSCTL_H */
 
-#elif defined(HAVE_LIBSTATGRAB)
+#elif HAVE_LIBSTATGRAB
        sg_swap_stats *swap;
 
        if ((swap = sg_get_swap_stats ()) != NULL)
index 929589e..c7f7110 100644 (file)
  *
  * Authors:
  *   Florian octo Forster <octo at verplant.org>
+ *   Sune Marcher <sm at flork.dk>
  **/
 
 #include "collectd.h"
 #include "common.h"
 #include "plugin.h"
+#include "configfile.h"
 
 #if HAVE_SYS_TYPES_H
 #  include <sys/types.h>
 
 #define MODULE_NAME "traffic"
 
-#if HAVE_GETIFADDRS || defined(KERNEL_LINUX) || defined(HAVE_LIBKSTAT) || defined(HAVE_LIBSTATGRAB)
+/*
+ * Various people have reported problems with `getifaddrs' and varying versions
+ * of `glibc'. That's why it's disabled by default. Since more statistics are
+ * available this way one may enable it using the `--enable-getifaddrs' option
+ * of the configure script. -octo
+ */
+#if KERNEL_LINUX
+# if !COLLECT_GETIFADDRS
+#  undef HAVE_GETIFADDRS
+# endif /* !COLLECT_GETIFADDRS */
+#endif /* KERNEL_LINUX */
+
+#if HAVE_GETIFADDRS || KERNEL_LINUX || HAVE_LIBKSTAT || HAVE_LIBSTATGRAB
 # define TRAFFIC_HAVE_READ 1
 #else
 # define TRAFFIC_HAVE_READ 0
 
 #define BUFSIZE 512
 
-static char *traffic_filename_template = "traffic-%s.rrd";
+/*
+ * (Module-)Global variables
+ */
+/* TODO: Move this to `interface-%s/<blah>.rrd' in version 4. */
+static char *bytes_file   = "traffic-%s.rrd";
+static char *packets_file = "if_packets-%s.rrd";
+static char *errors_file  = "if_errors-%s.rrd";
+/* TODO: Maybe implement multicast and broadcast counters */
 
-static char *ds_def[] =
+static char *config_keys[] =
+{
+       "Ignore",
+       NULL
+};
+static int config_keys_num = 1;
+
+static char *bytes_ds_def[] =
 {
        "DS:incoming:COUNTER:"COLLECTD_HEARTBEAT":0:U",
        "DS:outgoing:COUNTER:"COLLECTD_HEARTBEAT":0:U",
        NULL
 };
-static int ds_num = 2;
+static int bytes_ds_num = 2;
+
+static char *packets_ds_def[] =
+{
+       "DS:rx:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+       "DS:tx:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+       NULL
+};
+static int packets_ds_num = 2;
+
+static char *errors_ds_def[] =
+{
+       "DS:rx:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+       "DS:tx:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+       NULL
+};
+static int errors_ds_num = 2;
+
+static char **if_ignore_list = NULL;
+static int    if_ignore_list_num = 0;
 
 #ifdef HAVE_LIBKSTAT
 #define MAX_NUMIF 256
@@ -72,6 +119,33 @@ static kstat_t *ksp[MAX_NUMIF];
 static int numif = 0;
 #endif /* HAVE_LIBKSTAT */
 
+static int traffic_config (char *key, char *value)
+{
+       char **temp;
+
+       if (strcasecmp (key, "Ignore") != 0)
+               return (-1);
+
+       temp = (char **) realloc (if_ignore_list, (if_ignore_list_num + 1) * sizeof (char *));
+       if (temp == NULL)
+       {
+               syslog (LOG_EMERG, "Cannot allocate more memory.");
+               return (1);
+       }
+       if_ignore_list = temp;
+
+       if ((if_ignore_list[if_ignore_list_num] = strdup (value)) == NULL)
+       {
+               syslog (LOG_EMERG, "Cannot allocate memory.");
+               return (1);
+       }
+       if_ignore_list_num++;
+
+       syslog (LOG_NOTICE, "traffic: Ignoring interface `%s'", value);
+
+       return (0);
+}
+
 static void traffic_init (void)
 {
 #if HAVE_GETIFADDRS
@@ -114,32 +188,112 @@ static void traffic_init (void)
        return;
 }
 
-static void traffic_write (char *host, char *inst, char *val)
+/*
+ * 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_if (const char *interface)
+{
+       int i;
+
+       for (i = 0; i < if_ignore_list_num; i++)
+               if (strcasecmp (interface, if_ignore_list[i]) == 0)
+                       return (1);
+       return (0);
+}
+
+static void generic_write (char *host, char *inst, char *val,
+               char *file_template,
+               char **ds_def, int ds_num)
 {
-       char file[BUFSIZE];
+       char file[512];
        int status;
 
-       status = snprintf (file, BUFSIZE, traffic_filename_template, inst);
+       if (check_ignore_if (inst))
+               return;
+
+       status = snprintf (file, BUFSIZE, file_template, inst);
        if (status < 1)
                return;
-       else if (status >= BUFSIZE)
+       else if (status >= 512)
                return;
 
        rrd_update_file (host, file, val, ds_def, ds_num);
 }
 
+static void bytes_write (char *host, char *inst, char *val)
+{
+       generic_write (host, inst, val, bytes_file, bytes_ds_def, bytes_ds_num);
+}
+
+static void packets_write (char *host, char *inst, char *val)
+{
+       generic_write (host, inst, val, packets_file, packets_ds_def, packets_ds_num);
+}
+
+static void errors_write (char *host, char *inst, char *val)
+{
+       generic_write (host, inst, val, errors_file, errors_ds_def, errors_ds_num);
+}
+
 #if TRAFFIC_HAVE_READ
-static void traffic_submit (char *device,
-               unsigned long long incoming,
-               unsigned long long outgoing)
+static void bytes_submit (char *dev,
+               unsigned long long rx,
+               unsigned long long tx)
+{
+       char buf[512];
+       int  status;
+
+       if (check_ignore_if (dev))
+               return;
+
+       status = snprintf (buf, 512, "%u:%lld:%lld",
+                               (unsigned int) curtime,
+                               rx, tx);
+       if ((status >= 512) || (status < 1))
+               return;
+
+       plugin_submit (MODULE_NAME, dev, buf);
+}
+
+#if HAVE_GETIFADDRS || KERNEL_LINUX || HAVE_LIBKSTAT
+static void packets_submit (char *dev,
+               unsigned long long rx,
+               unsigned long long tx)
+{
+       char buf[512];
+       int  status;
+
+       if (check_ignore_if (dev))
+               return;
+
+       status = snprintf (buf, 512, "%u:%lld:%lld",
+                       (unsigned int) curtime,
+                       rx, tx);
+       if ((status >= 512) || (status < 1))
+               return;
+       plugin_submit ("if_packets", dev, buf);
+}
+
+static void errors_submit (char *dev,
+               unsigned long long rx,
+               unsigned long long tx)
 {
-       char buf[BUFSIZE];
+       char buf[512];
+       int  status;
 
-       if (snprintf (buf, BUFSIZE, "%u:%lld:%lld", (unsigned int) curtime, incoming, outgoing) >= BUFSIZE)
+       if (check_ignore_if (dev))
                return;
 
-       plugin_submit (MODULE_NAME, device, buf);
+       status = snprintf (buf, 512, "%u:%lld:%lld",
+                       (unsigned int) curtime,
+                       rx, tx);
+       if ((status >= 512) || (status < 1))
+               return;
+       plugin_submit ("if_errors", dev, buf);
 }
+#endif /* HAVE_GETIFADDRS || KERNEL_LINUX || HAVE_LIBKSTAT */
 
 static void traffic_read (void)
 {
@@ -147,14 +301,25 @@ static void traffic_read (void)
        struct ifaddrs *if_list;
        struct ifaddrs *if_ptr;
 
+/* Darin/Mac OS X and possible other *BSDs */
 #if HAVE_STRUCT_IF_DATA
 #  define IFA_DATA if_data
-#  define IFA_INCOMING ifi_ibytes
-#  define IFA_OUTGOING ifi_obytes
+#  define IFA_RX_BYTES ifi_ibytes
+#  define IFA_TX_BYTES ifi_obytes
+#  define IFA_RX_PACKT ifi_ipackets
+#  define IFA_TX_PACKT ifi_opackets
+#  define IFA_RX_ERROR ifi_ierrors
+#  define IFA_TX_ERROR ifi_oerrors
+/* #endif HAVE_STRUCT_IF_DATA */
+
 #elif HAVE_STRUCT_NET_DEVICE_STATS
 #  define IFA_DATA net_device_stats
-#  define IFA_INCOMING rx_bytes
-#  define IFA_OUTGOING tx_bytes
+#  define IFA_RX_BYTES rx_bytes
+#  define IFA_TX_BYTES tx_bytes
+#  define IFA_RX_PACKT rx_packets
+#  define IFA_TX_PACKT tx_packets
+#  define IFA_RX_ERROR rx_errors
+#  define IFA_TX_ERROR tx_errors
 #else
 #  error "No suitable type for `struct ifaddrs->ifa_data' found."
 #endif
@@ -169,9 +334,15 @@ static void traffic_read (void)
                if ((if_data = (struct IFA_DATA *) if_ptr->ifa_data) == NULL)
                        continue;
 
-               traffic_submit (if_ptr->ifa_name,
-                               if_data->IFA_INCOMING,
-                               if_data->IFA_OUTGOING);
+               bytes_submit (if_ptr->ifa_name,
+                               if_data->IFA_RX_BYTES,
+                               if_data->IFA_TX_BYTES);
+               packets_submit (if_ptr->ifa_name,
+                               if_data->IFA_RX_PACKT,
+                               if_data->IFA_TX_PACKT);
+               errors_submit (if_ptr->ifa_name,
+                               if_data->IFA_RX_ERROR,
+                               if_data->IFA_TX_ERROR);
        }
 
        freeifaddrs (if_list);
@@ -195,9 +366,10 @@ static void traffic_read (void)
 
        while (fgets (buffer, 1024, fh) != NULL)
        {
-               if (buffer[6] != ':')
+               if (!(dummy = strchr(buffer, ':')))
                        continue;
-               buffer[6] = '\0';
+               dummy[0] = '\0';
+               dummy++;
 
                device = buffer;
                while (device[0] == ' ')
@@ -206,24 +378,31 @@ static void traffic_read (void)
                if (device[0] == '\0')
                        continue;
                
-               dummy = buffer + 7;
                numfields = strsplit (dummy, fields, 16);
 
-               if (numfields < 9)
+               if (numfields < 11)
                        continue;
 
                incoming = atoll (fields[0]);
                outgoing = atoll (fields[8]);
+               bytes_submit (device, incoming, outgoing);
 
-               traffic_submit (device, incoming, outgoing);
+               incoming = atoll (fields[1]);
+               incoming = atoll (fields[9]);
+               packets_submit (device, incoming, outgoing);
+
+               incoming = atoll (fields[2]);
+               incoming = atoll (fields[10]);
+               errors_submit (device, incoming, outgoing);
        }
 
        fclose (fh);
 /* #endif KERNEL_LINUX */
 
-#elif defined(HAVE_LIBKSTAT)
+#elif HAVE_LIBKSTAT
        int i;
-       unsigned long long incoming, outgoing;
+       unsigned long long rx;
+       unsigned long long tx;
 
        if (kc == NULL)
                return;
@@ -233,12 +412,20 @@ static void traffic_read (void)
                if (kstat_read (kc, ksp[i], NULL) == -1)
                        continue;
 
-               if ((incoming = get_kstat_value (ksp[i], "rbytes")) == -1LL)
-                       continue;
-               if ((outgoing = get_kstat_value (ksp[i], "obytes")) == -1LL)
-                       continue;
+               rx = get_kstat_value (ksp[i], "rbytes");
+               tx = get_kstat_value (ksp[i], "obytes");
+               if ((rx != -1LL) || (tx != -1LL))
+                       bytes_submit (ksp[i]->ks_name, rx, tx);
+
+               rx = get_kstat_value (ksp[i], "ipackets");
+               tx = get_kstat_value (ksp[i], "opackets");
+               if ((rx != -1LL) || (tx != -1LL))
+                       packets_submit (ksp[i]->ks_name, rx, tx);
 
-               traffic_submit (ksp[i]->ks_name, incoming, outgoing);
+               rx = get_kstat_value (ksp[i], "ierrors");
+               tx = get_kstat_value (ksp[i], "oerrors");
+               if ((rx != -1LL) || (tx != -1LL))
+                       errors_submit (ksp[i]->ks_name, rx, tx);
        }
 /* #endif HAVE_LIBKSTAT */
 
@@ -249,7 +436,7 @@ static void traffic_read (void)
        ios = sg_get_network_io_stats (&num);
 
        for (i = 0; i < num; i++)
-               traffic_submit (ios[i].interface_name, ios[i].rx, ios[i].tx);
+               bytes_submit (ios[i].interface_name, ios[i].rx, ios[i].tx);
 #endif /* HAVE_LIBSTATGRAB */
 }
 #else
@@ -258,7 +445,10 @@ static void traffic_read (void)
 
 void module_register (void)
 {
-       plugin_register (MODULE_NAME, traffic_init, traffic_read, traffic_write);
+       plugin_register (MODULE_NAME, traffic_init, traffic_read, bytes_write);
+       plugin_register ("if_packets", NULL, NULL, packets_write);
+       plugin_register ("if_errors",  NULL, NULL, errors_write);
+       cf_register (MODULE_NAME, traffic_config, config_keys, config_keys_num);
 }
 
 #undef BUFSIZE