users module by:
Sebastian Harl <sh at tokkee.org>
+vserver module by:
+ Sebastian Harl <sh at tokkee.org>
+
PID-file patch by:
Tommie Gannert <d00-tga at d.kth.se>
+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.
+ <http://linux-vserver.org/> Thanks to Sebastian Harl for writing
+ this plugin :)
+ * A plugin for wireless LAN cards has been added. It monitors signal
+ strength, link quality and noise ratio..
+ * An option to compile collectd with different `step' and `hearbeat'
+ settings has been added. The size of RRAs is no longer static but
+ calculated based on the settings for `step' and `width'.
+ * The `ping' plugin can now be configured to use a certain TTL.
+ * A plugin to monitor the hardware sensors of Apple computers has been
+ added.
+ * The plugins `cpu', `memory', `processes' and `traffic' have been
+ ported to Mach/Darwin (Mac OS X).
+
2006-04-09, Version 3.8.4
* Applied patch by Vincent Stehlé which improves the disk-name
resolution in the `hddtemp' plugin for Linux systems.
- Users
(Currently logged in users)
+ - VServer
+ (System ressources used by vservers)
+
* Performance: Running as a daemon collectd doesn't spend much time in
startup. Since collectd links against libping, librrd and libsensors it
doesn't need to start any other processes.
+src/apple_sensors.c: Check for more sensor types.
+src/battery.c: commend not working code.
+general: build Darwin package
+
+Near future:
+* Update the RPM specfile to
+ - build `collectd-apache'
+ - be free of syntax erros.
+
For version 3.*:
* Port nfs module to solaris
* Port tape module to Linux
* Maybe look into porting the serial module
+
+http://developer.apple.com/documentation/DeviceDrivers/Conceptual/AccessingHardware/AH_IOKitLib_API/chapter_5_section_1.html
+http://developer.apple.com/documentation/DeviceDrivers/Conceptual/IOKitFundamentals/index.html#//apple_ref/doc/uid/TP0000011
+http://www.gauchosoft.com/Software/X%20Resource%20Graph/
+http://johannes.sipsolutions.net/PowerBook/Apple_Motion_Sensor_Specification/
Summary: Statistics collection daemon for filling RRD files.
Name: collectd
-Version: 3.8.4
+Version: 3.9.0
Release: 1
Source: http://verplant.org/collectd/%{name}-%{version}.tar.gz
License: GPL
%attr(0444,root,root) %{_libdir}/%{name}/tape.so*
%attr(0444,root,root) %{_libdir}/%{name}/traffic.so*
%attr(0444,root,root) %{_libdir}/%{name}/users.so*
+%attr(0444,root,root) %{_libdir}/%{name}/vserver.so*
+%attr(0444,root,root) %{_libdir}/%{name}/wireless.so*
%dir /var/lib/collectd
%files mysql
%attr(0444,root,root) %{_libdir}/%{name}/sensors.so*
%changelog
-* Sun Apr 09 2006 Florian octo Forster <octo@verplant.org> 3.8.4-1
-- New upstream version
-
-* Sun Apr 02 2006 Florian octo Forster <octo@verplant.org> 3.8.3-1
+* Thu Mar 21 2006 Florian octo Forster <octo@verplant.org> 3.9.0-1
- New upstream version
* Thu Mar 14 2006 Florian octo Forster <octo@verplant.org> 3.8.2-1
dnl Process this file with autoconf to produce a configure script.
-AC_INIT(collectd, 3.8.4)
+AC_INIT(collectd, 3.9.0-alpha1)
AC_CONFIG_SRCDIR(src/collectd.c)
AC_CONFIG_HEADERS(src/config.h)
AM_INIT_AUTOMAKE(dist-bzip2)
AC_HEADER_SYS_WAIT
AC_HEADER_DIRENT
AC_CHECK_HEADERS(stdint.h)
+AC_CHECK_HEADERS(stdio.h)
AC_CHECK_HEADERS(errno.h)
+AC_CHECK_HEADERS(math.h)
AC_CHECK_HEADERS(syslog.h)
AC_CHECK_HEADERS(fcntl.h)
AC_CHECK_HEADERS(signal.h)
# For cpu modules
AC_CHECK_HEADERS(sys/sysctl.h sys/dkstat.h)
+AC_CHECK_HEADERS(mach/mach_init.h)
+AC_CHECK_HEADERS(mach/host_priv.h)
+AC_CHECK_HEADERS(mach/mach_error.h)
+AC_CHECK_HEADERS(mach/mach_host.h)
+AC_CHECK_HEADERS(mach/mach_port.h)
+AC_CHECK_HEADERS(mach/mach_types.h)
+AC_CHECK_HEADERS(mach/message.h)
+AC_CHECK_HEADERS(mach/processor_set.h)
+AC_CHECK_HEADERS(mach/processor.h)
+AC_CHECK_HEADERS(mach/processor_info.h)
+AC_CHECK_HEADERS(mach/task.h)
+AC_CHECK_HEADERS(mach/thread_act.h)
+AC_CHECK_HEADERS(mach/vm_region.h)
+AC_CHECK_HEADERS(mach/vm_map.h)
+AC_CHECK_HEADERS(mach/vm_prot.h)
+AC_CHECK_HEADERS(mach/vm_statistics.h)
+AC_CHECK_HEADERS(mach/kern_return.h)
# For hddtemp module
AC_CHECK_HEADERS(linux/major.h)
+# For the apple_sensors module
+AC_CHECK_HEADERS(CoreFoundation/CoreFoundation.h)
+AC_CHECK_HEADERS(IOKit/IOKitLib.h)
+AC_CHECK_HEADERS(IOKit/IOTypes.h)
+
+# For the battery plugin
+AC_CHECK_HEADERS(IOKit/ps/IOPowerSources.h, [], [],
+[
+#if HAVE_IOKIT_IOKITLIB_H
+# include <IOKit/IOKitLib.h>
+#endif
+#if HAVE_IOKIT_IOTYPES_H
+# include <IOKit/IOTypes.h>
+#endif
+])
+AC_CHECK_HEADERS(IOKit/ps/IOPSKeys.h)
+
# For load module
AC_CHECK_HEADERS(sys/loadavg.h)
AC_CHECK_HEADERS(utmp.h)
AC_CHECK_HEADERS(utmpx.h)
+# For traffic plugin
+AC_CHECK_HEADERS(ifaddrs.h)
+AC_CHECK_HEADERS(net/if.h, [], [],
+[
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
+])
+AC_CHECK_HEADERS(linux/if.h, [], [],
+[
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
+])
+AC_CHECK_HEADERS(linux/netdevice.h, [], [],
+[
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
+#if HAVE_LINUX_IF_H
+# include <linux/if.h>
+#endif
+])
+
+# For apache plugin
+AC_CHECK_HEADERS(curl/curl.h)
+
# For quota module
AC_CHECK_HEADERS(grp.h pwd.h sys/ucred.h)
AC_CHECK_HEADERS(ctype.h)
# For load module
AC_CHECK_FUNCS(getloadavg, [have_getloadavg="yes"], [have_getloadavg="no"])
+# For the `processes' plugin
+AC_CHECK_FUNCS(thread_info)
+
# For users module
AC_CHECK_FUNCS(getutent getutxent)
AC_CHECK_FUNCS(quotactl)
AC_CHECK_FUNCS(getgrgid getpwuid)
+# For traffic module
+AC_CHECK_FUNCS(getifaddrs)
+
# For mount interface
AC_CHECK_FUNCS(getfsent getvfsent listmntent)
AC_CHECK_FUNCS(getfsstat)
)
fi
+# Check for structures
+AC_CHECK_MEMBERS([struct if_data.ifi_ibytes, struct if_data.ifi_obytes],
+ [AC_DEFINE(HAVE_STRUCT_IF_DATA, 1, [Define if struct if_data exists and is usable.])],
+ [],
+ [
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <net/if.h>
+ ])
+AC_CHECK_MEMBERS([struct net_device_stats.rx_bytes, struct net_device_stats.tx_bytes],
+ [AC_DEFINE(HAVE_STRUCT_NET_DEVICE_STATS, 1, [Define if struct net_device_stats exists and is usable.])],
+ [],
+ [
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <linux/if.h>
+ #include <linux/netdevice.h>
+ ])
+
AC_MSG_CHECKING([for kernel type ($host_os)])
case $host_os in
*linux*)
- AC_DEFINE([KERNEL_LINUX], [], [True if program is to be compiled for a Linux kernel])
+ AC_DEFINE([KERNEL_LINUX], 1, [True if program is to be compiled for a Linux kernel])
ac_system="Linux"
;;
*solaris*)
- AC_DEFINE([KERNEL_SOLARIS], [], [True if program is to be compiled for a Solaris kernel])
+ AC_DEFINE([KERNEL_SOLARIS], 1, [True if program is to be compiled for a Solaris kernel])
ac_system="Solaris"
;;
*)
[with_libresolv="no"])
AM_CONDITIONAL(BUILD_WITH_LIBRESOLV, test "x$with_libresolv" = "xyes")
+
m4_divert_once([HELP_WITH], [
collectd additional packages:])
[Wether or not to use kstat library (Solaris)])
AM_CONDITIONAL(BUILD_WITH_KSTAT, test "x$with_kstat" = "xyes")
+### BEGIN of check for libcurl ###
+with_curl_config="curl-config"
+with_curl_prefix=0
+with_curl_libs=""
+AC_ARG_WITH(libcurl, [AS_HELP_STRING([--with-libcurl@<:@=PREFIX@:>@], [Path to libcurl.])],
+[
+ if test "x$withval" != "xno" -a "x$withval" != "xyes"
+ then
+ if test -x "$withval/bin/curl-config"
+ then
+ with_curl_config="$withval/bin/curl-config"
+ with_curl_prefix=1
+ fi
+ fi
+ if test "x$withval" = "xno"
+ then
+ with_libcurl="no"
+ else
+ with_libcurl="yes"
+ fi
+],
+[
+ with_libcurl="yes"
+])
+if test "x$with_libcurl" = "xyes"
+then
+ with_curl_libs=`$with_curl_config --libs 2>/dev/null`
+ curl_config_status=$?
+
+ if test $curl_config_status -ne 0
+ then
+ with_libcurl="no"
+ else
+ AC_CHECK_LIB(curl, curl_easy_init,
+ [
+ BUILD_WITH_LIBCURL_LIBS="$with_curl_libs"
+ AC_SUBST(BUILD_WITH_LIBCURL_LIBS)
+ ],
+ [
+ with_libcurl="no"
+ ],
+ [$with_curl_libs])
+ fi
+fi
+if test "x$with_libcurl" = "xyes" -a $with_curl_prefix -ne 0
+then
+ with_curl_prefix=`$with_curl_config --libs 2>/dev/null`
+ curl_config_status=$?
+
+ if test $curl_config_status -ne 0
+ then
+ with_libcurl="no"
+ else
+ if test -d "$with_curl_prefix/include"
+ then
+ CPPFLAGS="$CPPFLAGS -I$with_curl_prefix/include"
+ fi
+ fi
+fi
+
+with_libcurl_numeric=0
+if test "x$with_libcurl" = "xyes"
+then
+ with_libcurl_numeric=1
+fi
+AC_DEFINE_UNQUOTED(HAVE_LIBCURL, [$with_libcurl_numeric], [Define to 1 if you have the 'curl' library (-lcurl).])
+AM_CONDITIONAL(BUILD_WITH_LIBCURL, test "x$with_libcurl" = "xyes")
+### END of check for libcurl ###
+
+with_libiokit="no"
+collectd_libiokit=0
+AC_CHECK_LIB(IOKit, IOServiceGetMatchingServices,
+[
+ with_libiokit="yes"
+ collectd_libiokit=1
+],
+[
+ with_libiokit="no"
+ collectd_libiokit=0
+])
+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")
+
AC_ARG_WITH(libstatgrab, [AS_HELP_STRING([--with-libstatgrab@<:@=PREFIX@:>@], [Path to libstatgrab.])],
[
- if test "x$withval" != "xno" && test "x$withval" != "xyes"
+ if test "x$withval" != "xno" -a "x$withval" != "xyes"
then
LDFLAGS="$LDFLAGS -L$withval/lib"
CPPFLAGS="$CPPFLAGS -I$withval/include"
[Wether or not to use mysql library])
AM_CONDITIONAL(BUILD_WITH_LIBMYSQL, test "x$with_libmysql" = "xyes")
+# Define `step' and `hearbeat' values..
+declare -i collectd_step=10
+declare -i collectd_heartbeat=25
+AC_ARG_WITH(step, [AS_HELP_STRING([--with-step=SECONDS], [Interval in which plugins are queried.])],
+[
+ if test "x$withval" != "xno" -a "x$withval" != "xyes"
+ then
+ declare -i tmp_collectd_step="$withval"
+ if test $tmp_collectd_step -gt 0
+ then
+ collectd_step=$tmp_collectd_step
+ let "collectd_heartbeat=$collectd_step*2"
+ fi
+ fi
+], [])
+AC_ARG_WITH(heartbeat, [AS_HELP_STRING([--with-heartbeat=SECONDS], [Heartbeat of the DS in generated RRD files.])],
+[
+ if test "x$withval" != "xno" -a "x$withval" != "xyes"
+ then
+ declare -i tmp_collectd_heartbeat="$withval"
+ if test $tmp_collectd_heartbeat -gt 0
+ then
+ collectd_heartbeat=$tmp_collectd_heartbeat
+ fi
+ fi
+], [])
+
+if test $collectd_step -ne 10
+then
+ AC_DEFINE_UNQUOTED(COLLECTD_STEP, "$collectd_step", [Interval in which plugins are queried.])
+fi
+if test $collectd_heartbeat -ne 25
+then
+ AC_DEFINE_UNQUOTED(COLLECTD_HEARTBEAT, "$collectd_heartbeat", [Interval in which plugins are queried.])
+fi
+
#
# Check for enabled/disabled features
#
m4_divert_once([HELP_ENABLE], [
collectd modules:])
+AC_COLLECTD([apache], [disable], [module], [Apache httpd statistics])
+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])
AC_COLLECTD([cpufreq], [disable], [module], [system cpu frequency statistics])
AC_COLLECTD([tape], [disable], [module], [tape statistics])
AC_COLLECTD([traffic], [disable], [module], [system traffic statistics])
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], [
Configuration:
Libraries:
+ libcurl . . . . . . $with_libcurl
+ libiokit . . . . . $with_libiokit
librrd . . . . . . $with_rrdtool
lm_sensors . . . . $with_lm_sensors
libstatgrab . . . . $with_libstatgrab
Features:
debug . . . . . . . $enable_debug
daemon mode . . . . $enable_daemon
+ step . . . . . . . $collectd_step seconds
+ heartbeat . . . . . $collectd_heartbeat seconds
Modules:
+ apache . . . . . . $enable_apache
+ apple_sensors . . . $enable_apple_sensors
battery . . . . . . $enable_battery
cpu . . . . . . . . $enable_cpu
cpufreq . . . . . . $enable_cpufreq
tape . . . . . . . $enable_tape
traffic . . . . . . $enable_traffic
users . . . . . . . $enable_users
+ vserver . . . . . . $enable_vserver
wireless . . . . . $enable_wireless
EOF
PIDFile /var/run/collectd.pid
PluginDir /usr/lib/collectd
+#LoadPlugin apache
+#LoadPlugin battery
LoadPlugin cpu
LoadPlugin cpufreq
LoadPlugin df
LoadPlugin disk
+#LoadPlugin hddtemp
LoadPlugin load
LoadPlugin memory
+#LoadPlugin mysql
LoadPlugin nfs
LoadPlugin ping
LoadPlugin processes
+#LoadPlugin sensors
LoadPlugin serial
LoadPlugin swap
LoadPlugin traffic
LoadPlugin users
-#LoadPlugin hddtemp
-#LoadPlugin mysql
-#LoadPlugin sensors
+#LoadPlugin vserver
+
+#<Plugin apache>
+# URL http://localhost/status?auto
+# User www-user
+# Password secret
+#</Plugin>
#<Plugin ping>
# Host host.foo.bar
$GraphDefs =
{
+ apache_bytes => ['DEF:min_raw={file}:count:MIN',
+ 'DEF:avg_raw={file}:count:AVERAGE',
+ 'DEF:max_raw={file}:count:MAX',
+ 'CDEF:min=min_raw,8,*',
+ 'CDEF:avg=avg_raw,8,*',
+ 'CDEF:max=max_raw,8,*',
+ 'CDEF:mytime=avg_raw,TIME,TIME,IF',
+ 'CDEF:sample_len_raw=mytime,PREV(mytime),-',
+ 'CDEF:sample_len=sample_len_raw,UN,0,sample_len_raw,IF',
+ 'CDEF:avg_sample=avg_raw,UN,0,avg_raw,IF,sample_len,*',
+ 'CDEF:avg_sum=PREV,UN,0,PREV,IF,avg_sample,+',
+ "AREA:avg#$HalfBlue",
+ "LINE1:avg#$FullBlue:Bit/s",
+ 'GPRINT:min:MIN:%5.1lf%s Min,',
+ 'GPRINT:avg:AVERAGE:%5.1lf%s Avg,',
+ 'GPRINT:max:MAX:%5.1lf%s Max,',
+ 'GPRINT:avg:LAST:%5.1lf%s Last',
+ 'GPRINT:avg_sum:LAST:(ca. %5.1lf%sB Total)\l'
+ ],
+ apache_requests => ['DEF:min={file}:count:MIN',
+ 'DEF:avg={file}:count:AVERAGE',
+ 'DEF:max={file}:count:MAX',
+ "AREA:max#$HalfBlue",
+ "AREA:min#$Canvas",
+ "LINE1:avg#$FullBlue:Requests/s",
+ 'GPRINT:min:MIN:%6.2lf Min,',
+ 'GPRINT:avg:AVERAGE:%6.2lf Avg,',
+ 'GPRINT:max:MAX:%6.2lf Max,',
+ 'GPRINT:avg:LAST:%6.2lf Last'
+ ],
+ apache_scoreboard => ['DEF:min={file}:count:MIN',
+ 'DEF:avg={file}:count:AVERAGE',
+ 'DEF:max={file}:count:MAX',
+ "AREA:max#$HalfBlue",
+ "AREA:min#$Canvas",
+ "LINE1:avg#$FullBlue:Processes",
+ 'GPRINT:min:MIN:%6.2lf Min,',
+ 'GPRINT:avg:AVERAGE:%6.2lf Avg,',
+ 'GPRINT:max:MAX:%6.2lf Max,',
+ 'GPRINT:avg:LAST:%6.2lf Last'
+ ],
charge => [
'DEF:avg={file}:charge:AVERAGE',
'DEF:min={file}:charge:MIN',
'DEF:free_max={file}:free:MAX',
'DEF:buffers_max={file}:buffers:MAX',
'DEF:cached_max={file}:cached:MAX',
- 'CDEF:free_cached_buffers_used=free_avg,cached_avg,+,buffers_avg,+,used_avg,+',
- 'CDEF:cached_buffers_used=cached_avg,buffers_avg,+,used_avg,+',
+ 'CDEF:cached_avg_nn=cached_avg,UN,0,cached_avg,IF',
+ 'CDEF:buffers_avg_nn=buffers_avg,UN,0,buffers_avg,IF',
+ 'CDEF:free_cached_buffers_used=free_avg,cached_avg_nn,+,buffers_avg_nn,+,used_avg,+',
+ 'CDEF:cached_buffers_used=cached_avg,buffers_avg_nn,+,used_avg,+',
'CDEF:buffers_used=buffers_avg,used_avg,+',
"AREA:free_cached_buffers_used#$HalfGreen",
"AREA:cached_buffers_used#$HalfBlue",
'GPRINT:avg:AVERAGE:%5.1lf%sV Avg,',
'GPRINT:max:MAX:%5.1lf%sV Max,',
'GPRINT:avg:LAST:%5.1lf%sV Last\l'
- ]
+ ],
+ threads => [
+ "DEF:total_avg={file}:total:AVERAGE",
+ "DEF:total_min={file}:total:MIN",
+ "DEF:total_max={file}:total:MAX",
+ "DEF:running_avg={file}:running:AVERAGE",
+ "DEF:running_min={file}:running:MIN",
+ "DEF:running_max={file}:running:MAX",
+ "DEF:uninterruptible_avg={file}:uninterruptible:AVERAGE",
+ "DEF:uninterruptible_min={file}:uninterruptible:MIN",
+ "DEF:uninterruptible_max={file}:uninterruptible:MAX",
+ "DEF:onhold_avg={file}:onhold:AVERAGE",
+ "DEF:onhold_min={file}:onhold:MIN",
+ "DEF:onhold_max={file}:onhold:MAX",
+ "LINE1:total_avg#$FullYellow:Total ",
+ 'GPRINT:total_min:MIN:%5.1lf Min,',
+ 'GPRINT:total_avg:AVERAGE:%5.1lf Avg.,',
+ 'GPRINT:total_max:MAX:%5.1lf Max,',
+ 'GPRINT:total_avg:LAST:%5.1lf Last\l',
+ "LINE1:running_avg#$FullRed:Running ",
+ 'GPRINT:running_min:MIN:%5.1lf Min,',
+ 'GPRINT:running_avg:AVERAGE:%5.1lf Avg.,',
+ 'GPRINT:running_max:MAX:%5.1lf Max,',
+ 'GPRINT:running_avg:LAST:%5.1lf Last\l',
+ "LINE1:uninterruptible_avg#$FullGreen:Unintr ",
+ 'GPRINT:uninterruptible_min:MIN:%5.1lf Min,',
+ 'GPRINT:uninterruptible_avg:AVERAGE:%5.1lf Avg.,',
+ 'GPRINT:uninterruptible_max:MAX:%5.1lf Max,',
+ 'GPRINT:uninterruptible_avg:LAST:%5.1lf Last\l',
+ "LINE1:onhold_avg#$FullBlue:Onhold ",
+ 'GPRINT:onhold_min:MIN:%5.1lf Min,',
+ 'GPRINT:onhold_avg:AVERAGE:%5.1lf Avg.,',
+ 'GPRINT:onhold_max:MAX:%5.1lf Max,',
+ 'GPRINT:onhold_avg:LAST:%5.1lf Last\l'
+ ],
+ vs_memory => [
+ 'DEF:vm_avg={file}:vm:AVERAGE',
+ 'DEF:vm_min={file}:vm:MIN',
+ 'DEF:vm_max={file}:vm:MAX',
+ 'DEF:vml_avg={file}:vml:AVERAGE',
+ 'DEF:vml_min={file}:vml:MIN',
+ 'DEF:vml_max={file}:vml:MAX',
+ 'DEF:rss_avg={file}:rss:AVERAGE',
+ 'DEF:rss_min={file}:rss:MIN',
+ 'DEF:rss_max={file}:rss:MAX',
+ 'DEF:anon_avg={file}:anon:AVERAGE',
+ 'DEF:anon_min={file}:anon:MIN',
+ 'DEF:anon_max={file}:anon:MAX',
+ "LINE1:vm_avg#$FullYellow:VM ",
+ 'GPRINT:vm_min:MIN:%5.1lf%s Min,',
+ 'GPRINT:vm_avg:AVERAGE:%5.1lf%s Avg.,',
+ 'GPRINT:vm_max:MAX:%5.1lf%s Avg.,',
+ 'GPRINT:vm_avg:LAST:%5.1lf%s Last\l',
+ "LINE1:vml_avg#$FullRed:Locked ",
+ 'GPRINT:vml_min:MIN:%5.1lf%s Min,',
+ 'GPRINT:vml_avg:AVERAGE:%5.1lf%s Avg.,',
+ 'GPRINT:vml_max:MAX:%5.1lf%s Avg.,',
+ 'GPRINT:vml_avg:LAST:%5.1lf%s Last\l',
+ "LINE1:rss_avg#$FullGreen:RSS ",
+ 'GPRINT:rss_min:MIN:%5.1lf%s Min,',
+ 'GPRINT:rss_avg:AVERAGE:%5.1lf%s Avg.,',
+ 'GPRINT:rss_max:MAX:%5.1lf%s Avg.,',
+ 'GPRINT:rss_avg:LAST:%5.1lf%s Last\l',
+ "LINE1:anon_avg#$FullBlue:Anon. ",
+ 'GPRINT:anon_min:MIN:%5.1lf%s Min,',
+ 'GPRINT:anon_avg:AVERAGE:%5.1lf%s Avg.,',
+ 'GPRINT:anon_max:MAX:%5.1lf%s Avg.,',
+ 'GPRINT:anon_avg:LAST:%5.1lf%s Last\l',
+ ],
+ vs_processes => [
+ 'DEF:proc_avg={file}:total:AVERAGE',
+ 'DEF:proc_min={file}:total:MIN',
+ 'DEF:proc_max={file}:total:MAX',
+ "AREA:proc_max#$HalfBlue",
+ "AREA:proc_min#$Canvas",
+ "LINE1:proc_avg#$FullBlue:Processes",
+ 'GPRINT:proc_min:MIN:%4.1lf Min,',
+ 'GPRINT:proc_avg:AVERAGE:%4.1lf Avg.,',
+ 'GPRINT:proc_max:MAX:%4.1lf Max,',
+ 'GPRINT:proc_avg:LAST:%4.1lf Last\l'
+ ],
};
$GraphDefs->{'disk'} = $GraphDefs->{'partition'};
$GraphDefs->{'meminfo'} = $GraphDefs->{'memory'};
our $GraphArgs =
{
+ apache_bytes => ['-t', 'apache traffic', '-v', 'Bit/s'],
+ apache_requests => ['-t', 'apache requests', '-v', 'Requests/s'],
+ apache_scoreboard => ['-t', 'apache scoreboard {inst}', '-v', 'Processes'],
charge => ['-t', '{host} charge', '-v', 'Ampere hours'],
cpu => ['-t', '{host} cpu{inst} usage', '-v', 'Percent', '-l', '0'],
cpufreq => ['-t', '{host} cpu{inst} usage', '-v', 'Mhz'],
swap => ['-t', '{host} swap usage', '-v', 'Bytes', '-b', '1024', '-l', '0'],
traffic => ['-t', '{host} {inst} traffic', '-v', 'Bit/s'],
users => ['-t', '{host} users', '-v', 'Users'],
- voltage => ['-t', '{host} voltage', '-v', 'Volts']
+ voltage => ['-t', '{host} voltage', '-v', 'Volts'],
+ threads => ['-t', '{host} threads', '-v', 'Threads'],
+ vs_memory => ['-t', '{host} memory usage', '-v', 'Bytes'],
+ vs_processes => ['-t', '{host} processes', '-v', 'Processes'],
};
our $GraphMulti =
{
+ apache_scoreboard => \&output_graph_apache_scoreboard,
cpu => \&output_graph_cpu,
cpufreq => 1,
disk => 1,
return (@ret);
}
+sub output_graph_apache_scoreboard
+{
+ my @inst = @_;
+ my @ret = ();
+
+ die if (@inst < 2);
+
+ my @colors = get_n_colors (scalar (@inst));
+
+ for (my $i = 0; $i < scalar (@inst); $i++)
+ {
+ my $inst = $inst[$i];
+ push (@ret,
+ "DEF:avg_$i=$AbsDir/apache_scoreboard-$inst.rrd:count:AVERAGE",
+ "DEF:min_$i=$AbsDir/apache_scoreboard-$inst.rrd:count:MIN",
+ "DEF:max_$i=$AbsDir/apache_scoreboard-$inst.rrd:count:MAX");
+ }
+
+ for (my $i = 0; $i < scalar (@inst); $i++)
+ {
+ my $inst = $inst[$i];
+ my $color = $colors[$i];
+
+ if (length ($inst) > 15)
+ {
+ $inst = substr ($inst, 0, 12) . '...';
+ }
+ else
+ {
+ $inst = sprintf ('%-15s', $inst);
+ }
+
+ push (@ret,
+ "LINE1:avg_$i#$color:$inst",
+ "GPRINT:min_$i:MIN:%6.2lf Min,",
+ "GPRINT:avg_$i:AVERAGE:%6.2lf Avg,",
+ "GPRINT:max_$i:MAX:%6.2lf Max,",
+ "GPRINT:avg_$i:LAST:%6.2lf Last\\l");
+ }
+
+ return (@ret);
+}
+
sub output_graph_ping
{
my @inst = @_;
$Inst = $files->{$Type}[0];
}
+ #push (@cmd, '-', '-a', 'PNG', '-s', $TimeSpan, '-w', 800, '-h', 150);
push (@cmd, '-', '-a', 'PNG', '-s', $TimeSpan);
push (@cmd, @{$GraphArgs->{$Type}}) if (defined ($GraphArgs->{$Type}));
print <<HTML;
</ul>
+ <h3>Hourly</h3>
+ <div><img src="$MySelf$RelDir/$Type/hour" /></div>
<h3>Daily</h3>
<div><img src="$MySelf$RelDir/$Type/day" /></div>
<h3>Weekly</h3>
}
print <<HTML;
+ <h3>Hourly</h3>
+ <div><img src="$MySelf$RelDir/$ext/hour" /></div>
<h3>Daily</h3>
<div><img src="$MySelf$RelDir/$ext/day" /></div>
<h3>Weekly</h3>
-collectd (3.8.4-1) unstable; urgency=low
+collectd (3.9.0-1) unstable; urgency=low
* New upstream version
- -- Florian Forster <octo@verplant.org> Sun, 9 Apr 2006 16:01:11 +0200
-
-collectd (3.8.3-1) unstable; urgency=low
-
- * New upstream version
-
- -- Florian Forster <octo@verplant.org> Sun, 2 Apr 2006 10:34:05 +0200
+ -- Florian Forster <octo@verplant.org> Tue, 21 Mar 2006 22:52:54 +0200
collectd (3.8.2-1) unstable; urgency=low
--- /dev/null
+usr/lib/collectd/apache.so*
Section: utils
Priority: optional
Maintainer: Florian Forster <octo@verplant.org>
-Build-Depends: debhelper (>= 4.0.0), autotools-dev, librrd0-dev | librrd2-dev, libsensors-dev, libmysqlclient14-dev
+Build-Depends: debhelper (>= 4.0.0), autotools-dev, librrd0-dev | librrd2-dev, libsensors-dev, libmysqlclient14-dev, libcurl3-dev
Standards-Version: 3.6.1
Package: collectd
it's very fast and easy on the system. Also, the statistics are very fine
grained since the files are updated every 10 seconds.
+Package: collectd-apache
+Architecture: any
+Depends: collectd (= ${Source-Version}), apache2 | apache, libcurl3
+Description: collectd plugin for Apache-statistics
+ collectd module to collect Apache statistics. It reads the page generated by
+ `mod_status' and writes it's content into RRD files.
+
Package: collectd-mysql
Architecture: any
Depends: collectd (= ${Source-Version}), libmysqlclient14
CFLAGS = -Wall -g
-PLUGINS = mysql sensors
+PLUGINS = apache mysql sensors
ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
CFLAGS += -O0
pkglib_LTLIBRARIES =
+if BUILD_MODULE_APACHE
+pkglib_LTLIBRARIES += apache.la
+apache_la_SOURCES = apache.c
+apache_la_LDFLAGS = -module -avoid-version
+if BUILD_WITH_LIBCURL
+apache_la_LDFLAGS += $(BUILD_WITH_LIBCURL_LIBS)
+endif
+collectd_LDADD += "-dlopen" apache.la
+collectd_DEPENDENCIES += apache.la
+endif
+
+if BUILD_MODULE_APPLE_SENSORS
+pkglib_LTLIBRARIES += apple_sensors.la
+apple_sensors_la_SOURCES = apple_sensors.c
+apple_sensors_la_LDFLAGS = -module -avoid-version
+if BUILD_WITH_LIBIOKIT
+apple_sensors_la_LDFLAGS += -lIOKit
+endif
+collectd_LDADD += "-dlopen" apple_sensors.la
+collectd_DEPENDENCIES += apple_sensors.la
+endif
+
if BUILD_MODULE_BATTERY
pkglib_LTLIBRARIES += battery.la
battery_la_SOURCES = battery.c
battery_la_LDFLAGS = -module -avoid-version
+if BUILD_WITH_LIBIOKIT
+battery_la_LDFLAGS += -lIOKit
+endif
collectd_LDADD += "-dlopen" battery.la
collectd_DEPENDENCIES += battery.la
endif
if BUILD_MODULE_CPU
pkglib_LTLIBRARIES += cpu.la
-cpu_la_SOURCES = cpu.c cpu.h
+cpu_la_SOURCES = cpu.c
cpu_la_LDFLAGS = -module -avoid-version
collectd_LDADD += "-dlopen" cpu.la
collectd_DEPENDENCIES += cpu.la
if BUILD_MODULE_CPUFREQ
pkglib_LTLIBRARIES += cpufreq.la
-cpufreq_la_SOURCES = cpufreq.c cpufreq.h
+cpufreq_la_SOURCES = cpufreq.c
cpufreq_la_LDFLAGS = -module -avoid-version
collectd_LDADD += "-dlopen" cpufreq.la
collectd_DEPENDENCIES += cpufreq.la
if BUILD_MODULE_DISK
pkglib_LTLIBRARIES += disk.la
-disk_la_SOURCES = disk.c disk.h
+disk_la_SOURCES = disk.c
disk_la_LDFLAGS = -module -avoid-version
collectd_LDADD += "-dlopen" disk.la
collectd_DEPENDENCIES += disk.la
if BUILD_MODULE_HDDTEMP
pkglib_LTLIBRARIES += hddtemp.la
-hddtemp_la_SOURCES = hddtemp.c hddtemp.h
+hddtemp_la_SOURCES = hddtemp.c
hddtemp_la_LDFLAGS = -module -avoid-version
collectd_LDADD += "-dlopen" hddtemp.la
collectd_DEPENDENCIES += hddtemp.la
if BUILD_MODULE_LOAD
pkglib_LTLIBRARIES += load.la
-load_la_SOURCES = load.c load.h
+load_la_SOURCES = load.c
load_la_LDFLAGS = -module -avoid-version
collectd_LDADD += "-dlopen" load.la
collectd_DEPENDENCIES += load.la
if BUILD_MODULE_MEMORY
pkglib_LTLIBRARIES += memory.la
-memory_la_SOURCES = memory.c memory.h
+memory_la_SOURCES = memory.c
memory_la_LDFLAGS = -module -avoid-version
collectd_LDADD += "-dlopen" memory.la
collectd_DEPENDENCIES += memory.la
if BUILD_MODULE_NFS
pkglib_LTLIBRARIES += nfs.la
-nfs_la_SOURCES = nfs.c nfs.h
+nfs_la_SOURCES = nfs.c
nfs_la_LDFLAGS = -module -avoid-version
collectd_LDADD += "-dlopen" nfs.la
collectd_DEPENDENCIES += nfs.la
if BUILD_MODULE_PING
pkglib_LTLIBRARIES += ping.la
-ping_la_SOURCES = ping.c ping.h
+ping_la_SOURCES = ping.c
ping_la_LDFLAGS = -module -avoid-version
ping_la_LIBADD = liboping/liboping.la
ping_la_DEPENDENCIES = liboping/liboping.la
if BUILD_MODULE_PROCESSES
pkglib_LTLIBRARIES += processes.la
-processes_la_SOURCES = processes.c processes.h
+processes_la_SOURCES = processes.c
processes_la_LDFLAGS = -module -avoid-version
collectd_LDADD += "-dlopen" processes.la
collectd_DEPENDENCIES += processes.la
if BUILD_MODULE_SENSORS
pkglib_LTLIBRARIES += sensors.la
-sensors_la_SOURCES = sensors.c sensors.h
+sensors_la_SOURCES = sensors.c
sensors_la_LDFLAGS = -module -avoid-version
if BUILD_WITH_LM_SENSORS
sensors_la_LDFLAGS += -lsensors
if BUILD_MODULE_SERIAL
pkglib_LTLIBRARIES += serial.la
-serial_la_SOURCES = serial.c serial.h
+serial_la_SOURCES = serial.c
serial_la_LDFLAGS = -module -avoid-version
collectd_LDADD += "-dlopen" serial.la
collectd_DEPENDENCIES += serial.la
if BUILD_MODULE_SWAP
pkglib_LTLIBRARIES += swap.la
-swap_la_SOURCES = swap.c swap.h
+swap_la_SOURCES = swap.c
swap_la_LDFLAGS = -module -avoid-version
collectd_LDADD += "-dlopen" swap.la
collectd_DEPENDENCIES += swap.la
if BUILD_MODULE_TAPE
pkglib_LTLIBRARIES += tape.la
-tape_la_SOURCES = tape.c tape.h
+tape_la_SOURCES = tape.c
tape_la_LDFLAGS = -module -avoid-version
collectd_LDADD += "-dlopen" tape.la
collectd_DEPENDENCIES += tape.la
if BUILD_MODULE_TRAFFIC
pkglib_LTLIBRARIES += traffic.la
-traffic_la_SOURCES = traffic.c traffic.h
+traffic_la_SOURCES = traffic.c
traffic_la_LDFLAGS = -module -avoid-version
collectd_LDADD += "-dlopen" traffic.la
collectd_DEPENDENCIES += traffic.la
if BUILD_MODULE_USERS
pkglib_LTLIBRARIES += users.la
-users_la_SOURCES = users.c users.h
+users_la_SOURCES = users.c
users_la_LDFLAGS = -module -avoid-version
collectd_LDADD += "-dlopen" users.la
collectd_DEPENDENCIES += users.la
endif
+if BUILD_MODULE_VSERVER
+pkglib_LTLIBRARIES += vserver.la
+vserver_la_SOURCES = vserver.c
+vserver_la_LDFLAGS = -module -avoid-version
+collectd_LDADD += "-dlopen" vserver.la
+collectd_DEPENDENCIES += vserver.la
+endif
+
if BUILD_MODULE_WIRELESS
pkglib_LTLIBRARIES += wireless.la
wireless_la_SOURCES = wireless.c
wireless_la_LDFLAGS = -module -avoid-version
-# FIXME Make `-lm' conditional
-wireless_la_LDFLAGS += -lm
collectd_LDADD += "-dlopen" wireless.la
collectd_DEPENDENCIES += wireless.la
endif
--- /dev/null
+/**
+ * collectd - src/apache.c
+ * Copyright (C) 2006 Florian octo Forster
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors:
+ * Florian octo Forster <octo at verplant.org>
+ **/
+
+#include "collectd.h"
+#include "common.h"
+#include "plugin.h"
+#include "configfile.h"
+
+#define MODULE_NAME "apache"
+
+#if HAVE_LIBCURL && HAVE_CURL_CURL_H
+# define APACHE_HAVE_READ 1
+# include <curl/curl.h>
+#else
+# define APACHE_HAVE_READ 0
+#endif
+
+static char *url = NULL;
+static char *user = NULL;
+static char *pass = NULL;
+
+#if APACHE_HAVE_READ
+static CURL *curl = NULL;
+
+static char apache_buffer[4096];
+static int apache_buffer_len = 0;
+static char apache_curl_error[CURL_ERROR_SIZE];
+#endif
+
+/* Limit to 2^27 bytes/s. That's what a gigabit-ethernet link can handle, in
+ * theory. */
+static char *bytes_file = "apache/apache_bytes.rrd";
+static char *bytes_ds_def[] =
+{
+ "DS:count:COUNTER:"COLLECTD_HEARTBEAT":0:134217728",
+ NULL
+};
+static int bytes_ds_num = 1;
+
+/* Limit to 2^20 requests/s */
+static char *requests_file = "apache/apache_requests.rrd";
+static char *requests_ds_def[] =
+{
+ "DS:count:COUNTER:"COLLECTD_HEARTBEAT":0:1048576",
+ NULL
+};
+static int requests_ds_num = 1;
+
+static char *scoreboard_file = "apache/apache_scoreboard-%s.rrd";
+static char *scoreboard_ds_def[] =
+{
+ "DS:count:GAUGE:"COLLECTD_HEARTBEAT":0:U",
+ NULL
+};
+static int scoreboard_ds_num = 1;
+
+static char *config_keys[] =
+{
+ "URL",
+ "User",
+ "Password",
+ NULL
+};
+static int config_keys_num = 3;
+
+
+static size_t apache_curl_callback (void *buf, size_t size, size_t nmemb, void *stream)
+{
+ size_t len = size * nmemb;
+
+ if ((apache_buffer_len + len) >= 4096)
+ {
+ len = 4095 - apache_buffer_len;
+ }
+
+ if (len <= 0)
+ return (len);
+
+ memcpy (apache_buffer + apache_buffer_len, (char *) buf, len);
+ apache_buffer_len += len;
+ apache_buffer[apache_buffer_len] = '\0';
+
+ return (len);
+}
+
+static int config_set (char **var, char *value)
+{
+ if (*var != NULL)
+ {
+ free (*var);
+ *var = NULL;
+ }
+
+ if ((*var = strdup (value)) == NULL)
+ return (1);
+ else
+ return (0);
+}
+
+static int config (char *key, char *value)
+{
+ if (strcasecmp (key, "url") == 0)
+ return (config_set (&url, value));
+ else if (strcasecmp (key, "user") == 0)
+ return (config_set (&user, value));
+ else if (strcasecmp (key, "password") == 0)
+ return (config_set (&pass, value));
+ else
+ return (-1);
+}
+
+static void init (void)
+{
+#if APACHE_HAVE_READ
+ static char credentials[1024];
+
+ if (curl != NULL)
+ {
+ curl_easy_cleanup (curl);
+ }
+
+ if ((curl = curl_easy_init ()) == NULL)
+ {
+ syslog (LOG_ERR, "apache: `curl_easy_init' failed.");
+ return;
+ }
+
+ curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, apache_curl_callback);
+ curl_easy_setopt (curl, CURLOPT_USERAGENT, PACKAGE_NAME"/"PACKAGE_VERSION);
+ curl_easy_setopt (curl, CURLOPT_ERRORBUFFER, apache_curl_error);
+
+ if (user != NULL)
+ {
+ if (snprintf (credentials, 1024, "%s:%s", user, pass == NULL ? "" : pass) >= 1024)
+ {
+ syslog (LOG_ERR, "apache: Credentials would have been truncated.");
+ return;
+ }
+
+ curl_easy_setopt (curl, CURLOPT_USERPWD, credentials);
+ }
+
+ if (url != NULL)
+ {
+ curl_easy_setopt (curl, CURLOPT_URL, url);
+ }
+#endif /* APACHE_HAVE_READ */
+}
+
+static void bytes_write (char *host, char *inst, char *val)
+{
+ rrd_update_file (host, bytes_file, val, bytes_ds_def, bytes_ds_num);
+}
+
+static void requests_write (char *host, char *inst, char *val)
+{
+ rrd_update_file (host, requests_file, val, requests_ds_def, requests_ds_num);
+}
+
+static void scoreboard_write (char *host, char *inst, char *val)
+{
+ char buf[1024];
+
+ if (snprintf (buf, 1024, scoreboard_file, inst) >= 1024)
+ return;
+
+ rrd_update_file (host, buf, val, scoreboard_ds_def, scoreboard_ds_num);
+}
+
+#if APACHE_HAVE_READ
+static void submit (char *type, char *inst, long long value)
+{
+ char buf[1024];
+ int status;
+
+ status = snprintf (buf, 1024, "%u:%lli", (unsigned int) curtime, value);
+ if (status < 0)
+ {
+ syslog (LOG_ERR, "apache: bytes_submit: snprintf failed");
+ return;
+ }
+ else if (status >= 1024)
+ {
+ syslog (LOG_WARNING, "apache: bytes_submit: snprintf was truncated");
+ return;
+ }
+
+ plugin_submit (type, inst, buf);
+}
+
+static void submit_scoreboard (char *buf)
+{
+ /*
+ * Scoreboard Key:
+ * "_" Waiting for Connection, "S" Starting up, "R" Reading Request,
+ * "W" Sending Reply, "K" Keepalive (read), "D" DNS Lookup,
+ * "C" Closing connection, "L" Logging, "G" Gracefully finishing,
+ * "I" Idle cleanup of worker, "." Open slot with no current process
+ */
+ long long open = 0LL;
+ long long waiting = 0LL;
+ long long starting = 0LL;
+ long long reading = 0LL;
+ long long sending = 0LL;
+ long long keepalive = 0LL;
+ long long dnslookup = 0LL;
+ long long closing = 0LL;
+ long long logging = 0LL;
+ long long finishing = 0LL;
+ long long idle_cleanup = 0LL;
+
+ int i;
+
+ for (i = 0; buf[i] != '\0'; i++)
+ {
+ if (buf[i] == '.') open++;
+ else if (buf[i] == '_') waiting++;
+ else if (buf[i] == 'S') starting++;
+ else if (buf[i] == 'R') reading++;
+ else if (buf[i] == 'W') sending++;
+ else if (buf[i] == 'K') keepalive++;
+ else if (buf[i] == 'D') dnslookup++;
+ else if (buf[i] == 'C') closing++;
+ else if (buf[i] == 'L') logging++;
+ else if (buf[i] == 'G') finishing++;
+ else if (buf[i] == 'I') idle_cleanup++;
+ }
+
+ submit ("apache_scoreboard", "open" , open);
+ submit ("apache_scoreboard", "waiting" , waiting);
+ submit ("apache_scoreboard", "starting" , starting);
+ submit ("apache_scoreboard", "reading" , reading);
+ submit ("apache_scoreboard", "sending" , sending);
+ submit ("apache_scoreboard", "keepalive", keepalive);
+ submit ("apache_scoreboard", "dnslookup", dnslookup);
+ submit ("apache_scoreboard", "closing" , closing);
+ submit ("apache_scoreboard", "logging" , logging);
+ submit ("apache_scoreboard", "finishing", finishing);
+ submit ("apache_scoreboard", "idle_cleanup", idle_cleanup);
+}
+
+static void apache_read (void)
+{
+ int i;
+
+ char *ptr;
+ char *lines[16];
+ int lines_num = 0;
+
+ char *fields[4];
+ int fields_num;
+
+ if (curl == NULL)
+ return;
+ if (url == NULL)
+ return;
+
+ if (curl_easy_perform (curl) != 0)
+ {
+ syslog (LOG_WARNING, "apache: curl_easy_perform failed: %s", apache_curl_error);
+ return;
+ }
+
+ ptr = apache_buffer;
+ while ((lines[lines_num] = strtok (ptr, "\n\r")) != NULL)
+ {
+ ptr = NULL;
+ lines_num++;
+
+ if (lines_num >= 16)
+ break;
+ }
+
+ for (i = 0; i < lines_num; i++)
+ {
+ fields_num = strsplit (lines[i], fields, 4);
+
+ if (fields_num == 3)
+ {
+ if ((strcmp (fields[0], "Total") == 0)
+ && (strcmp (fields[1], "Accesses:") == 0))
+ submit ("apache_requests", NULL, atoll (fields[2]));
+ else if ((strcmp (fields[0], "Total") == 0)
+ && (strcmp (fields[1], "kBytes:") == 0))
+ submit ("apache_bytes", NULL, 1024LL * atoll (fields[2]));
+ }
+ else if (fields_num == 2)
+ {
+ if (strcmp (fields[0], "Scoreboard:") == 0)
+ submit_scoreboard (fields[1]);
+ }
+ }
+
+ apache_buffer_len = 0;
+}
+#else
+# define apache_read NULL
+#endif /* APACHE_HAVE_READ */
+
+void module_register (void)
+{
+ plugin_register (MODULE_NAME, init, apache_read, NULL);
+ plugin_register ("apache_requests", NULL, NULL, requests_write);
+ plugin_register ("apache_bytes", NULL, NULL, bytes_write);
+ plugin_register ("apache_scoreboard", NULL, NULL, scoreboard_write);
+ cf_register (MODULE_NAME, config, config_keys, config_keys_num);
+}
+
+#undef MODULE_NAME
--- /dev/null
+/**
+ * collectd - src/apple_sensors.c
+ * Copyright (C) 2006 Florian octo Forster
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors:
+ * Florian octo Forster <octo at verplant.org>
+ **/
+
+#include "collectd.h"
+#include "common.h"
+#include "plugin.h"
+#include "utils_debug.h"
+
+#define MODULE_NAME "apple_sensors"
+
+#if HAVE_CTYPE_H
+# include <ctype.h>
+#endif
+
+#if HAVE_MACH_MACH_TYPES_H
+# include <mach/mach_types.h>
+#endif
+#if HAVE_MACH_MACH_INIT_H
+# include <mach/mach_init.h>
+#endif
+#if HAVE_MACH_MACH_ERROR_H
+# include <mach/mach_error.h>
+#endif
+#if HAVE_MACH_MACH_PORT_H
+# include <mach/mach_port.h>
+#endif
+#if HAVE_COREFOUNDATION_COREFOUNDATION_H
+# include <CoreFoundation/CoreFoundation.h>
+#endif
+#if HAVE_IOKIT_IOKITLIB_H
+# include <IOKit/IOKitLib.h>
+#endif
+#if HAVE_IOKIT_IOTYPES_H
+# include <IOKit/IOTypes.h>
+#endif
+
+#if HAVE_IOKIT_IOKITLIB_H
+# define IOKIT_HAVE_READ 1
+#else
+# define IOKIT_HAVE_READ 0
+#endif
+
+#if HAVE_IOKIT_IOKITLIB_H
+static mach_port_t io_master_port = MACH_PORT_NULL;
+#endif
+
+static char *temperature_file = "apple_sensors/temperature-%s.rrd";
+static char *fanspeed_file = "apple_sensors/fanspeed-%s.rrd";
+
+static char *ds_def[] =
+{
+ "DS:value:GAUGE:"COLLECTD_HEARTBEAT":U:U",
+ NULL
+};
+static int ds_num = 1;
+
+static void as_init (void)
+{
+#if IOKIT_HAVE_READ
+ kern_return_t status;
+
+ if (io_master_port != MACH_PORT_NULL)
+ {
+ mach_port_deallocate (mach_task_self (),
+ io_master_port);
+ io_master_port = MACH_PORT_NULL;
+ }
+
+ status = IOMasterPort (MACH_PORT_NULL, &io_master_port);
+ if (status != kIOReturnSuccess)
+ {
+ syslog (LOG_ERR, "IOMasterPort failed: %s",
+ mach_error_string (status));
+ io_master_port = MACH_PORT_NULL;
+ return;
+ }
+#endif /* IOKIT_HAVE_READ */
+
+ return;
+}
+
+static void as_write (char *host, char *inst, char *val, const char *template)
+{
+ char filename[256];
+ int status;
+
+ status = snprintf (filename, 256, template, inst);
+ if ((status < 1) || (status >= 256))
+ return;
+
+ rrd_update_file (host, filename, val, ds_def, ds_num);
+}
+
+static void temperature_write (char *host, char *inst, char *val)
+{
+ as_write (host, inst, val, temperature_file);
+}
+
+static void fanspeed_write (char *host, char *inst, char *val)
+{
+ as_write (host, inst, val, fanspeed_file);
+}
+
+#if IOKIT_HAVE_READ
+static void as_submit (char *type, char *inst, double value)
+{
+ char buf[128];
+
+ if (snprintf (buf, 1024, "%u:%f", (unsigned int) curtime,
+ value) >= 128)
+ return;
+
+ plugin_submit (type, inst, buf);
+}
+
+static void as_read (void)
+{
+ kern_return_t status;
+ io_iterator_t iterator;
+ io_object_t io_obj;
+ CFMutableDictionaryRef prop_dict;
+ CFTypeRef property;
+
+ char type[128];
+ char inst[128];
+ int value_int;
+ double value_double;
+ int i;
+
+ if (!io_master_port || (io_master_port == MACH_PORT_NULL))
+ return;
+
+ status = IOServiceGetMatchingServices (io_master_port,
+ IOServiceNameMatching("IOHWSensor"),
+ &iterator);
+ if (status != kIOReturnSuccess)
+ {
+ syslog (LOG_ERR, "IOServiceGetMatchingServices failed: %s",
+ mach_error_string (status));
+ return;
+ }
+
+ while ((io_obj = IOIteratorNext (iterator)))
+ {
+ prop_dict = NULL;
+ status = IORegistryEntryCreateCFProperties (io_obj,
+ &prop_dict,
+ kCFAllocatorDefault,
+ kNilOptions);
+ if (status != kIOReturnSuccess)
+ {
+ DBG ("IORegistryEntryCreateCFProperties failed: %s",
+ mach_error_string (status));
+ continue;
+ }
+
+ /* Copy the sensor type. */
+ property = NULL;
+ if (!CFDictionaryGetValueIfPresent (prop_dict,
+ CFSTR ("type"),
+ &property))
+ continue;
+ if (CFGetTypeID (property) != CFStringGetTypeID ())
+ continue;
+ if (!CFStringGetCString (property,
+ type, 128,
+ kCFStringEncodingASCII))
+ continue;
+ type[127] = '\0';
+
+ /* Copy the sensor location. This will be used as `instance'. */
+ property = NULL;
+ if (!CFDictionaryGetValueIfPresent (prop_dict,
+ CFSTR ("location"),
+ &property))
+ continue;
+ if (CFGetTypeID (property) != CFStringGetTypeID ())
+ continue;
+ if (!CFStringGetCString (property,
+ inst, 128,
+ kCFStringEncodingASCII))
+ continue;
+ inst[127] = '\0';
+ for (i = 0; i < 128; i++)
+ {
+ if (inst[i] == '\0')
+ break;
+ else if (isalnum (inst[i]))
+ inst[i] = (char) tolower (inst[i]);
+ else
+ inst[i] = '_';
+ }
+
+ /* Get the actual value. Some computation, based on the `type'
+ * is neccessary. */
+ property = NULL;
+ if (!CFDictionaryGetValueIfPresent (prop_dict,
+ CFSTR ("current-value"),
+ &property))
+ continue;
+ if (CFGetTypeID (property) != CFNumberGetTypeID ())
+ continue;
+ if (!CFNumberGetValue (property,
+ kCFNumberIntType,
+ &value_int))
+ continue;
+
+ if (strcmp (type, "temperature") == 0)
+ {
+ value_double = ((double) value_int) / 65536.0;
+ strncpy (type, "apple_temperature", 128);
+ }
+ else if (strcmp (type, "fanspeed") == 0)
+ {
+ value_double = ((double) value_int) / 65536.0;
+ strncpy (type, "apple_fanspeed", 128);
+ }
+ else if (strcmp (type, "voltage") == 0)
+ {
+ /* Leave this to the battery plugin. */
+ continue;
+ }
+ else
+ {
+ DBG ("apple_sensors: Read unknown sensor type: %s",
+ type);
+ value_double = (double) value_int;
+ }
+
+ as_submit (type, inst, value_double);
+
+ CFRelease (prop_dict);
+ IOObjectRelease (io_obj);
+ } /* while (iterator) */
+
+ IOObjectRelease (iterator);
+}
+#else
+# define as_read NULL
+#endif /* IOKIT_HAVE_READ */
+
+void module_register (void)
+{
+ plugin_register (MODULE_NAME, as_init, as_read, NULL);
+ plugin_register ("apple_temperature", NULL, NULL, temperature_write);
+ plugin_register ("apple_fanspeed", NULL, NULL, fanspeed_write);
+}
+
+#undef MODULE_NAME
#include "collectd.h"
#include "common.h"
#include "plugin.h"
+#include "utils_debug.h"
#define MODULE_NAME "battery"
#define BUFSIZE 512
-#if defined(KERNEL_LINUX)
+#if HAVE_MACH_MACH_TYPES_H
+# include <mach/mach_types.h>
+#endif
+#if HAVE_MACH_MACH_INIT_H
+# include <mach/mach_init.h>
+#endif
+#if HAVE_MACH_MACH_ERROR_H
+# include <mach/mach_error.h>
+#endif
+#if HAVE_COREFOUNDATION_COREFOUNDATION_H
+# include <CoreFoundation/CoreFoundation.h>
+#endif
+#if HAVE_IOKIT_IOKITLIB_H
+# include <IOKit/IOKitLib.h>
+#endif
+#if HAVE_IOKIT_IOTYPES_H
+# include <IOKit/IOTypes.h>
+#endif
+#if HAVE_IOKIT_PS_IOPOWERSOURCES_H
+# include <IOKit/ps/IOPowerSources.h>
+#endif
+#if HAVE_IOKIT_PS_IOPSKEYS_H
+# include <IOKit/ps/IOPSKeys.h>
+#endif
+
+#if HAVE_IOKIT_PS_IOPOWERSOURCES_H || KERNEL_LINUX
# define BATTERY_HAVE_READ 1
#else
# define BATTERY_HAVE_READ 0
static char *ds_def_current[] =
{
- "DS:current:GAUGE:25:U:U",
+ "DS:current:GAUGE:"COLLECTD_HEARTBEAT":U:U",
NULL
};
static int ds_num_current = 1;
static char *ds_def_voltage[] =
{
- "DS:voltage:GAUGE:25:U:U",
+ "DS:voltage:GAUGE:"COLLECTD_HEARTBEAT":U:U",
NULL
};
static int ds_num_voltage = 1;
static char *ds_def_charge[] =
{
- "DS:charge:GAUGE:25:0:U",
+ "DS:charge:GAUGE:"COLLECTD_HEARTBEAT":0:U",
NULL
};
static int ds_num_charge = 1;
-#if BATTERY_HAVE_READ
+#if HAVE_IOKIT_PS_IOPOWERSOURCES_H
+ /* No global variables */
+/* #endif HAVE_IOKIT_PS_IOPOWERSOURCES_H */
+
+#elif KERNEL_LINUX
static int battery_pmu_num = 0;
static char *battery_pmu_file = "/proc/pmu/battery_%i";
-#endif
+#endif /* KERNEL_LINUX */
static void battery_init (void)
{
-#if BATTERY_HAVE_READ
+#if HAVE_IOKIT_PS_IOPOWERSOURCES_H
+ /* No init neccessary */
+/* #endif HAVE_IOKIT_PS_IOPOWERSOURCES_H */
+
+#elif KERNEL_LINUX
int len;
char filename[BUFSIZE];
if (access (filename, R_OK))
break;
}
-#endif
+#endif /* KERNEL_LINUX */
return;
}
static void battery_read (void)
{
-#ifdef KERNEL_LINUX
+#if HAVE_IOKIT_PS_IOPOWERSOURCES_H
+ CFTypeRef ps_raw;
+ CFArrayRef ps_array;
+ int ps_array_len;
+ CFDictionaryRef ps_dict;
+ CFTypeRef ps_obj;
+ CFTypeRef ps_value;
+
+ int i;
+
+ char name[128];
+ double charge = INVALID_VALUE;
+ double current = INVALID_VALUE;
+ double voltage = INVALID_VALUE;
+
+ ps_raw = IOPSCopyPowerSourcesInfo ();
+ ps_array = IOPSCopyPowerSourcesList (ps_raw);
+ ps_array_len = CFArrayGetCount (ps_array);
+
+ DBG ("ps_array_len == %i", ps_array_len);
+
+ for (i = 0; i < ps_array_len; i++)
+ {
+ ps_obj = CFArrayGetValueAtIndex (ps_array, i);
+ ps_dict = IOPSGetPowerSourceDescription (ps_raw, ps_obj);
+
+ if (CFGetTypeID (ps_dict) != CFDictionaryGetTypeID ())
+ {
+ DBG ("IOPSGetPowerSourceDescription did not return a CFDictionaryRef");
+ continue;
+ }
+
+ if (ps_dict != NULL)
+ {
+ /* Get the current capacity/charge */
+ ps_value = NULL;
+ charge = INVALID_VALUE;
+ if (CFDictionaryGetValueIfPresent (ps_dict,
+ CFSTR (kIOPSCurrentCapacityKey),
+ &ps_value))
+ {
+ if (CFGetTypeID (ps_value) != CFNumberGetTypeID ())
+ CFNumberGetValue (ps_value,
+ kCFNumberDoubleType,
+ &charge);
+ else
+ DBG ("kIOPSCurrentCapacityKey: Not a CFNumber");
+
+ DBG ("charge = %f", charge);
+ }
+ else
+ DBG ("`%s' does not exist", kIOPSCurrentCapacityKey);
+
+ /* Get the current */
+ ps_value = NULL;
+ current = INVALID_VALUE;
+ if (CFDictionaryGetValueIfPresent (ps_dict,
+ CFSTR (kIOPSCurrentKey),
+ &ps_value))
+ {
+ if (CFGetTypeID (ps_value) != CFNumberGetTypeID ())
+ CFNumberGetValue (ps_value,
+ kCFNumberDoubleType,
+ ¤t);
+ else
+ DBG ("kIOPSCurrentKey: Not a CFNumber");
+ DBG ("current = %f", current);
+ }
+ else
+ DBG ("`%s' does not exist", kIOPSCurrentKey);
+
+ /* Get the voltage */
+ ps_value = NULL;
+ voltage = INVALID_VALUE;
+ if (CFDictionaryGetValueIfPresent (ps_dict,
+ CFSTR (kIOPSVoltageKey),
+ &ps_value))
+ {
+ if (CFGetTypeID (ps_value) != CFNumberGetTypeID ())
+ CFNumberGetValue (ps_value,
+ kCFNumberDoubleType,
+ &voltage);
+ else
+ DBG ("kIOPSVoltageKey: Not a CFNumber");
+ DBG ("voltage = %f", voltage);
+ }
+ else
+ DBG ("`%s' does not exist", kIOPSVoltageKey);
+
+ /* Get the name of the device.. */
+ ps_value = NULL;
+ if (CFDictionaryGetValueIfPresent (ps_dict,
+ CFSTR (kIOPSNameKey),
+ &ps_value))
+ {
+ if (CFGetTypeID (ps_value) != CFStringGetTypeID ())
+ if (!CFStringGetCString (ps_value,
+ name, 128,
+ kCFStringEncodingASCII))
+ continue;
+ else
+ DBG ("kIOPSNameKey: Not a CFStringGetTypeID");
+ DBG ("Original string: `%s'", name);
+ }
+ else
+ {
+ strncpy (name, "unknown", 128);
+ }
+ name[127] = '\0';
+ for (i = 0; i < 128; i++)
+ {
+ if (name[i] == '\0')
+ break;
+ else if (isalnum (name[i]))
+ name[i] = (char) tolower (name[i]);
+ else
+ name[i] = '_';
+ }
+
+ battery_submit (name, current, voltage, charge);
+ }
+ }
+
+ CFRelease(ps_array);
+ CFRelease(ps_raw);
+/* #endif HAVE_IOKIT_PS_IOPOWERSOURCES_H */
+
+#elif KERNEL_LINUX
FILE *fh;
char buffer[BUFSIZE];
char filename[BUFSIZE];
#include "plugin.h"
#include "configfile.h"
-#include "ping.h"
-
static int loop = 0;
#if HAVE_LIBKSTAT
#if COLLECT_DEBUG
" Log-File "LOGFILE"\n"
#endif
+ " Step "COLLECTD_STEP" seconds\n"
+ " Heartbeat "COLLECTD_HEARTBEAT" seconds\n"
"\n"PACKAGE" "VERSION", http://verplant.org/collectd/\n"
"by Florian octo Forster <octo@verplant.org>\n"
"for contributions see `AUTHORS'\n");
static int start_client (void)
{
- int sleepingtime;
+ int step;
+
+ struct timeval tv_now;
+ struct timeval tv_next;
+ struct timespec ts_wait;
+
+ step = atoi (COLLECTD_STEP);
+ if (step <= 0)
+ step = 10;
#if HAVE_LIBKSTAT
kc = NULL;
while (loop == 0)
{
- curtime = time (NULL);
+ if (gettimeofday (&tv_next, NULL) < 0)
+ {
+ syslog (LOG_ERR, "gettimeofday failed: %s", strerror (errno));
+ return (-1);
+ }
+ tv_next.tv_sec += step;
+
#if HAVE_LIBKSTAT
update_kstat ();
#endif
+ /* `curtime' is used by many (all?) plugins as the
+ * data-sample-time passed to RRDTool */
+ curtime = time (NULL);
+
+ /* Issue all plugins */
plugin_read_all ();
- sleepingtime = 10;
- while (sleepingtime != 0)
+ if (gettimeofday (&tv_now, NULL) < 0)
{
- if (loop != 0)
+ syslog (LOG_ERR, "gettimeofday failed: %s", strerror (errno));
+ return (-1);
+ }
+
+ if (timeval_sub_timespec (&tv_next, &tv_now, &ts_wait) != 0)
+ {
+ syslog (LOG_WARNING, "No sleeping because `timeval_sub_timespec' returned non-zero!");
+ continue;
+ }
+
+ while (nanosleep (&ts_wait, &ts_wait) == -1)
+ {
+ if (errno != EINTR)
+ {
+ syslog (LOG_ERR, "nanosleep failed: %s", strerror (errno));
break;
- sleepingtime = sleep (sleepingtime);
+ }
}
}
Some Plugins may register own options. These options must be inclosed in a
C<Plugin>-Section. Which options exist depends on the plugin used:
+=head2 Plugin C<apache>
+
+=over 4
+
+=item B<URL> I<http://host/mod_status?auto>
+
+Sets the URL of the C<mod_status> output. This needs to be the output generated
+by C<ExtendedStatus on> and it needs to be the machine readable output
+generated by appending the C<?auto> argument.
+
+=item B<User> I<Username>
+
+Optional user name needed for authentication.
+
+=item B<Password> I<Password>
+
+Optional password needed for authentication.
+
+=back
+
=head2 Plugin C<hddtemp>
=over 4
Host to ping periodically. This option may be repeated several times to ping
multiple hosts.
+=item B<TTL> I<0-255>
+
+Sets the Time-To-Live of generated ICMP packets.
+
=back
=head1 SEE ALSO
#define MODE_LOCAL 0x04
#define MODE_LOG 0x08
+#ifndef COLLECTD_STEP
+# define COLLECTD_STEP "10"
+#endif
+
+#ifndef COLLECTD_HEARTBEAT
+# define COLLECTD_HEARTBEAT "25"
+#endif
+
+#ifndef COLLECTD_ROWS
+# define COLLECTD_ROWS "1200"
+#endif
+
+#ifndef COLLECTD_XFF
+# define COLLECTD_XFF 0.1
+#endif
+
extern time_t curtime;
#ifdef HAVE_LIBRRD
Number of users logged into the system (I<users>)
+=item
+
+System ressources used by VServers (I<vserver>)
+
=back
=head1 OPTIONS
=head1 SPECIAL PLUGINS
+=head2 apache
+
+This module connects to an Apache webserver and expects the output produced by
+B<mod_status.c>. If requires B<libcurl> to set up the HTTP connection and issue
+the request(s). The following is a sample config for the Apache webserver. The
+use of C<ExtendedStatus on> is mandatory.
+
+ ExtendedStatus on
+ <IfModule mod_status.c>
+ <Location /mod_status>
+ SetHandler server-status
+ </Location>
+ </IfModule>
+
+This plugin requires further configuration. Please read L<collectd.conf(5)>.
+
=head2 cpufreq
This module reads F</sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq> (for
the first CPU installed) to get the current CPU frequency. If this file does
not exist make sure B<cpufreqd> (L<http://cpufreqd.sourceforge.net/>) or a
-similar tool is installed.
+similar tool is installed and an "cpu governor" (that's kernel module) is
+loaded.
=head2 mysql
The B<hddtemp> homepage can be found at
L<http://www.guzu.net/linux/hddtemp.php>.
-=head1 RRD FILES
+=head2 vserver
-The RRD files are created automatically with the following RRAs:
+B<VServer> support is only available for Linux. It cannot yet be found in a
+vanilla kernel, though. To make use of this plugin you need a kernel that has
+B<VServer> support built in, i.e. you need to apply the patches and compile
+your own kernel, which will then provide the /proc/virtual filesystem that is
+required by this plugin.
- RRA:AVERAGE:0.2:6:1500
- RRA:AVERAGE:0.1:180:1680
- RRA:AVERAGE:0.1:2160:1520
- RRA:MIN:0.2:6:1500
- RRA:MIN:0.1:180:1680
- RRA:MIN:0.1:2160:1520
- RRA:MAX:0.2:6:1500
- RRA:MAX:0.1:180:1680
- RRA:MAX:0.1:2160:1520
+The B<VServer> homepage can be found at L<http://linux-vserver.org/>.
-Since collectd uses a 10 second I<step> the RRAs contain the following
-timespans:
+=head1 RRD FILES
- Resolution | Data points | Timespan
- -----------+-------------+----------
- 60 seconds | 1500 | 25 hours
- 30 minutes | 1680 | 35 days
- 6 hours | 1520 | 380 days
+The RRD files are created automatically. The size of the RRAs depend on the
+compile time settings of I<step> and I<width>. With the default values (I<step>
+= B<10>, I<width> = B<1200>) the following RRAs are created:
+
+ RRA:AVERAGE:0.1:1:8640
+ RRA:AVERAGE:0.1:50:1210
+ RRA:AVERAGE:0.1:223:1202
+ RRA:AVERAGE:0.1:2635:1201
+ RRA:MIN:0.1:1:8640
+ RRA:MIN:0.1:50:1210
+ RRA:MIN:0.1:223:1202
+ RRA:MIN:0.1:2635:1201
+ RRA:MAX:0.1:1:8640
+ RRA:MAX:0.1:50:1210
+ RRA:MAX:0.1:223:1202
+ RRA:MAX:0.1:2635:1201
+
+By default collectd uses a 10 second I<step>. Thus the RRAs contain the
+following timespans. If you've changed the I<step> at compile time you will
+have calculate resolution and timespan yourself.
+
+ PDP per CDP | Resolution | Data points | Timespan
+ ------------+--------------+-------------+---------
+ 1 | 10.0 seconds ! 8640 ! 1 day
+ 50 | 8.3 minutes | 1210 | 1 week
+ 223 | 37.2 minutes | 1202 | 1 month
+ 2635 | 7.3 hours | 1201 | 1 year
The DS'es depend on the module creating the RRD files:
DS:users:GAUGE:25: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
+
+=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
+
+=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
+
+=item VServer processes (F<vserver-I<E<lt>xidE<gt>>/vs_processes.rrd>)
+
+ DS:total:GAUGE:25: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
+
=back
=head1 SEE ALSO
#include "common.h"
#include "utils_debug.h"
+#ifdef HAVE_MATH_H
+# include <math.h>
+#endif
+
extern int operating_mode;
#ifdef HAVE_LIBKSTAT
#endif
#ifdef HAVE_LIBRRD
+#if 0
static char *rra_def[] =
{
+ "RRA:AVERAGE:0.0:1:1500",
"RRA:AVERAGE:0.2:6:1500",
"RRA:AVERAGE:0.1:180:1680",
"RRA:AVERAGE:0.1:2160:1520",
+ "RRA:MIN:0.0:1:1500",
"RRA:MIN:0.2:6:1500",
"RRA:MIN:0.1:180:1680",
"RRA:MIN:0.1:2160:1520",
+ "RRA:MAX:0.0:1:1500",
"RRA:MAX:0.2:6:1500",
"RRA:MAX:0.1:180:1680",
"RRA:MAX:0.1:2160:1520",
NULL
};
-static int rra_num = 9;
+static int rra_num = 12;
+#endif
+
+static int rra_timespans[] =
+{
+ 3600,
+ 86400,
+ 604800,
+ 2678400,
+ 31622400,
+ 0
+};
+static int rra_timespans_num = 5;
+
+static char *rra_types[] =
+{
+ "AVERAGE",
+ "MIN",
+ "MAX",
+ NULL
+};
+static int rra_types_num = 3;
#endif /* HAVE_LIBRRD */
void sstrncpy (char *d, const char *s, int len)
return (0);
}
+int timeval_sub_timespec (struct timeval *tv0, struct timeval *tv1, struct timespec *ret)
+{
+ if ((tv0 == NULL) || (tv1 == NULL) || (ret == NULL))
+ return (-2);
+
+ if ((tv0->tv_sec < tv1->tv_sec)
+ || ((tv0->tv_sec == tv1->tv_sec) && (tv0->tv_usec < tv1->tv_usec)))
+ return (-1);
+
+ ret->tv_sec = tv0->tv_sec - tv1->tv_sec;
+ ret->tv_nsec = 1000 * ((long) (tv0->tv_usec - tv1->tv_usec));
+
+ if (ret->tv_nsec < 0)
+ {
+ assert (ret->tv_sec > 0);
+
+ ret->tv_nsec += 1000000000;
+ ret->tv_sec -= 1;
+ }
+
+ return (0);
+}
+
static int check_create_dir (const char *file_orig)
{
struct stat statbuf;
return (0);
}
+/* * * * *
+ * Magic *
+ * * * * */
+int rra_get (char ***ret)
+{
+ static char **rra_def = NULL;
+ static int rra_num = 0;
+
+ int rra_max = rra_timespans_num * rra_types_num;
+
+ int step;
+ int rows;
+ int span;
+
+ int cdp_num;
+ int cdp_len;
+ int i, j;
+
+ char buffer[64];
+
+ if ((rra_num != 0) && (rra_def != NULL))
+ {
+ *ret = rra_def;
+ return (rra_num);
+ }
+
+ if ((rra_def = (char **) malloc ((rra_max + 1) * sizeof (char *))) == NULL)
+ return (-1);
+ memset (rra_def, '\0', (rra_max + 1) * sizeof (char *));
+
+ step = atoi (COLLECTD_STEP);
+ rows = atoi (COLLECTD_ROWS);
+
+ if ((step <= 0) || (rows <= 0))
+ {
+ *ret = NULL;
+ return (-1);
+ }
+
+ cdp_len = 0;
+ for (i = 0; i < rra_timespans_num; i++)
+ {
+ span = rra_timespans[i];
+
+ if ((span / step) < rows)
+ continue;
+
+ if (cdp_len == 0)
+ cdp_len = 1;
+ else
+ cdp_len = (int) floor (((double) span) / ((double) (rows * step)));
+
+ cdp_num = (int) ceil (((double) span) / ((double) (cdp_len * step)));
+
+ for (j = 0; j < rra_types_num; j++)
+ {
+ if (rra_num >= rra_max)
+ break;
+
+ if (snprintf (buffer, sizeof(buffer), "RRA:%s:%3.1f:%u:%u",
+ rra_types[j], COLLECTD_XFF,
+ cdp_len, cdp_num) >= sizeof (buffer))
+ {
+ syslog (LOG_ERR, "rra_get: Buffer would have been truncated.");
+ continue;
+ }
+
+ rra_def[rra_num++] = sstrdup (buffer);
+ }
+ }
+
+#if COLLECT_DEBUG
+ DBG ("rra_num = %i", rra_num);
+ for (i = 0; i < rra_num; i++)
+ DBG (" %s", rra_def[i]);
+#endif
+
+ *ret = rra_def;
+ return (rra_num);
+}
+
static int log_create_file (char *filename, char **ds_def, int ds_num)
{
FILE *log;
{
char **argv;
int argc;
+ char **rra_def;
+ int rra_num;
int i, j;
int status = 0;
if (check_create_dir (filename))
return (-1);
+ if ((rra_num = rra_get (&rra_def)) < 1)
+ {
+ syslog (LOG_ERR, "rra_create failed: Could not calculate RRAs");
+ return (-1);
+ }
+
argc = ds_num + rra_num + 4;
if ((argv = (char **) malloc (sizeof (char *) * (argc + 1))) == NULL)
argv[0] = "create";
argv[1] = filename;
argv[2] = "-s";
- argv[3] = "10";
+ argv[3] = COLLECTD_STEP;
j = 4;
for (i = 0; i < ds_num; i++)
*/
int escape_slashes (char *buf, int buf_len);
+/* FIXME: `timeval_sub_timespec' needs a description */
+int timeval_sub_timespec (struct timeval *tv0, struct timeval *tv1, struct timespec *ret);
+
int rrd_update_file (char *host, char *file, char *values,
char **ds_def, int ds_num);
if ((cf_cb = cf_search (type)) == NULL)
{
- syslog (LOG_WARNING, "Plugin `%s' did not register a callback.\n", type);
+ syslog (LOG_WARNING, "Plugin `%s' did not register a callback.", type);
return (-1);
}
}
if (i >= cf_cb->keys_num)
- syslog (LOG_WARNING, "Plugin `%s' did not register for value `%s'.\n", type, key);
+ syslog (LOG_WARNING, "Plugin `%s' did not register for value `%s'.", type, key);
free (key);
free (value);
+ DBG ("return (%i)", ret);
+
return (ret);
}
#include "collectd.h"
#include "common.h"
#include "plugin.h"
+#include "utils_debug.h"
#define MODULE_NAME "cpu"
+#ifdef HAVE_MACH_KERN_RETURN_H
+# include <mach/kern_return.h>
+#endif
+#ifdef HAVE_MACH_MACH_INIT_H
+# include <mach/mach_init.h>
+#endif
+#ifdef HAVE_MACH_HOST_PRIV_H
+# include <mach/host_priv.h>
+#endif
+#if HAVE_MACH_MACH_ERROR_H
+# include <mach/mach_error.h>
+#endif
+#ifdef HAVE_MACH_PROCESSOR_INFO_H
+# include <mach/processor_info.h>
+#endif
+#ifdef HAVE_MACH_PROCESSOR_H
+# include <mach/processor.h>
+#endif
+#ifdef HAVE_MACH_VM_MAP_H
+# include <mach/vm_map.h>
+#endif
+
#ifdef HAVE_LIBKSTAT
# include <sys/sysinfo.h>
#endif /* HAVE_LIBKSTAT */
# endif
#endif /* HAVE_SYSCTLBYNAME */
-#if defined(KERNEL_LINUX) || defined(HAVE_LIBKSTAT) || defined(HAVE_SYSCTLBYNAME)
+#if defined(PROCESSOR_CPU_LOAD_INFO) || defined(KERNEL_LINUX) || defined(HAVE_LIBKSTAT) || defined(HAVE_SYSCTLBYNAME)
# define CPU_HAVE_READ 1
#else
# define CPU_HAVE_READ 0
#endif
-#ifdef HAVE_LIBKSTAT
+#ifdef PROCESSOR_CPU_LOAD_INFO
+static mach_port_t port_host;
+static processor_port_array_t cpu_list;
+static mach_msg_type_number_t cpu_list_len;
+/* #endif PROCESSOR_CPU_LOAD_INFO */
+
+#elif defined(KERNEL_LINUX)
+/* no variables needed */
+/* #endif KERNEL_LINUX */
+
+#elif defined(HAVE_LIBKSTAT)
/* colleague tells me that Sun doesn't sell systems with more than 100 or so CPUs.. */
# define MAX_NUMCPU 256
extern kstat_ctl_t *kc;
static kstat_t *ksp[MAX_NUMCPU];
static int numcpu;
-#endif /* HAVE_LIBKSTAT */
+/* #endif HAVE_LIBKSTAT */
-#ifdef HAVE_SYSCTLBYNAME
+#elif defined(HAVE_SYSCTLBYNAME)
static int numcpu;
#endif /* HAVE_SYSCTLBYNAME */
static char *ds_def[] =
{
- "DS:user:COUNTER:25:0:U",
- "DS:nice:COUNTER:25:0:U",
- "DS:syst:COUNTER:25:0:U",
- "DS:idle:COUNTER:25:0:U",
- "DS:wait:COUNTER:25:0:U",
+ "DS:user:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:nice:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:syst:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:idle:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:wait:COUNTER:"COLLECTD_HEARTBEAT":0:U",
NULL
};
static int ds_num = 5;
static void cpu_init (void)
{
-#ifdef HAVE_LIBKSTAT
+#if PROCESSOR_CPU_LOAD_INFO || PROCESSOR_TEMPERATURE
+ kern_return_t status;
+
+ port_host = mach_host_self ();
+
+ /* FIXME: Free `cpu_list' if it's not NULL */
+ if ((status = host_processors (port_host, &cpu_list, &cpu_list_len)) != KERN_SUCCESS)
+ {
+ syslog (LOG_ERR, "cpu-plugin: host_processors returned %i\n", (int) status);
+ cpu_list_len = 0;
+ return;
+ }
+
+ DBG ("host_processors returned %i %s", (int) cpu_list_len, cpu_list_len == 1 ? "processor" : "processors");
+ syslog (LOG_INFO, "cpu-plugin: Found %i processor%s.", (int) cpu_list_len, cpu_list_len == 1 ? "" : "s");
+/* #endif PROCESSOR_CPU_LOAD_INFO */
+
+#elif defined(HAVE_LIBKSTAT)
kstat_t *ksp_chain;
numcpu = 0;
static void cpu_read (void)
{
-#ifdef KERNEL_LINUX
-#define BUFSIZE 1024
+#if PROCESSOR_CPU_LOAD_INFO || PROCESSOR_TEMPERATURE
+ int cpu;
+
+ kern_return_t status;
+
+#if PROCESSOR_CPU_LOAD_INFO
+ processor_cpu_load_info_data_t cpu_info;
+ mach_msg_type_number_t cpu_info_len;
+#endif
+#if PROCESSOR_TEMPERATURE
+ processor_info_data_t cpu_temp;
+ mach_msg_type_number_t cpu_temp_len;
+#endif
+
+ host_t cpu_host;
+
+ for (cpu = 0; cpu < cpu_list_len; cpu++)
+ {
+#if PROCESSOR_CPU_LOAD_INFO
+ cpu_host = 0;
+ cpu_info_len = PROCESSOR_BASIC_INFO_COUNT;
+
+ if ((status = processor_info (cpu_list[cpu],
+ PROCESSOR_CPU_LOAD_INFO, &cpu_host,
+ (processor_info_t) &cpu_info, &cpu_info_len)) != KERN_SUCCESS)
+ {
+ syslog (LOG_ERR, "processor_info failed with status %i\n", (int) status);
+ continue;
+ }
+
+ if (cpu_info_len < CPU_STATE_MAX)
+ {
+ syslog (LOG_ERR, "processor_info returned only %i elements..\n", cpu_info_len);
+ continue;
+ }
+
+ cpu_submit (cpu, cpu_info.cpu_ticks[CPU_STATE_USER],
+ cpu_info.cpu_ticks[CPU_STATE_NICE],
+ cpu_info.cpu_ticks[CPU_STATE_SYSTEM],
+ cpu_info.cpu_ticks[CPU_STATE_IDLE],
+ 0ULL);
+#endif /* PROCESSOR_CPU_LOAD_INFO */
+#if PROCESSOR_TEMPERATURE
+ cpu_temp_len = PROCESSOR_INFO_MAX;
+
+ status = processor_info (cpu_list[cpu],
+ PROCESSOR_TEMPERATURE,
+ &cpu_host,
+ cpu_temp, &cpu_temp_len);
+ if (status != KERN_SUCCESS)
+ {
+ syslog (LOG_ERR, "processor_info failed: %s",
+ mach_error_string (status));
+ continue;
+ }
+
+ if (cpu_temp_len != 1)
+ {
+ DBG ("processor_info (PROCESSOR_TEMPERATURE) returned %i elements..?",
+ (int) cpu_temp_len);
+ continue;
+ }
+
+ DBG ("cpu_temp = %i", (int) cpu_temp);
+#endif /* PROCESSOR_TEMPERATURE */
+ }
+/* #endif PROCESSOR_CPU_LOAD_INFO */
+
+#elif defined(KERNEL_LINUX)
+# define BUFSIZE 1024
int cpu;
unsigned long long user, nice, syst, idle;
unsigned long long wait, intr, sitr; /* sitr == soft interrupt */
+++ /dev/null
-/**
- * collectd - src/cpu.h
- * Copyright (C) 2005 Florian octo Forster
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Authors:
- * Florian octo Forster <octo at verplant.org>
- **/
-
-#ifndef CPU_H
-#define CPU_H
-
-#include "collectd.h"
-
-#ifndef COLLECT_CPU
-#if defined(KERNEL_LINUX) || defined(HAVE_LIBKSTAT) || defined(HAVE_SYSCTLBYNAME)
-#define COLLECT_CPU 1
-#else
-#define COLLECT_CPU 0
-#endif
-#endif /* !defined(COLLECT_CPU) */
-
-#if COLLECT_CPU
-
-void cpu_init (void);
-void cpu_read (void);
-
-#endif /* COLLECT_CPU */
-#endif /* CPU_H */
static char *ds_def[] =
{
- "DS:value:GAUGE:25:0:U",
+ "DS:value:GAUGE:"COLLECTD_HEARTBEAT":0:U",
NULL
};
static int ds_num = 1;
+++ /dev/null
-/**
- * collectd - src/cpufreq.c
- * Copyright (C) 2005 Peter Holik
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Authors:
- * Peter Holik <peter at holik.at>
- **/
-
-#ifndef CPUFREQ_H
-#define CPUFREQ_H
-
-#include "collectd.h"
-#include "common.h"
-
-#ifndef COLLECT_CPUFREQ
-#if defined(KERNEL_LINUX)
-#define COLLECT_CPUFREQ 1
-#else
-#define COLLECT_CPUFREQ 0
-#endif
-#endif /* !defined(COLLECT_CPUFREQ) */
-
-#endif /* CPUFREQ_H */
static char *ds_def[] =
{
- "DS:used:GAUGE:25:0:U",
- "DS:free:GAUGE:25:0:U",
+ "DS:used:GAUGE:"COLLECTD_HEARTBEAT":0:U",
+ "DS:free:GAUGE:"COLLECTD_HEARTBEAT":0:U",
NULL
};
static int ds_num = 2;
mnt_list = NULL;
if (cu_mount_getlist (&mnt_list) == NULL)
- {
- syslog (LOG_WARNING, "cu_mount_getlist returned `NULL'");
return;
- }
for (mnt_ptr = mnt_list; mnt_ptr != NULL; mnt_ptr = mnt_ptr->next)
{
/* 104857600 == 100 MB */
static char *disk_ds_def[] =
{
- "DS:rcount:COUNTER:25:0:U",
- "DS:rmerged:COUNTER:25:0:U",
- "DS:rbytes:COUNTER:25:0:104857600",
- "DS:rtime:COUNTER:25:0:U",
- "DS:wcount:COUNTER:25:0:U",
- "DS:wmerged:COUNTER:25:0:U",
- "DS:wbytes:COUNTER:25:0:104857600",
- "DS:wtime:COUNTER:25:0:U",
+ "DS:rcount:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:rmerged:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:rbytes:COUNTER:"COLLECTD_HEARTBEAT":0:104857600",
+ "DS:rtime:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:wcount:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:wmerged:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:wbytes:COUNTER:"COLLECTD_HEARTBEAT":0:104857600",
+ "DS:wtime:COUNTER:"COLLECTD_HEARTBEAT":0:U",
NULL
};
static int disk_ds_num = 8;
static char *part_ds_def[] =
{
- "DS:rcount:COUNTER:25:0:U",
- "DS:rbytes:COUNTER:25:0:104857600",
- "DS:wcount:COUNTER:25:0:U",
- "DS:wbytes:COUNTER:25:0:104857600",
+ "DS:rcount:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:rbytes:COUNTER:"COLLECTD_HEARTBEAT":0:104857600",
+ "DS:wcount:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:wbytes:COUNTER:"COLLECTD_HEARTBEAT":0:104857600",
NULL
};
static int part_ds_num = 4;
+++ /dev/null
-/**
- * collectd - src/disk.h
- * Copyright (C) 2005 Florian octo Forster
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Authors:
- * Florian octo Forster <octo at verplant.org>
- **/
-
-#ifndef DISKSTATS_H
-#define DISKSTATS_H
-
-#include "collectd.h"
-#include "common.h"
-
-#ifndef COLLECT_DISK
-#if defined(KERNEL_LINUX) || defined(HAVE_LIBKSTAT)
-#define COLLECT_DISK 1
-#else
-#define COLLECT_DISK 0
-#endif
-#endif /* !defined(COLLECT_DISK) */
-
-#endif /* DISKSTATS_H */
static char *ds_def[] =
{
- "DS:value:GAUGE:25:U:U",
+ "DS:value:GAUGE:"COLLECTD_HEARTBEAT":U:U",
NULL
};
static int ds_num = 1;
* operating-systems, it's not done at all. */
static void hddtemp_init (void)
{
-#if defined(KERNEL_LINUX)
+#if KERNEL_LINUX
FILE *fh;
char buf[BUFFER_SIZE];
int buflen;
+++ /dev/null
-/**
- * collectd - src/hddtemp.c
- * Copyright (C) 2005 Vincent Stehlé
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Authors:
- * Vincent Stehlé <vincent.stehle at free.fr>
- * Florian octo Forster <octo at verplant.org>
- **/
-
-#ifndef HDDTEMP_H
-#define HDDTEMP_H
-
-#include "collectd.h"
-#include "common.h"
-
-#ifndef COLLECT_HDDTEMP
-#define COLLECT_HDDTEMP 1
-#endif
-
-#endif /* HDDTEMP_H */
AUTOMAKE_OPTIONS = foreign no-dependencies
+if COMPILER_IS_GCC
+AM_CFLAGS = -Wall -Werror
+endif
+
noinst_LTLIBRARIES = liboping.la
#liboping_la_CFLAGS =
/*
* private (static) functions
*/
+static int ping_timeval_add (struct timeval *tv1, struct timeval *tv2,
+ struct timeval *res)
+{
+ res->tv_sec = tv1->tv_sec + tv2->tv_sec;
+ res->tv_usec = tv1->tv_usec + tv2->tv_usec;
+
+ while (res->tv_usec > 1000000)
+ {
+ res->tv_usec -= 1000000;
+ res->tv_sec++;
+ }
+
+ return (0);
+}
+
static int ping_timeval_sub (struct timeval *tv1, struct timeval *tv2,
struct timeval *res)
{
return (0);
}
-static int ping_receive_all (pinghost_t *ph)
+static int ping_receive_all (pingobj_t *obj)
{
fd_set readfds;
int num_readfds;
int max_readfds;
+ pinghost_t *ph;
pinghost_t *ptr;
struct timeval endtime;
int ret;
+ ph = obj->head;
ret = 0;
for (ptr = ph; ptr != NULL; ptr = ptr->next)
ptr->latency = -1.0;
- if (gettimeofday (&endtime, NULL) == -1)
+ if (gettimeofday (&nowtime, NULL) == -1)
return (-1);
- endtime.tv_sec += 1;
+
+ /* Set up timeout */
+ timeout.tv_sec = (time_t) obj->timeout;
+ timeout.tv_usec = (suseconds_t) (1000000 * (obj->timeout - ((double) timeout.tv_sec)));
+
+ dprintf ("Set timeout to %i.%06i seconds\n",
+ (int) timeout.tv_sec,
+ (int) timeout.tv_usec);
+
+ ping_timeval_add (&nowtime, &timeout, &endtime);
while (1)
{
return (0);
}
+/*
+ * Set the TTL of a socket protocol independently.
+ */
+static int ping_set_ttl (pinghost_t *ph, int ttl)
+{
+ int ret = -2;
+
+ if (ph->addrfamily == AF_INET)
+ {
+ ret = setsockopt (ph->fd, IPPROTO_IP, IP_TTL, &ttl, sizeof (ttl));
+ }
+ else if (ph->addrfamily == AF_INET6)
+ {
+ ret = setsockopt (ph->fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof (ttl));
+ }
+
+ return (ret);
+}
+
static int ping_get_ident (void)
{
int fd;
if (ping_send_all (obj->head) < 0)
return (-1);
- if ((ret = ping_receive_all (obj->head)) < 0)
+ if ((ret = ping_receive_all (obj)) < 0)
return (-2);
return (ret);
#ifdef AI_ADDRCONFIG
ai_hints.ai_flags |= AI_ADDRCONFIG;
#endif
- ai_hints.ai_family = PF_UNSPEC;
+ ai_hints.ai_family = obj->addrfamily;
ai_hints.ai_socktype = SOCK_RAW;
if ((ph = ping_alloc ()) == NULL)
ph->next = obj->head;
obj->head = ph;
+ ping_set_ttl (ph, obj->ttl);
+
return (0);
}
static char *ds_def[] =
{
- "DS:shortterm:GAUGE:25:0:100",
- "DS:midterm:GAUGE:25:0:100",
- "DS:longterm:GAUGE:25:0:100",
+ "DS:shortterm:GAUGE:"COLLECTD_HEARTBEAT":0:100",
+ "DS:midterm:GAUGE:"COLLECTD_HEARTBEAT":0:100",
+ "DS:longterm:GAUGE:"COLLECTD_HEARTBEAT":0:100",
NULL
};
static int ds_num = 3;
+++ /dev/null
-/**
- * collectd - src/load.h
- * Copyright (C) 2005 Florian octo Forster
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Authors:
- * Florian octo Forster <octo at verplant.org>
- **/
-
-#ifndef LOAD_H
-#define LOAD_H
-
-#include "collectd.h"
-#include "common.h"
-
-#ifndef COLLECT_LOAD
-#if defined(HAVE_GETLOADAVG) || defined(KERNEL_LINUX) || defined(HAVE_LIBSTATGRAB)
-#define COLLECT_LOAD 1
-#else
-#define COLLECT_LOAD 0
-#endif
-#endif /* !defined(COLLECT_LOAD) */
-
-#endif /* LOAD_H */
#include "common.h"
#include "plugin.h"
-#if defined(KERNEL_LINUX) || defined(HAVE_LIBKSTAT)
+#ifdef HAVE_MACH_KERN_RETURN_H
+# include <mach/kern_return.h>
+#endif
+#ifdef HAVE_MACH_MACH_INIT_H
+# include <mach/mach_init.h>
+#endif
+#ifdef HAVE_MACH_MACH_HOST_H
+# include <mach/mach_host.h>
+#endif
+#ifdef HAVE_MACH_HOST_PRIV_H
+# include <mach/host_priv.h>
+#endif
+#ifdef MACH_VM_STATISTICS_H
+# include <mach/vm_statistics.h>
+#endif
+
+#if defined (HOST_VM_INFO) || defined(KERNEL_LINUX) || defined(HAVE_LIBKSTAT)
# define MEMORY_HAVE_READ 1
#else
# define MEMORY_HAVE_READ 0
/* 9223372036854775807 == LLONG_MAX */
static char *ds_def[] =
{
- "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:"COLLECTD_HEARTBEAT":0:9223372036854775807",
+ "DS:free:GAUGE:"COLLECTD_HEARTBEAT":0:9223372036854775807",
+ "DS:buffers:GAUGE:"COLLECTD_HEARTBEAT":0:9223372036854775807",
+ "DS:cached:GAUGE:"COLLECTD_HEARTBEAT":0:9223372036854775807",
NULL
};
static int ds_num = 4;
-#ifdef HAVE_LIBKSTAT
+/* vm_statistics_data_t */
+#if defined(HOST_VM_INFO)
+static mach_port_t port_host;
+static vm_size_t pagesize;
+/* #endif HOST_VM_INFO */
+
+#elif defined(KERNEL_LINUX)
+/* no global variables */
+/* #endif KERNEL_LINUX */
+
+#elif defined(HAVE_LIBKSTAT)
static int pagesize;
static kstat_t *ksp;
#endif /* HAVE_LIBKSTAT */
static void memory_init (void)
{
-#ifdef HAVE_LIBKSTAT
+#if defined(HOST_VM_INFO)
+ port_host = mach_host_self ();
+ host_page_size (port_host, &pagesize);
+/* #endif HOST_VM_INFO */
+
+#elif defined(KERNEL_LINUX)
+/* no init stuff */
+/* #endif KERNEL_LINUX */
+
+#elif defined(HAVE_LIBKSTAT)
/* getpagesize(3C) tells me this does not fail.. */
pagesize = getpagesize ();
if (get_kstat (&ksp, "unix", 0, "system_pages"))
static void memory_read (void)
{
-#ifdef KERNEL_LINUX
+#if defined(HOST_VM_INFO)
+ kern_return_t status;
+ vm_statistics_data_t vm_data;
+ mach_msg_type_number_t vm_data_len;
+
+ long long wired;
+ long long active;
+ long long inactive;
+ long long free;
+
+ if (!port_host || !pagesize)
+ return;
+
+ vm_data_len = sizeof (vm_data) / sizeof (natural_t);
+ if ((status = host_statistics (port_host, HOST_VM_INFO,
+ (host_info_t) &vm_data,
+ &vm_data_len)) != KERN_SUCCESS)
+ {
+ syslog (LOG_ERR, "memory-plugin: host_statistics failed and returned the value %i", (int) status);
+ return;
+ }
+
+ /*
+ * From <http://docs.info.apple.com/article.html?artnum=107918>:
+ *
+ * Wired memory
+ * This information can't be cached to disk, so it must stay in RAM.
+ * The amount depends on what applications you are using.
+ *
+ * Active memory
+ * This information is currently in RAM and actively being used.
+ *
+ * Inactive memory
+ * This information is no longer being used and has been cached to
+ * disk, but it will remain in RAM until another application needs
+ * the space. Leaving this information in RAM is to your advantage if
+ * you (or a client of your computer) come back to it later.
+ *
+ * Free memory
+ * This memory is not being used.
+ */
+
+ wired = vm_data.wire_count * pagesize;
+ active = vm_data.active_count * pagesize;
+ inactive = vm_data.inactive_count * pagesize;
+ free = vm_data.free_count * pagesize;
+
+ memory_submit (wired + active, -1, inactive, free);
+/* #endif HOST_VM_INFO */
+
+#elif defined(KERNEL_LINUX)
FILE *fh;
char buffer[1024];
+++ /dev/null
-/**
- * collectd - src/memory.h
- * Copyright (C) 2005 Florian octo Forster
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Authors:
- * Florian octo Forster <octo at verplant.org>
- **/
-
-#ifndef MEMINFO_H
-#define MEMINFO_H
-
-#include "collectd.h"
-#include "common.h"
-
-#ifndef COLLECT_MEMORY
-#if defined(KERNEL_LINUX) || defined(HAVE_LIBKSTAT) || defined(HAVE_LIBSTATGRAB)
-#define COLLECT_MEMORY 1
-#else
-#define COLLECT_MEMORY 0
-#endif
-#endif /* !defined(COLLECT_MEMORY) */
-
-#endif /* MEMINFO_H */
static char *commands_ds_def[] =
{
- "DS:value:COUNTER:25:0:U",
+ "DS:value:COUNTER:"COLLECTD_HEARTBEAT":0:U",
NULL
};
static int commands_ds_num = 1;
static char *handler_ds_def[] =
{
- "DS:value:COUNTER:25:0:U",
+ "DS:value:COUNTER:"COLLECTD_HEARTBEAT":0:U",
NULL
};
static int handler_ds_num = 1;
static char *qcache_ds_def[] =
{
- "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:"COLLECTD_HEARTBEAT":0:U",
+ "DS:inserts:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:not_cached:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:lowmem_prunes:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:queries_in_cache:GAUGE:"COLLECTD_HEARTBEAT":0:U",
NULL
};
static int qcache_ds_num = 5;
static char *threads_ds_def[] =
{
- "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:"COLLECTD_HEARTBEAT":0:U",
+ "DS:connected:GAUGE:"COLLECTD_HEARTBEAT":0:U",
+ "DS:cached:GAUGE:"COLLECTD_HEARTBEAT":0:U",
+ "DS:created:COUNTER:"COLLECTD_HEARTBEAT":0:U",
NULL
};
static int threads_ds_num = 4;
static char *traffic_ds_def[] =
{
- "DS:incoming:COUNTER:25:0:U",
- "DS:outgoing:COUNTER:25:0:U",
+ "DS:incoming:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:outgoing:COUNTER:"COLLECTD_HEARTBEAT":0:U",
NULL
};
static int traffic_ds_num = 2;
if (se->mode != operating_mode)
continue;
- DBG ("fd = %i", se->fd);
-
while (1)
{
status = sendto (se->fd, buf, buflen, 0,
static char *nfs2_procedures_ds_def[] =
{
- "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:"COLLECTD_HEARTBEAT":0:U",
+ "DS:getattr:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:setattr:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:root:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:lookup:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:readlink:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:read:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:wrcache:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:write:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:create:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:remove:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:rename:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:link:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:symlink:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:mkdir:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:rmdir:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:readdir:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:fsstat:COUNTER:"COLLECTD_HEARTBEAT":0:U",
NULL
};
static int nfs2_procedures_ds_num = 18;
static char *nfs3_procedures_ds_def[] =
{
- "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:"COLLECTD_HEARTBEAT":0:U",
+ "DS:getattr:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:setattr:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:lookup:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:access:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:readlink:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:read:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:write:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:create:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:mkdir:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:symlink:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:mknod:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:remove:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:rmdir:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:rename:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:link:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:readdir:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:readdirplus:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:fsstat:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:fsinfo:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:pathconf:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:commit:COUNTER:"COLLECTD_HEARTBEAT":0:U",
NULL
};
static int nfs3_procedures_ds_num = 22;
+++ /dev/null
-/**
- * collectd - src/nfs.h
- * Copyright (C) 2005 Jason Pepas
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Authors:
- * Jason Pepas <cell at ices.utexas.edu>
- * Florian octo Forster <octo at verplant.org>
- **/
-
-#ifndef NFS_H
-#define NFS_H
-
-#include "collectd.h"
-
-#ifndef COLLECT_NFS
-#if defined(KERNEL_LINUX)
-#define COLLECT_NFS 1
-#else
-#define COLLECT_NFS 0
-#endif
-#endif /* !defined(COLLECT_NFS) */
-
-#endif /* NFS_H */
static char *ds_def[] =
{
- "DS:ping:GAUGE:25:0:65535",
+ "DS:ping:GAUGE:"COLLECTD_HEARTBEAT":0:65535",
NULL
};
static int ds_num = 1;
static char *config_keys[] =
{
"Host",
+ "TTL",
NULL
};
-static int config_keys_num = 1;
+static int config_keys_num = 2;
static void ping_init (void)
{
static int ping_config (char *key, char *value)
{
- if (strcasecmp (key, "host"))
- {
- return (-1);
- }
-
if (pingobj == NULL)
{
if ((pingobj = ping_construct ()) == NULL)
{
syslog (LOG_ERR, "ping: `ping_construct' failed.\n");
- return (-1);
+ return (1);
}
}
- if (ping_host_add (pingobj, value) < 0)
+ if (strcasecmp (key, "host") == 0)
+ {
+ if (ping_host_add (pingobj, value) < 0)
+ {
+ syslog (LOG_WARNING, "ping: `ping_host_add' failed.");
+ return (1);
+ }
+ }
+ else if (strcasecmp (key, "ttl") == 0)
+ {
+ int ttl = atoi (value);
+ if (ping_setopt (pingobj, PING_DEF_TIMEOUT, (void *) &ttl))
+ {
+ syslog (LOG_WARNING, "ping: liboping did not accept the TTL value %i", ttl);
+ return (1);
+ }
+ }
+ else
{
- syslog (LOG_ERR, "ping: `ping_host_add' failed.\n");
return (-1);
}
+++ /dev/null
-/**
- * collectd - src/ping.h
- * Copyright (C) 2005 Florian octo Forster
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Authors:
- * Florian octo Forster <octo at verplant.org>
- **/
-
-#ifndef COLLECTD_PING_H
-#define COLLECTD_PING_H
-
-#include "collectd.h"
-#include "common.h"
-
-#ifndef COLLECT_PING
-#if defined(HAVE_NETINET_IN_H)
-#define COLLECT_PING 1
-#else
-#define COLLECT_PING 0
-#endif /* defined(HAVE_NETINET_IN_H) */
-#endif /* !defined(COLLECT_PING) */
-
-#if COLLECT_PING
-
-#define MAX_PINGHOSTS 32
-
-#endif /* COLLECT_PING */
-#endif
#include "plugin.h"
#include "network.h"
+#include "utils_debug.h"
typedef struct plugin
{
lt_dlhandle dlh;
void (*reg_handle) (void);
+ DBG ("file = %s", file);
+
lt_dlinit ();
lt_dlerror (); /* clear errors */
if ((dlh = lt_dlopen (file)) == NULL)
+ {
+ const char *error = lt_dlerror ();
+
+ syslog (LOG_ERR, "lt_dlopen failed: %s", error);
+ DBG ("lt_dlopen failed: %s", error);
return (1);
+ }
if ((reg_handle = lt_dlsym (dlh, "module_register")) == NULL)
{
struct stat statbuf;
struct dirent *de;
+ DBG ("type = %s", type);
+
dir = plugin_get_dir ();
ret = 1;
/**
* collectd - src/processes.c
* Copyright (C) 2005 Lyonel Vincent
+ * Copyright (C) 2006 Florian Forster (Mach code)
*
* 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
#include "collectd.h"
#include "common.h"
#include "plugin.h"
+#include "utils_debug.h"
+
+/* Include header files for the mach system, if they exist.. */
+#if HAVE_MACH_MACH_INIT_H
+# include <mach/mach_init.h>
+#endif
+#if HAVE_MACH_HOST_PRIV_H
+# include <mach/host_priv.h>
+#endif
+#if HAVE_MACH_MACH_ERROR_H
+# include <mach/mach_error.h>
+#endif
+#if HAVE_MACH_MACH_HOST_H
+# include <mach/mach_host.h>
+#endif
+#if HAVE_MACH_MACH_PORT_H
+# include <mach/mach_port.h>
+#endif
+#if HAVE_MACH_MACH_TYPES_H
+# include <mach/mach_types.h>
+#endif
+#if HAVE_MACH_MESSAGE_H
+# include <mach/message.h>
+#endif
+#if HAVE_MACH_PROCESSOR_SET_H
+# include <mach/processor_set.h>
+#endif
+#if HAVE_MACH_TASK_H
+# include <mach/task.h>
+#endif
+#if HAVE_MACH_THREAD_ACT_H
+# include <mach/thread_act.h>
+#endif
+#if HAVE_MACH_VM_REGION_H
+# include <mach/vm_region.h>
+#endif
+#if HAVE_MACH_VM_MAP_H
+# include <mach/vm_map.h>
+#endif
+#if HAVE_MACH_VM_PROT_H
+# include <mach/vm_prot.h>
+#endif
#define MODULE_NAME "processes"
-#ifdef KERNEL_LINUX
+#if HAVE_THREAD_INFO || KERNEL_LINUX
# define PROCESSES_HAVE_READ 1
#else
# define PROCESSES_HAVE_READ 0
static char *ds_def[] =
{
- "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:"COLLECTD_HEARTBEAT":0:65535",
+ "DS:sleeping:GAUGE:"COLLECTD_HEARTBEAT":0:65535",
+ "DS:zombies:GAUGE:"COLLECTD_HEARTBEAT":0:65535",
+ "DS:stopped:GAUGE:"COLLECTD_HEARTBEAT":0:65535",
+ "DS:paging:GAUGE:"COLLECTD_HEARTBEAT":0:65535",
+ "DS:blocked:GAUGE:"COLLECTD_HEARTBEAT":0:65535",
NULL
};
static int ds_num = 6;
+#if HAVE_THREAD_INFO
+static mach_port_t port_host_self;
+static mach_port_t port_task_self;
+
+static processor_set_name_array_t pset_list;
+static mach_msg_type_number_t pset_list_len;
+/* #endif HAVE_THREAD_INFO */
+
+#elif KERNEL_LINUX
+/* No global variables */
+#endif /* KERNEL_LINUX */
+
static void ps_init (void)
{
+#if HAVE_THREAD_INFO
+ kern_return_t status;
+
+ port_host_self = mach_host_self ();
+ port_task_self = mach_task_self ();
+
+ if (pset_list != NULL)
+ {
+ vm_deallocate (port_task_self,
+ (vm_address_t) pset_list,
+ pset_list_len * sizeof (processor_set_t));
+ pset_list = NULL;
+ pset_list_len = 0;
+ }
+
+ if ((status = host_processor_sets (port_host_self,
+ &pset_list,
+ &pset_list_len)) != KERN_SUCCESS)
+ {
+ syslog (LOG_ERR, "host_processor_sets failed: %s\n",
+ mach_error_string (status));
+ pset_list = NULL;
+ pset_list_len = 0;
+ return;
+ }
+/* #endif HAVE_THREAD_INFO */
+
+#elif KERNEL_LINUX
+ /* No init */
+#endif /* KERNEL_LINUX */
+
+ return;
}
static void ps_write (char *host, char *inst, char *val)
}
#if PROCESSES_HAVE_READ
-static void ps_submit (unsigned int running,
- unsigned int sleeping,
- unsigned int zombies,
- unsigned int stopped,
- unsigned int paging,
- unsigned int blocked)
+static void ps_submit (int running,
+ int sleeping,
+ int zombies,
+ int stopped,
+ int paging,
+ int blocked)
{
char buf[BUFSIZE];
- if (snprintf (buf, BUFSIZE, "%u:%u:%u:%u:%u:%u:%u",
+ if (snprintf (buf, BUFSIZE, "%u:%i:%i:%i:%i:%i:%i",
(unsigned int) curtime,
running, sleeping, zombies, stopped, paging,
blocked) >= BUFSIZE)
static void ps_read (void)
{
-#ifdef KERNEL_LINUX
- unsigned int running, sleeping, zombies, stopped, paging, blocked;
+#if HAVE_THREAD_INFO
+ kern_return_t status;
+
+ int pset;
+ processor_set_t port_pset_priv;
+
+ int task;
+ task_array_t task_list;
+ mach_msg_type_number_t task_list_len;
+
+ int thread;
+ thread_act_array_t thread_list;
+ mach_msg_type_number_t thread_list_len;
+ thread_basic_info_data_t thread_data;
+ mach_msg_type_number_t thread_data_len;
+
+ int running = 0;
+ int sleeping = 0;
+ int zombies = 0;
+ int stopped = 0;
+ int blocked = 0;
+
+ /*
+ * The Mach-concept is a little different from the traditional UNIX
+ * concept: All the work is done in threads. Threads are contained in
+ * `tasks'. Therefore, `task status' doesn't make much sense, since
+ * it's actually a `thread status'.
+ * Tasks are assigned to sets of processors, so that's where you go to
+ * get a list.
+ */
+ for (pset = 0; pset < pset_list_len; pset++)
+ {
+ if ((status = host_processor_set_priv (port_host_self,
+ pset_list[pset],
+ &port_pset_priv)) != KERN_SUCCESS)
+ {
+ syslog (LOG_ERR, "host_processor_set_priv failed: %s\n",
+ mach_error_string (status));
+ continue;
+ }
+
+ if ((status = processor_set_tasks (port_pset_priv,
+ &task_list,
+ &task_list_len)) != KERN_SUCCESS)
+ {
+ syslog (LOG_ERR, "processor_set_tasks failed: %s\n",
+ mach_error_string (status));
+ mach_port_deallocate (port_task_self, port_pset_priv);
+ continue;
+ }
+
+ for (task = 0; task < task_list_len; task++)
+ {
+ status = task_threads (task_list[task], &thread_list,
+ &thread_list_len);
+ if (status != KERN_SUCCESS)
+ {
+ /* Apple's `top' treats this case a zombie. It
+ * makes sense to some extend: A `zombie'
+ * thread is nonsense, since the task/process
+ * is dead. */
+ zombies++;
+ DBG ("task_threads failed: %s",
+ mach_error_string (status));
+ if (task_list[task] != port_task_self)
+ mach_port_deallocate (port_task_self,
+ task_list[task]);
+ continue; /* with next task_list */
+ }
+
+ for (thread = 0; thread < thread_list_len; thread++)
+ {
+ thread_data_len = THREAD_BASIC_INFO_COUNT;
+ status = thread_info (thread_list[thread],
+ THREAD_BASIC_INFO,
+ (thread_info_t) &thread_data,
+ &thread_data_len);
+ if (status != KERN_SUCCESS)
+ {
+ syslog (LOG_ERR, "thread_info failed: %s\n",
+ mach_error_string (status));
+ if (task_list[task] != port_task_self)
+ mach_port_deallocate (port_task_self,
+ thread_list[thread]);
+ continue; /* with next thread_list */
+ }
+
+ switch (thread_data.run_state)
+ {
+ case TH_STATE_RUNNING:
+ running++;
+ break;
+ case TH_STATE_STOPPED:
+ /* What exactly is `halted'? */
+ case TH_STATE_HALTED:
+ stopped++;
+ break;
+ case TH_STATE_WAITING:
+ sleeping++;
+ break;
+ case TH_STATE_UNINTERRUPTIBLE:
+ blocked++;
+ break;
+ /* There is no `zombie' case here,
+ * since there are no zombie-threads.
+ * There's only zombie tasks, which are
+ * handled above. */
+ default:
+ syslog (LOG_WARNING,
+ "Unknown thread status: %s",
+ thread_data.run_state);
+ break;
+ } /* switch (thread_data.run_state) */
+
+ if (task_list[task] != port_task_self)
+ {
+ status = mach_port_deallocate (port_task_self,
+ thread_list[thread]);
+ if (status != KERN_SUCCESS)
+ syslog (LOG_ERR, "mach_port_deallocate failed: %s",
+ mach_error_string (status));
+ }
+ } /* for (thread_list) */
+
+ if ((status = vm_deallocate (port_task_self,
+ (vm_address_t) thread_list,
+ thread_list_len * sizeof (thread_act_t)))
+ != KERN_SUCCESS)
+ {
+ syslog (LOG_ERR, "vm_deallocate failed: %s",
+ mach_error_string (status));
+ }
+ thread_list = NULL;
+ thread_list_len = 0;
+
+ /* Only deallocate the task port, if it isn't our own.
+ * Don't know what would happen in that case, but this
+ * is what Apple's top does.. ;) */
+ if (task_list[task] != port_task_self)
+ {
+ status = mach_port_deallocate (port_task_self,
+ task_list[task]);
+ if (status != KERN_SUCCESS)
+ syslog (LOG_ERR, "mach_port_deallocate failed: %s",
+ mach_error_string (status));
+ }
+ } /* for (task_list) */
+
+ if ((status = vm_deallocate (port_task_self,
+ (vm_address_t) task_list,
+ task_list_len * sizeof (task_t))) != KERN_SUCCESS)
+ {
+ syslog (LOG_ERR, "vm_deallocate failed: %s",
+ mach_error_string (status));
+ }
+ task_list = NULL;
+ task_list_len = 0;
+
+ if ((status = mach_port_deallocate (port_task_self, port_pset_priv))
+ != KERN_SUCCESS)
+ {
+ syslog (LOG_ERR, "mach_port_deallocate failed: %s",
+ mach_error_string (status));
+ }
+ } /* for (pset_list) */
+
+ ps_submit (running, sleeping, zombies, stopped, -1, blocked);
+/* #endif HAVE_THREAD_INFO */
+
+#elif KERNEL_LINUX
+ int running = 0;
+ int sleeping = 0;
+ int zombies = 0;
+ int stopped = 0;
+ int paging = 0;
+ int blocked = 0;
char buf[BUFSIZE];
char filename[20]; /* need 17 bytes */
closedir(proc);
ps_submit (running, sleeping, zombies, stopped, paging, blocked);
-#endif /* defined(KERNEL_LINUX) */
+#endif /* KERNEL_LINUX */
}
#else
# define ps_read NULL
+++ /dev/null
-/**
- * collectd - src/processes.h
- * Copyright (C) 2005 Lyonel Vincent
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Authors:
- * Lyonel Vincent <lyonel at ezix.org>
- * Florian octo Forster <octo at verplant.org>
- **/
-
-#ifndef PROCESSES_H
-#define PROCESSES_H
-
-#include "collectd.h"
-#include "common.h"
-
-#ifndef COLLECT_PROCESSES
-#if defined(KERNEL_LINUX)
-#define COLLECT_PROCESSES 1
-#else
-#define COLLECT_PROCESSES 0
-#endif
-#endif /* !defined(COLLECT_PROCESSES) */
-
-#endif /* PROCESSES_H */
static char *ds_def[] =
{
- "DS:value:GAUGE:25:U:U",
+ "DS:value:GAUGE:"COLLECTD_HEARTBEAT":U:U",
NULL
};
static int ds_num = 1;
+++ /dev/null
-/**
- * collectd - src/sensors.h
- * Copyright (C) 2005 Florian octo Forster
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Authors:
- * Florian octo Forster <octo at verplant.org>
- **/
-
-#ifndef SENSORS_H
-#define SENSORS_H
-
-#include "collectd.h"
-#include "common.h"
-
-/* Won't compile without header file */
-#ifndef HAVE_SENSORS_SENSORS_H
-#undef HAVE_LIBSENSORS
-#endif
-
-#ifndef COLLECT_SENSORS
-#ifdef HAVE_LIBSENSORS
-#define COLLECT_SENSORS 1
-#else
-#define COLLECT_SENSORS 0
-#endif
-#endif /* !defined(COLLECT_SENSORS) */
-
-#endif /* SENSORS_H */
static char *ds_def[] =
{
- "DS:incoming:COUNTER:25:0:U",
- "DS:outgoing:COUNTER:25:0:U",
+ "DS:incoming:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:outgoing:COUNTER:"COLLECTD_HEARTBEAT":0:U",
NULL
};
static int ds_num = 2;
+++ /dev/null
-/**
- * collectd - src/serial.h
- * Copyright (C) 2005 David Bacher
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Authors:
- * David Bacher <drbacher at gmail.com>
- * Florian octo Forster <octo at verplant.org>
- **/
-
-#ifndef SERIAL_H
-#define SERIAL_H
-
-#include "collectd.h"
-#include "common.h"
-
-#ifndef COLLECT_SERIAL
-#if defined(KERNEL_LINUX)
-#define COLLECT_SERIAL 1
-#else
-#define COLLECT_SERIAL 0
-#endif
-#endif /* !defined(COLLECT_SERIAL) */
-
-#endif /* SERIAL_H */
-
-
-
-
/* 1099511627776 == 1TB ought to be enough for anyone ;) */
static char *ds_def[] =
{
- "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:"COLLECTD_HEARTBEAT":0:1099511627776",
+ "DS:free:GAUGE:"COLLECTD_HEARTBEAT":0:1099511627776",
+ "DS:cached:GAUGE:"COLLECTD_HEARTBEAT":0:1099511627776",
+ "DS:resv:GAUGE:"COLLECTD_HEARTBEAT":0:1099511627776",
NULL
};
static int ds_num = 4;
+++ /dev/null
-/**
- * collectd - src/swap.h
- * Copyright (C) 2005 Florian octo Forster
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Authors:
- * Florian octo Forster <octo at verplant.org>
- **/
-
-#ifndef SWAP_H
-#define SWAP_H
-
-#include "collectd.h"
-#include "common.h"
-
-#ifndef COLLECT_SWAP
-#if defined(KERNEL_LINUX) || defined(HAVE_LIBKSTAT) || defined(HAVE_LIBSTATGRAB)
-#define COLLECT_SWAP 1
-#else
-#define COLLECT_SWAP 0
-#endif
-#endif /* !defined(COLLECT_SWAP) */
-
-#endif /* SWAP_H */
/* 104857600 == 100 MB */
static char *tape_ds_def[] =
{
- "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:"COLLECTD_HEARTBEAT":0:U",
+ "DS:rmerged:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:rbytes:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:rtime:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:wcount:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:wmerged:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:wbytes:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:wtime:COUNTER:"COLLECTD_HEARTBEAT":0:U",
NULL
};
static int tape_ds_num = 8;
+++ /dev/null
-/**
- * collectd - src/tape.h
- * Copyright (C) 2005 Scott Garrett
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Authors:
- * Scott Garrett <sgarrett at technomancer.com>
- **/
-
-#ifndef TAPESTATS_H
-#define TAPESTATS_H
-
-#include "collectd.h"
-#include "common.h"
-
-#ifndef COLLECT_TAPE
-#if defined(KERNEL_LINUX) || defined(HAVE_LIBKSTAT)
-#define COLLECT_TAPE 1
-#else
-#define COLLECT_TAPE 0
-#endif
-#endif /* !defined(COLLECT_TAPE) */
-
-#endif /* TAPESTATS_H */
#include "common.h"
#include "plugin.h"
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
+
+/* One cannot include both. This sucks. */
+#if HAVE_LINUX_IF_H
+# include <linux/if.h>
+#elif HAVE_NET_IF_H
+# include <net/if.h>
+#endif
+
+#if HAVE_LINUX_NETDEVICE_H
+# include <linux/netdevice.h>
+#endif
+#if HAVE_IFADDRS_H
+# include <ifaddrs.h>
+#endif
+
#define MODULE_NAME "traffic"
-#if defined(KERNEL_LINUX) || defined(HAVE_LIBKSTAT) || defined(HAVE_LIBSTATGRAB)
+#if HAVE_GETIFADDRS || defined(KERNEL_LINUX) || defined(HAVE_LIBKSTAT) || defined(HAVE_LIBSTATGRAB)
# define TRAFFIC_HAVE_READ 1
#else
# define TRAFFIC_HAVE_READ 0
static char *ds_def[] =
{
- "DS:incoming:COUNTER:25:0:U",
- "DS:outgoing:COUNTER:25:0:U",
+ "DS:incoming:COUNTER:"COLLECTD_HEARTBEAT":0:U",
+ "DS:outgoing:COUNTER:"COLLECTD_HEARTBEAT":0:U",
NULL
};
static int ds_num = 2;
static void traffic_init (void)
{
-#ifdef HAVE_LIBKSTAT
+#if HAVE_GETIFADDRS
+ /* nothing */
+/* #endif HAVE_GETIFADDRS */
+
+#elif KERNEL_LINUX
+ /* nothing */
+/* #endif KERNEL_LINUX */
+
+#elif HAVE_LIBKSTAT
kstat_t *ksp_chain;
unsigned long long val;
continue;
ksp[numif++] = ksp_chain;
}
-#endif /* HAVE_LIBKSTAT */
+/* #endif HAVE_LIBKSTAT */
+
+#elif HAVE_LIBSTATG
+ /* nothing */
+#endif /* HAVE_LIBSTATG */
+
+ return;
}
static void traffic_write (char *host, char *inst, char *val)
static void traffic_read (void)
{
-#ifdef KERNEL_LINUX
+#if HAVE_GETIFADDRS
+ struct ifaddrs *if_list;
+ struct ifaddrs *if_ptr;
+
+#if HAVE_STRUCT_IF_DATA
+# define IFA_DATA if_data
+# define IFA_INCOMING ifi_ibytes
+# define IFA_OUTGOING ifi_obytes
+#elif HAVE_STRUCT_NET_DEVICE_STATS
+# define IFA_DATA net_device_stats
+# define IFA_INCOMING rx_bytes
+# define IFA_OUTGOING tx_bytes
+#else
+# error "No suitable type for `struct ifaddrs->ifa_data' found."
+#endif
+
+ struct IFA_DATA *if_data;
+
+ if (getifaddrs (&if_list) != 0)
+ return;
+
+ for (if_ptr = if_list; if_ptr != NULL; if_ptr = if_ptr->ifa_next)
+ {
+ 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);
+ }
+
+ freeifaddrs (if_list);
+/* #endif HAVE_GETIFADDRS */
+
+#elif KERNEL_LINUX
FILE *fh;
char buffer[1024];
unsigned long long incoming, outgoing;
+++ /dev/null
-/**
- * collectd - src/traffic.h
- * Copyright (C) 2005 Florian octo Forster
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Authors:
- * Florian octo Forster <octo at verplant.org>
- **/
-
-#ifndef TRAFFIC_H
-#define TRAFFIC_H
-
-#include "collectd.h"
-#include "common.h"
-
-#ifndef COLLECT_TRAFFIC
-#if defined(KERNEL_LINUX) || defined(HAVE_LIBKSTAT) || defined(HAVE_LIBSTATGRAB)
-#define COLLECT_TRAFFIC 1
-#else
-#define COLLECT_TRAFFIC 0
-#endif
-#endif /* !defined(COLLECT_TRAFFIC) */
-
-#endif /* TRAFFIC_H */
static char *rrd_file = "users.rrd";
static char *ds_def[] =
{
- "DS:users:GAUGE:25:0:65535",
+ "DS:users:GAUGE:"COLLECTD_HEARTBEAT":0:65535",
NULL
};
static int ds_num = 1;
+++ /dev/null
-/**
- * collectd - src/users.h
- * Copyright (C) 2005 Sebastian Harl
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Authors:
- * Sebastian Harl <sh at tokkee.org>
- **/
-
-#if !COLLECTD_USERS_H
-#define COLLECTD_USERS_H 1
-
-void module_register(void);
-
-#endif /* !COLLECTD_USERS_H */
-
/* Get the number of mounted file systems */
if ((bufsize = getfsstat (NULL, 0, MNT_NOWAIT)) < 1)
+ {
+ DBG ("getfsstat failed: %s", strerror (errno));
return (NULL);
+ }
- if ((buf = (struct statfs *) malloc (bufsize * sizeof (struct statfs))) == NULL)
+ if ((buf = (struct statfs *) malloc (bufsize * sizeof (struct statfs)))
+ == NULL)
return (NULL);
memset (buf, '\0', bufsize * sizeof (struct statfs));
- /* FIXME: If `bufsize' in bytes or structures? */
- if ((num = getfsstat (buf, bufsize, MNT_NOWAIT)) < 1)
+ /* The bufsize needs to be passed in bytes. Really. This is not in the
+ * manpage.. -octo */
+ if ((num = getfsstat (buf, bufsize * sizeof (struct statfs), MNT_NOWAIT)) < 1)
{
+ DBG ("getfsstat failed: %s", strerror (errno));
free (buf);
return (NULL);
}
--- /dev/null
+/**
+ * collectd - src/vserver.c
+ * Copyright (C) 2006 Sebastian Harl
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors:
+ * Sebastian Harl <sh at tokkee.org>
+ **/
+
+#include "collectd.h"
+#include "common.h"
+#include "plugin.h"
+
+#include <dirent.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <syslog.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#define BUFSIZE 512
+
+#define MODULE_NAME "vserver"
+#define PROCDIR "/proc/virtual"
+
+#if defined(KERNEL_LINUX)
+# define VSERVER_HAVE_READ 1
+#else
+# define VSERVER_HAVE_READ 0
+#endif /* defined(KERNEL_LINUX) */
+
+static char *rrd_unix = "vserver-%s/traffic-unix.rrd";
+static char *rrd_inet = "vserver-%s/traffic-inet.rrd";
+static char *rrd_inet6 = "vserver-%s/traffic-inet6.rrd";
+static char *rrd_other = "vserver-%s/traffic-other.rrd";
+static char *rrd_unspec = "vserver-%s/traffic-unspec.rrd";
+
+static char *rrd_thread = "vserver-%s/vs_threads.rrd";
+
+static char *rrd_load = "vserver-%s/load.rrd";
+
+static char *rrd_procs = "vserver-%s/vs_processes.rrd";
+static char *rrd_memory = "vserver-%s/vs_memory.rrd";
+
+/* 9223372036854775807 == LLONG_MAX */
+/* bytes transferred */
+static char *ds_def_unix[] =
+{
+ "DS:incoming:COUNTER:"COLLECTD_HEARTBEAT":0:9223372036854775807",
+ "DS:outgoing:COUNTER:"COLLECTD_HEARTBEAT":0:9223372036854775807",
+ "DS:failed:COUNTER:"COLLECTD_HEARTBEAT":0:9223372036854775807",
+ NULL
+};
+static int ds_num_unix = 3;
+
+static char *ds_def_inet[] =
+{
+ "DS:incoming:COUNTER:"COLLECTD_HEARTBEAT":0:9223372036854775807",
+ "DS:outgoing:COUNTER:"COLLECTD_HEARTBEAT":0:9223372036854775807",
+ "DS:failed:COUNTER:"COLLECTD_HEARTBEAT":0:9223372036854775807",
+ NULL
+};
+static int ds_num_inet = 3;
+
+static char *ds_def_inet6[] =
+{
+ "DS:incoming:COUNTER:"COLLECTD_HEARTBEAT":0:9223372036854775807",
+ "DS:outgoing:COUNTER:"COLLECTD_HEARTBEAT":0:9223372036854775807",
+ "DS:failed:COUNTER:"COLLECTD_HEARTBEAT":0:9223372036854775807",
+ NULL
+};
+static int ds_num_inet6 = 3;
+
+static char *ds_def_other[] =
+{
+ "DS:incoming:COUNTER:"COLLECTD_HEARTBEAT":0:9223372036854775807",
+ "DS:outgoing:COUNTER:"COLLECTD_HEARTBEAT":0:9223372036854775807",
+ "DS:failed:COUNTER:"COLLECTD_HEARTBEAT":0:9223372036854775807",
+ NULL
+};
+static int ds_num_other = 3;
+
+static char *ds_def_unspec[] =
+{
+ "DS:incoming:COUNTER:"COLLECTD_HEARTBEAT":0:9223372036854775807",
+ "DS:outgoing:COUNTER:"COLLECTD_HEARTBEAT":0:9223372036854775807",
+ "DS:failed:COUNTER:"COLLECTD_HEARTBEAT":0:9223372036854775807",
+ NULL
+};
+static int ds_num_unspec = 3;
+
+static char *ds_def_threads[] =
+{
+ "DS:total:GAUGE:"COLLECTD_HEARTBEAT":0:65535",
+ "DS:running:GAUGE:"COLLECTD_HEARTBEAT":0:65535",
+ "DS:uninterruptible:GAUGE:"COLLECTD_HEARTBEAT":0:65535",
+ "DS:onhold:GAUGE:"COLLECTD_HEARTBEAT":0:65535",
+ NULL
+};
+static int ds_num_threads = 4;
+
+static char *ds_def_load[] =
+{
+ "DS:shortterm:GAUGE:"COLLECTD_HEARTBEAT":0:100",
+ "DS:midterm:GAUGE:"COLLECTD_HEARTBEAT":0:100",
+ "DS:longterm:GAUGE:"COLLECTD_HEARTBEAT":0:100",
+ NULL
+};
+static int ds_num_load = 3;
+
+static char *ds_def_procs[] =
+{
+ "DS:total:GAUGE:"COLLECTD_HEARTBEAT":0:65535",
+ NULL
+};
+static int ds_num_procs = 1;
+
+/* 9223372036854775807 == LLONG_MAX */
+/* bytes */
+static char *ds_def_memory[] =
+{
+ "DS:vm:GAUGE:"COLLECTD_HEARTBEAT":0:9223372036854775807",
+ "DS:vml:GAUGE:"COLLECTD_HEARTBEAT":0:9223372036854775807",
+ "DS:rss:GAUGE:"COLLECTD_HEARTBEAT":0:9223372036854775807",
+ "DS:anon:GAUGE:"COLLECTD_HEARTBEAT":0:9223372036854775807",
+ NULL
+};
+static int ds_num_memory = 4;
+
+static int pagesize = 0;
+
+static void vserver_init (void)
+{
+ /* XXX Should we check for getpagesize () in configure?
+ * What's the right thing to do, if there is no getpagesize ()? */
+ pagesize = getpagesize ();
+ return;
+} /* static void vserver_init(void) */
+
+static void vserver_unix_write (char *host, char *inst, char *val)
+{
+ int len;
+ char filename[BUFSIZE];
+
+ len = snprintf (filename, BUFSIZE, rrd_unix, inst);
+ if ((len > 0) && (len < BUFSIZE))
+ rrd_update_file (host, filename, val, ds_def_unix, ds_num_unix);
+ return;
+} /* static void vserver_unix_write(char *host, char *inst, char *val) */
+
+static void vserver_inet_write (char *host, char *inst, char *val)
+{
+ int len;
+ char filename[BUFSIZE];
+
+ len = snprintf (filename, BUFSIZE, rrd_inet, inst);
+ if ((len > 0) && (len < BUFSIZE))
+ rrd_update_file (host, filename, val, ds_def_inet, ds_num_inet);
+ return;
+} /* static void vserver_inet_write(char *host, char *inst, char *val) */
+
+static void vserver_inet6_write (char *host, char *inst, char *val)
+{
+ int len;
+ char filename[BUFSIZE];
+
+ len = snprintf (filename, BUFSIZE, rrd_inet6, inst);
+ if ((len > 0) && (len < BUFSIZE))
+ rrd_update_file (host, filename, val, ds_def_inet6, ds_num_inet6);
+ return;
+} /* static void vserver_inet6_write(char *host, char *inst, char *val) */
+
+static void vserver_other_write (char *host, char *inst, char *val)
+{
+ int len;
+ char filename[BUFSIZE];
+
+ len = snprintf (filename, BUFSIZE, rrd_other, inst);
+ if ((len > 0) && (len < BUFSIZE))
+ rrd_update_file (host, filename, val, ds_def_other, ds_num_other);
+ return;
+} /* static void vserver_other_write(char *host, char *inst, char *val) */
+
+static void vserver_unspec_write (char *host, char *inst, char *val)
+{
+ int len;
+ char filename[BUFSIZE];
+
+ len = snprintf (filename, BUFSIZE, rrd_unspec, inst);
+ if ((len > 0) && (len < BUFSIZE))
+ rrd_update_file (host, filename, val, ds_def_unspec, ds_num_unspec);
+ return;
+} /* static void vserver_unspec_write(char *host, char *inst, char *val) */
+
+static void vserver_threads_write (char *host, char *inst, char *val)
+{
+ int len;
+ char filename[BUFSIZE];
+
+ len = snprintf (filename, BUFSIZE, rrd_thread, inst);
+ if ((len > 0) && (len < BUFSIZE))
+ rrd_update_file (host, filename, val, ds_def_threads, ds_num_threads);
+ return;
+} /* static void vserver_threads_write(char *host, char *inst, char *val) */
+
+static void vserver_load_write (char *host, char *inst, char *val)
+{
+ int len;
+ char filename[BUFSIZE];
+
+ len = snprintf (filename, BUFSIZE, rrd_load, inst);
+ if ((len > 0) && (len < BUFSIZE))
+ rrd_update_file (host, filename, val, ds_def_load, ds_num_load);
+ return;
+} /* static void vserver_load_write(char *host, char *inst, char *val) */
+
+static void vserver_procs_write (char *host, char *inst, char *val)
+{
+ int len;
+ char filename[BUFSIZE];
+
+ len = snprintf (filename, BUFSIZE, rrd_procs, inst);
+ if ((len > 0) && (len < BUFSIZE))
+ rrd_update_file (host, filename, val, ds_def_procs, ds_num_procs);
+ return;
+} /* static void vserver_procs_write(char *host, char *inst, char *val) */
+
+static void vserver_memory_write (char *host, char *inst, char *val)
+{
+ int len;
+ char filename[BUFSIZE];
+
+ len = snprintf (filename, BUFSIZE, rrd_memory, inst);
+ if ((len > 0) && (len < BUFSIZE))
+ rrd_update_file (host, filename, val, ds_def_memory, ds_num_memory);
+ return;
+} /* static void vserver_memory_write(char *host, char *inst, char *val) */
+
+#if VSERVER_HAVE_READ
+static void vserver_submit (char *inst, long long unix_in, long long unix_out,
+ long long unix_failed, long long inet_in, long long inet_out,
+ long long inet_failed, long long inet6_in, long long inet6_out,
+ long long inet6_failed, long long other_in, long long other_out,
+ long long other_failed, long long unspec_in, long long unspec_out,
+ long long unspec_failed, int t_total, int t_running,
+ int t_uninterruptible, int t_onhold, double avg1, double avg5,
+ double avg15, int p_total, long long vm, long long vml, long long rss,
+ long long anon)
+{
+ int len;
+ char buffer[BUFSIZE];
+
+ len = snprintf (buffer, BUFSIZE,
+ "N:%lld:%lld:%lld", unix_in, unix_out, unix_failed);
+
+ if ((len > 0) && (len < BUFSIZE))
+ plugin_submit ("vserver_unix", inst, buffer);
+
+
+ len = snprintf (buffer, BUFSIZE,
+ "N:%lld:%lld:%lld", inet_in, inet_out, inet_failed);
+
+ if ((len > 0) && (len < BUFSIZE))
+ plugin_submit ("vserver_inet", inst, buffer);
+
+
+ len = snprintf (buffer, BUFSIZE,
+ "N:%lld:%lld:%lld", inet6_in, inet6_out, inet6_failed);
+
+ if ((len > 0) && (len < BUFSIZE))
+ plugin_submit ("vserver_inet6", inst, buffer);
+
+
+ len = snprintf (buffer, BUFSIZE,
+ "N:%lld:%lld:%lld", other_in, other_out, other_failed);
+
+ if ((len > 0) && (len < BUFSIZE))
+ plugin_submit ("vserver_other", inst, buffer);
+
+
+ len = snprintf (buffer, BUFSIZE,
+ "N:%lld:%lld:%lld", unspec_in, unspec_out, unspec_failed);
+
+ if ((len > 0) && (len < BUFSIZE))
+ plugin_submit ("vserver_unspec", inst, buffer);
+
+
+ len = snprintf (buffer, BUFSIZE, "N:%d:%d:%d:%d",
+ t_total, t_running, t_uninterruptible, t_onhold);
+
+ if ((len > 0) && (len < BUFSIZE))
+ plugin_submit ("vserver_threads", inst, buffer);
+
+
+ len = snprintf (buffer, BUFSIZE, "N:%.2f:%.2f:%.2f",
+ avg1, avg5, avg15);
+
+ if ((len > 0) && (len < BUFSIZE))
+ plugin_submit ("vserver_load", inst, buffer);
+
+
+ len = snprintf (buffer, BUFSIZE, "N:%d",
+ p_total);
+
+ if ((len > 0) && (len < BUFSIZE))
+ plugin_submit ("vserver_procs", inst, buffer);
+
+
+ len = snprintf (buffer, BUFSIZE, "N:%lld:%lld:%lld:%lld",
+ vm, vml, rss, anon);
+
+ if ((len > 0) && (len < BUFSIZE))
+ plugin_submit ("vserver_memory", inst, buffer);
+ return;
+} /* static void vserver_submit() */
+
+static inline long long __get_sock_bytes(const char *s)
+{
+ while (s[0] != '/')
+ ++s;
+
+ /* Remove '/' */
+ ++s;
+ return atoll(s);
+}
+
+static void vserver_read (void)
+{
+ DIR *proc;
+ struct dirent *dent; /* 42 */
+
+ errno = 0;
+ if (NULL == (proc = opendir (PROCDIR))) {
+ syslog (LOG_ERR, "Cannot open '%s': %s", PROCDIR, strerror (errno));
+ return;
+ }
+
+ while (NULL != (dent = readdir (proc))) {
+ int len;
+ char file[BUFSIZE];
+
+ FILE *fh;
+ char buffer[BUFSIZE];
+
+ char *cols[4];
+
+ long long unix_s[3] = {-1, -1, -1};
+ long long inet[3] = {-1, -1, -1};
+ long long inet6[3] = {-1, -1, -1};
+ long long other[3] = {-1, -1, -1};
+ long long unspec[3] = {-1, -1, -1};
+ int threads[4] = {-1, -1, -1, -1};
+ double load[3] = {-1, -1, -1};
+ /* Just to be consistent ;-) */
+ int procs[1] = {-1};
+ long long memory[4] = {-1, -1, -1, -1};
+
+ if (dent->d_name[0] == '.')
+ continue;
+
+ /* XXX This check is just the result of a trial-and-error test.
+ * I did not find any documentation describing the d_type field. */
+ if (!(dent->d_type & 0x4))
+ /* This is not a directory */
+ continue;
+
+ /* socket message accounting */
+ len = snprintf (file, BUFSIZE, PROCDIR "/%s/cacct", dent->d_name);
+ if ((len < 0) || (len >= BUFSIZE))
+ continue;
+
+ if (NULL == (fh = fopen (file, "r"))) {
+ syslog (LOG_ERR, "Cannot open '%s': %s", file, strerror (errno));
+ continue;
+ }
+
+ while (NULL != fgets (buffer, BUFSIZE, fh)) {
+ if (strsplit (buffer, cols, 4) < 4)
+ continue;
+
+ if (0 == strcmp (cols[0], "UNIX:")) {
+ unix_s[0] = __get_sock_bytes (cols[1]);
+ unix_s[1] = __get_sock_bytes (cols[2]);
+ unix_s[2] = __get_sock_bytes (cols[3]);
+ }
+ else if (0 == strcmp (cols[0], "INET:")) {
+ inet[0] = __get_sock_bytes (cols[1]);
+ inet[1] = __get_sock_bytes (cols[2]);
+ inet[2] = __get_sock_bytes (cols[3]);
+ }
+ else if (0 == strcmp (cols[0], "INET6:")) {
+ inet6[0] = __get_sock_bytes (cols[1]);
+ inet6[1] = __get_sock_bytes (cols[2]);
+ inet6[2] = __get_sock_bytes (cols[3]);
+ }
+ else if (0 == strcmp (cols[0], "OTHER:")) {
+ other[0] = __get_sock_bytes (cols[1]);
+ other[1] = __get_sock_bytes (cols[2]);
+ other[2] = __get_sock_bytes (cols[3]);
+ }
+ else if (0 == strcmp (cols[0], "UNSPEC:")) {
+ unspec[0] = __get_sock_bytes (cols[1]);
+ unspec[1] = __get_sock_bytes (cols[2]);
+ unspec[2] = __get_sock_bytes (cols[3]);
+ }
+ }
+
+ fclose (fh);
+
+ /* thread information and load */
+ len = snprintf (file, BUFSIZE, PROCDIR "/%s/cvirt", dent->d_name);
+ if ((len < 0) || (len >= BUFSIZE))
+ continue;
+
+ if (NULL == (fh = fopen (file, "r"))) {
+ syslog (LOG_ERR, "Cannot open '%s': %s", file, strerror (errno));
+ continue;
+ }
+
+ while (NULL != fgets (buffer, BUFSIZE, fh)) {
+ int n = strsplit (buffer, cols, 4);
+
+ if (2 == n) {
+ if (0 == strcmp (cols[0], "nr_threads:")) {
+ threads[0] = atoi (cols[1]);
+ }
+ else if (0 == strcmp (cols[0], "nr_running:")) {
+ threads[1] = atoi (cols[1]);
+ }
+ else if (0 == strcmp (cols[0], "nr_unintr:")) {
+ threads[2] = atoi (cols[1]);
+ }
+ else if (0 == strcmp (cols[0], "nr_onhold:")) {
+ threads[3] = atoi (cols[1]);
+ }
+ }
+ else if (4 == n) {
+ if (0 == strcmp (cols[0], "loadavg:")) {
+ load[0] = atof (cols[1]);
+ load[1] = atof (cols[2]);
+ load[2] = atof (cols[3]);
+ }
+ }
+ }
+
+ fclose (fh);
+
+ /* processes and memory usage */
+ len = snprintf (file, BUFSIZE, PROCDIR "/%s/limit", dent->d_name);
+ if ((len < 0) || (len >= BUFSIZE))
+ continue;
+
+ if (NULL == (fh = fopen (file, "r"))) {
+ syslog (LOG_ERR, "Cannot open '%s': %s", file, strerror (errno));
+ continue;
+ }
+
+ while (NULL != fgets (buffer, BUFSIZE, fh)) {
+ if (strsplit (buffer, cols, 2) < 2)
+ continue;
+
+ if (0 == strcmp (cols[0], "PROC:")) {
+ procs[0] = atoi (cols[1]);
+ }
+ else if (0 == strcmp (cols[0], "VM:")) {
+ memory[0] = atoll (cols[1]) * pagesize;
+ }
+ else if (0 == strcmp (cols[0], "VML:")) {
+ memory[1] = atoll (cols[1]) * pagesize;
+ }
+ else if (0 == strcmp (cols[0], "RSS:")) {
+ memory[2] = atoll (cols[1]) * pagesize;
+ }
+ else if (0 == strcmp (cols[0], "ANON:")) {
+ memory[3] = atoll (cols[1]) * pagesize;
+ }
+ }
+
+ fclose (fh);
+
+ /* XXX What to do in case of an error (i.e. some value is
+ * still -1)? */
+
+ vserver_submit (dent->d_name, unix_s[0], unix_s[1], unix_s[2],
+ inet[0], inet[1], inet[2], inet6[0], inet6[1], inet6[2],
+ other[0], other[1], other[2], unspec[0], unspec[1], unspec[2],
+ threads[0], threads[1], threads[2], threads[3], load[0],
+ load[1], load[2], procs[0], memory[0], memory[1], memory[2],
+ memory[3]);
+ }
+
+ closedir (proc);
+ return;
+} /* static void vserver_read(void) */
+#else
+# define vserver_read NULL
+#endif /* VSERVER_HAVE_READ */
+
+void module_register (void)
+{
+ plugin_register (MODULE_NAME, vserver_init, vserver_read, NULL);
+ plugin_register ("vserver_unix", NULL, NULL, vserver_unix_write);
+ plugin_register ("vserver_inet", NULL, NULL, vserver_inet_write);
+ plugin_register ("vserver_inet6", NULL, NULL, vserver_inet6_write);
+ plugin_register ("vserver_other", NULL, NULL, vserver_other_write);
+ plugin_register ("vserver_unspec", NULL, NULL, vserver_unspec_write);
+ plugin_register ("vserver_threads", NULL, NULL, vserver_threads_write);
+ plugin_register ("vserver_load", NULL, NULL, vserver_load_write);
+ plugin_register ("vserver_procs", NULL, NULL, vserver_procs_write);
+ plugin_register ("vserver_memory", NULL, NULL, vserver_memory_write);
+ return;
+} /* void module_register(void) */
+
+/* vim: set ts=4 sw=4 noexpandtab : */
#include "common.h"
#include "plugin.h"
-#include <math.h>
-
#define MODULE_NAME "wireless"
#define BUFSIZE 1024
static char *ds_def[] =
{
- "DS:quality:GAUGE:25:0:U",
- "DS:power:GAUGE:25:0:U",
- "DS:noise:GAUGE:25:0:U",
+ "DS:quality:GAUGE:"COLLECTD_HEARTBEAT":0:U",
+ "DS:power:GAUGE:"COLLECTD_HEARTBEAT":U:0",
+ "DS:noise:GAUGE:"COLLECTD_HEARTBEAT":U:0",
NULL
};
static int ds_num = 3;
}
#if WIRELESS_HAVE_READ
+#if 0
static double wireless_dbm_to_watt (double dbm)
{
double watt;
return (watt);
}
+#endif
static void wireless_submit (char *device,
double quality, double power, double noise)
power = atof (fields[3]);
noise = atof (fields[4]);
+ /* Fill in invalid values when conversion failed.. */
if (quality == 0.0)
- quality = -1.0;
+ quality = -1.0; /* quality >= 0 */
- if (power >= 0.0)
- power = -1.0;
- else
- power = wireless_dbm_to_watt (power);
+ if (power == 0.0)
+ power = 1.0; /* power <= 0 */
- if (noise >= 0.0)
- noise = -1.0;
- else
- noise = wireless_dbm_to_watt (noise);
+ if (noise == 0.0)
+ noise = 1.0; /* noise <= 0 */
wireless_submit (device, quality, power, noise);
}
void module_register (void)
{
- plugin_register (MODULE_NAME, wireless_init, wireless_read, wireless_write);
+ plugin_register (MODULE_NAME, wireless_init, wireless_read, wireless_write);
}
#undef BUFSIZE