From: Florian Forster Date: Sat, 9 May 2009 10:39:12 +0000 (+0200) Subject: Merge branch 'collectd-4.6' into collectd-4.7 X-Git-Tag: collectd-4.7.0~13 X-Git-Url: https://git.octo.it/?a=commitdiff_plain;h=f71895576cbd4b488cd66f0c96efb6fd3e7a6faf;hp=37905c5a2370c8e6edae5011978773eeaa589d09;p=collectd.git Merge branch 'collectd-4.6' into collectd-4.7 --- diff --git a/AUTHORS b/AUTHORS index 782e8f2b..9f82ee1b 100644 --- a/AUTHORS +++ b/AUTHORS @@ -21,6 +21,9 @@ Alessandro Iurlano Alvaro Barcellos - Don't-fork patch. +Amit Gupta + - Multiple servers in the apache plugin. + Anthony Gialluca - apcups plugin. @@ -49,12 +52,18 @@ Doug MacEachern - jcollectd (two-way JMX integration). - A few other patches to various plugins. +Edward “Koko” Konetzko + - fscache plugin. + Fabian Linzberger - Percentage aggregation for `collectd-nagios'. Flavio Stanchina - mbmon plugin. +Franck Lombardi + - UNIX socket code for the memcached plugin. + Jason Pepas - nfs plugin. @@ -69,6 +78,10 @@ Luke Herberling Lyonel Vincent - processes plugin. +Marco Chiappero + - uptime plugin. + - ip6tables support in the iptables plugin. + Michael Stapelberg - OpenBSD port of the tcpconns plugin. @@ -107,15 +120,24 @@ Richard W. M. Jones Roman Klesel - Oracle schema and sample SQL statements to be used with the Oracle plugin. +Rodolphe Quiédeville + - Lock statistics in the mysql plugin. + Scott Garrett - tape plugin. +Simon Kuhnle + - OpenBSD code for the cpu and memory plugins. + Sjoerd van der Berg - iptables plugin. Stefan Hacker - teamspeak2 plugin. +Tomasz Pala + - conntrack plugin. + Tommie Gannert - PID-file patch. diff --git a/ChangeLog b/ChangeLog index 924d4045..9d85ff08 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,47 @@ +2009-05-01, Version 4.7.0 + * apache plugin: Support to query multiple servers has been added. + Thanks to Amit Gupta for the patch. + * apache plugin: Handling of lighttpd's scoreboard statistics has been + improved. Thanks to Amit Gupta for the patch. + * conntrack plugin: The new conntrack plugin collects the connection + tracking table size. Thanks to Tomasz Pala for the patch. + * fscache plugin: The new fscache plugin collects statistics about + Linux' file-system based caching framework. Thanks to Edward + Konetzko for the patch. + * gmond plugin: The new gmond plugin can receive and interpret + multicast traffic from Ganglia's gmond daemon. + * java plugin: The new java plugin exports the collectd API to Java, + making it possible to write extensions to collectd in Java. + * memcachec plugin: The new memcachec plugin queries data from a + memcached daemon and parses it similar to the cURL plugin. Thanks to + Doug MacEachern for the initial code. + * memcached plugin: Support for connections over UNIX domain sockets + has been added. Thanks to Franck Lombardi for the patch. + * memory plugin: Support for OpenBSD and possibly other *BSDs has been + added. Thanks to Simon Kuhnle for the patch. + * mysql plugin: Support to query multiple databases has been added. + Thanks to Doug MacEachern for the patch. + * mysql plugin: Master/slave statistics have been added. + * mysql plugin: Lock statistics have been added. Thanks to Rodolphe + Quiédeville for the patch. + * network plugin: The possibility to sign or encrypt network traffic + has been added. + * protocols plugin: The new protocols plugin provides information + about network protocols, such as IP, TCP and UDP. + * snmp plugin: The intervals given in the configuration of the SNMP + plugin must no longer be a multiple of the global interval. + * table plugin: The new Table plugin provides parsing for table-like + structured files, such as many files beneath /proc. + * ted plugin: The new TED plugin reads power consumption measurements + from “The Energy Detective” (TED). Thanks to Eric Reed for this + plugin. + * onewire plugin: The new `Interval' option allows collecting + information from OneWire sensors at arbitrary intervals. + * ping plugin: Support for collecting the drop rate and standard + deviation of round-trip times has been added. + * uptime plugin: The new uptime plugin can collect the server's + uptime. Thanks to Marco Chiappero for the patch. + 2009-03-18, Version 4.6.2 * collectd: Some Solaris utility code has been improved. * filter subsystem: Allow `Chains' without default targets. diff --git a/README b/README index b6417411..a1bf5ff2 100644 --- a/README +++ b/README @@ -40,6 +40,9 @@ Features Name server and resolver statistics from the `statistics-channel' interface of BIND 9.5, 9,6 and later. + - conntrack + Number of nf_conntrack entries. + - cpu CPU utilization: Time spent in the system, user, nice, idle, and related states. @@ -76,6 +79,9 @@ Features - filecount Count the number of files in directories. + - gmond + Receive multicast traffic from Ganglia instances. + - hddtemp Harddisk temperatures using hddtempd. @@ -98,6 +104,10 @@ Features - irq IRQ counters: Frequency in which certain interrupts occur. + - java + Integrates a `Java Virtual Machine' (JVM) to execute plugins in Java + bytecode. See “Configuring with libjvm” below. + - load System load average over the last 1, 5 and 15 minutes. @@ -179,6 +189,9 @@ Features - processes Process counts: Number of running, sleeping, zombie, ... processes. + - protocols + Counts various aspects of network protocols such as IP, TCP, UDP, etc. + - rrdcached RRDtool caching daemon (RRDcacheD) statistics. @@ -210,6 +223,9 @@ Features - teamspeak2 TeamSpeak2 server statistics. + - ted + Plugin to read values from `The Energy Detective' (TED). + - thermal Linux ACPI thermal zone information. @@ -424,6 +440,11 @@ Prerequisites For querying iptables counters. + * libjvm (optional) + Library that encapsulates the `Java Virtual Machine' (JVM). This library is + used by the Java plugin to execute Java bytecode. See “Configuring with + libjvm” below. + * libmysqlclient (optional) Unsurprisingly used by the `mysql' plugin. @@ -522,6 +543,42 @@ Configuring / Compiling / Installing prefixed to all installation directories. This might be useful when creating packages for collectd. +Configuring with libjvm +----------------------- + + To determine the location of the required files of a Java installation is not + an easy task, because the locations vary with your kernel (Linux, SunOS, …) + and with your architecture (x86, SPARC, …) and there is no ‘java-config’ + script we could use. Configuration of the JVM library is therefore a bit + tricky. + + The easiest way to use the `--with-java=$JAVA_HOME' option, where + `$JAVA_HOME' is usually something like: + /usr/lib/jvm/java-1.5.0-sun-1.5.0.14 + + The configure script will then use find(1) to look for the following files: + + - jni.h + - jni_md.h + - libjvm.so + + If found, appropriate CPP-flags and LD-flags are set and the following + library checks succeed. + + If this doesn't work for you, you have the possibility to specify CPP-flags, + C-flags and LD-flags for the ‘Java’ plugin by hand, using the following three + (environment) variables: + + - JAVA_CPPFLAGS + - JAVA_CFLAGS + - JAVA_LDFLAGS + + For example (shortened for demonstration purposes): + + ./configure JAVA_CPPFLAGS="-I$JAVA_HOME/include -I$JAVA_HOME/include/linux" + + Adding "-ljvm" to the JAVA_LDFLAGS is done automatically, you don't have to + do that. Crosscompiling -------------- diff --git a/bindings/java/org/collectd/api/Collectd.java b/bindings/java/org/collectd/api/Collectd.java new file mode 100644 index 00000000..84e65926 --- /dev/null +++ b/bindings/java/org/collectd/api/Collectd.java @@ -0,0 +1,295 @@ +/* + * collectd/java - org/collectd/api/Collectd.java + * Copyright (C) 2009 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; only version 2 of the License is applicable. + * + * 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 + */ + +package org.collectd.api; + +/** + * Java API to internal functions of collectd. + * + * All functions in this class are {@code static}. You don't need to create an + * object of this class (in fact, you can't). Just call these functions + * directly. + * + * @author Florian Forster <octo at verplant.org> + */ +public class Collectd +{ + + /** + * Constant for severity (log level) "error". + * + * @see CollectdLogInterface + */ + public static final int LOG_ERR = 3; + + /** + * Constant for severity (log level) "warning". + * + * @see CollectdLogInterface + */ + public static final int LOG_WARNING = 4; + + /** + * Constant for severity (log level) "notice". + * + * @see CollectdLogInterface + */ + public static final int LOG_NOTICE = 5; + + /** + * Constant for severity (log level) "info". + * + * @see CollectdLogInterface + */ + public static final int LOG_INFO = 6; + + /** + * Constant for severity (log level) "debug". + * + * @see CollectdLogInterface + */ + public static final int LOG_DEBUG = 7; + + /** + * Return value of match methods: No match. + * + * This is one of two valid return values from match callbacks, indicating + * that the passed {@link DataSet} and {@link ValueList} did not match. + * + * Do not use the numeric value directly, it is subject to change without + * notice! + * + * @see CollectdMatchInterface + */ + public static final int FC_MATCH_NO_MATCH = 0; + + /** + * Return value of match methods: Match. + * + * This is one of two valid return values from match callbacks, indicating + * that the passed {@link DataSet} and {@link ValueList} did match. + * + * Do not use the numeric value directly, it is subject to change without + * notice! + * + * @see CollectdMatchInterface + */ + public static final int FC_MATCH_MATCHES = 1; + + /** + * Return value of target methods: Continue. + * + * This is one of three valid return values from target callbacks, indicating + * that processing of the {@link ValueList} should continue. + * + * Do not use the numeric value directly, it is subject to change without + * notice! + * + * @see CollectdTargetInterface + */ + public static final int FC_TARGET_CONTINUE = 0; + + /** + * Return value of target methods: Stop. + * + * This is one of three valid return values from target callbacks, indicating + * that processing of the {@link ValueList} should stop immediately. + * + * Do not use the numeric value directly, it is subject to change without + * notice! + * + * @see CollectdTargetInterface + */ + public static final int FC_TARGET_STOP = 1; + + /** + * Return value of target methods: Return. + * + * This is one of three valid return values from target callbacks, indicating + * that processing of the current chain should be stopped and processing of + * the {@link ValueList} should continue in the calling chain. + * + * Do not use the numeric value directly, it is subject to change without + * notice! + * + * @see CollectdTargetInterface + */ + public static final int FC_TARGET_RETURN = 2; + + /** + * Java representation of collectd/src/plugin.h:plugin_register_config + * + * @return Zero when successful, non-zero otherwise. + * @see CollectdConfigInterface + */ + native public static int registerConfig (String name, + CollectdConfigInterface object); + + /** + * Java representation of collectd/src/plugin.h:plugin_register_init + * + * @return Zero when successful, non-zero otherwise. + * @see CollectdInitInterface + */ + native public static int registerInit (String name, + CollectdInitInterface object); + + /** + * Java representation of collectd/src/plugin.h:plugin_register_read + * + * @return Zero when successful, non-zero otherwise. + * @see CollectdReadInterface + */ + native public static int registerRead (String name, + CollectdReadInterface object); + + /** + * Java representation of collectd/src/plugin.h:plugin_register_write + * + * @return Zero when successful, non-zero otherwise. + * @see CollectdWriteInterface + */ + native public static int registerWrite (String name, + CollectdWriteInterface object); + + /** + * Java representation of collectd/src/plugin.h:plugin_register_flush + * + * @return Zero when successful, non-zero otherwise. + * @see CollectdFlushInterface + */ + native public static int registerFlush (String name, + CollectdFlushInterface object); + + /** + * Java representation of collectd/src/plugin.h:plugin_register_shutdown + * + * @return Zero when successful, non-zero otherwise. + * @see CollectdShutdownInterface + */ + native public static int registerShutdown (String name, + CollectdShutdownInterface object); + + /** + * Java representation of collectd/src/plugin.h:plugin_register_log + * + * @return Zero when successful, non-zero otherwise. + * @see CollectdLogInterface + */ + native public static int registerLog (String name, + CollectdLogInterface object); + + /** + * Java representation of collectd/src/plugin.h:plugin_register_notification + * + * @return Zero when successful, non-zero otherwise. + * @see CollectdNotificationInterface + */ + native public static int registerNotification (String name, + CollectdNotificationInterface object); + + /** + * Java representation of collectd/src/filter_chain.h:fc_register_match + * + * @return Zero when successful, non-zero otherwise. + * @see CollectdMatchFactoryInterface + */ + native public static int registerMatch (String name, + CollectdMatchFactoryInterface object); + + /** + * Java representation of collectd/src/filter_chain.h:fc_register_target + * + * @return Zero when successful, non-zero otherwise. + * @see CollectdTargetFactoryInterface + */ + native public static int registerTarget (String name, + CollectdTargetFactoryInterface object); + + /** + * Java representation of collectd/src/plugin.h:plugin_dispatch_values + * + * @return Zero when successful, non-zero otherwise. + */ + native public static int dispatchValues (ValueList vl); + + /** + * Java representation of collectd/src/plugin.h:plugin_dispatch_notification + * + * @return Zero when successful, non-zero otherwise. + */ + native public static int dispatchNotification (Notification n); + + /** + * Java representation of collectd/src/plugin.h:plugin_get_ds + * + * @return The appropriate {@link DataSet} object or {@code null} if no such + * type is registered. + */ + native public static DataSet getDS (String type); + + /** + * Java representation of collectd/src/plugin.h:plugin_log + */ + native private static void log (int severity, String message); + + /** + * Prints an error message. + */ + public static void logError (String message) + { + log (LOG_ERR, message); + } /* void logError */ + + /** + * Prints a warning message. + */ + public static void logWarning (String message) + { + log (LOG_WARNING, message); + } /* void logWarning */ + + /** + * Prints a notice. + */ + public static void logNotice (String message) + { + log (LOG_NOTICE, message); + } /* void logNotice */ + + /** + * Prints an info message. + */ + public static void logInfo (String message) + { + log (LOG_INFO, message); + } /* void logInfo */ + + /** + * Prints a debug message. + */ + public static void logDebug (String message) + { + log (LOG_DEBUG, message); + } /* void logDebug */ +} /* class Collectd */ + +/* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/bindings/java/org/collectd/api/CollectdConfigInterface.java b/bindings/java/org/collectd/api/CollectdConfigInterface.java new file mode 100644 index 00000000..060f9442 --- /dev/null +++ b/bindings/java/org/collectd/api/CollectdConfigInterface.java @@ -0,0 +1,33 @@ +/* + * collectd/java - org/collectd/api/CollectdConfigInterface.java + * Copyright (C) 2009 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; only version 2 of the License is applicable. + * + * 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 + */ + +package org.collectd.api; + +/** + * Interface for objects implementing a config method. + * + * @author Florian Forster <octo at verplant.org> + * @see Collectd#registerConfig(String, CollectdConfigInterface) + */ +public interface CollectdConfigInterface +{ + public int config (OConfigItem ci); +} diff --git a/bindings/java/org/collectd/api/CollectdFlushInterface.java b/bindings/java/org/collectd/api/CollectdFlushInterface.java new file mode 100644 index 00000000..3e492ddf --- /dev/null +++ b/bindings/java/org/collectd/api/CollectdFlushInterface.java @@ -0,0 +1,33 @@ +/* + * collectd/java - org/collectd/api/CollectdFlushInterface.java + * Copyright (C) 2009 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; only version 2 of the License is applicable. + * + * 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 + */ + +package org.collectd.api; + +/** + * Interface for objects implementing a flush method. + * + * @author Florian Forster <octo at verplant.org> + * @see Collectd#registerFlush + */ +public interface CollectdFlushInterface +{ + public int flush (int timeout, String identifier); +} diff --git a/bindings/java/org/collectd/api/CollectdInitInterface.java b/bindings/java/org/collectd/api/CollectdInitInterface.java new file mode 100644 index 00000000..fbfd3061 --- /dev/null +++ b/bindings/java/org/collectd/api/CollectdInitInterface.java @@ -0,0 +1,33 @@ +/* + * collectd/java - org/collectd/api/CollectdInitInterface.java + * Copyright (C) 2009 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; only version 2 of the License is applicable. + * + * 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 + */ + +package org.collectd.api; + +/** + * Interface for objects implementing an init method. + * + * @author Florian Forster <octo at verplant.org> + * @see Collectd#registerInit + */ +public interface CollectdInitInterface +{ + public int init (); +} diff --git a/bindings/java/org/collectd/api/CollectdLogInterface.java b/bindings/java/org/collectd/api/CollectdLogInterface.java new file mode 100644 index 00000000..ba0350a2 --- /dev/null +++ b/bindings/java/org/collectd/api/CollectdLogInterface.java @@ -0,0 +1,33 @@ +/* + * collectd/java - org/collectd/api/CollectdLogInterface.java + * Copyright (C) 2009 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; only version 2 of the License is applicable. + * + * 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 + */ + +package org.collectd.api; + +/** + * Interface for objects implementing a log method. + * + * @author Florian Forster <octo at verplant.org> + * @see Collectd#registerLog + */ +public interface CollectdLogInterface +{ + public void log (int severity, String message); +} diff --git a/bindings/java/org/collectd/api/CollectdMatchFactoryInterface.java b/bindings/java/org/collectd/api/CollectdMatchFactoryInterface.java new file mode 100644 index 00000000..7b1c71a4 --- /dev/null +++ b/bindings/java/org/collectd/api/CollectdMatchFactoryInterface.java @@ -0,0 +1,49 @@ +/* + * collectd/java - org/collectd/api/CollectdMatchFactoryInterface.java + * Copyright (C) 2009 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; only version 2 of the License is applicable. + * + * 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 + */ + +package org.collectd.api; + +/** + * Interface for objects implementing a "match factory". + * + * Objects implementing this interface are used to create objects implementing + * the CollectdMatchInterface interface. + * + * @author Florian Forster <octo at verplant.org> + * @see CollectdMatchInterface + * @see Collectd#registerMatch + */ +public interface CollectdMatchFactoryInterface +{ + /** + * Create a new "match" object. + * + * This method uses the configuration provided as argument to create a + * new object which must implement the {@link CollectdMatchInterface} + * interface. + * + * This function corresponds to the create member of the + * src/filter_chain.h:match_proc_t struct. + * + * @return New {@link CollectdMatchInterface} object. + */ + public CollectdMatchInterface createMatch (OConfigItem ci); +} diff --git a/bindings/java/org/collectd/api/CollectdMatchInterface.java b/bindings/java/org/collectd/api/CollectdMatchInterface.java new file mode 100644 index 00000000..cc8a99e6 --- /dev/null +++ b/bindings/java/org/collectd/api/CollectdMatchInterface.java @@ -0,0 +1,48 @@ +/* + * collectd/java - org/collectd/api/CollectdMatchInterface.java + * Copyright (C) 2009 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; only version 2 of the License is applicable. + * + * 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 + */ + +package org.collectd.api; + +/** + * Interface for objects implementing a match method. + * + * These objects are instantiated using objects which implement the + * CollectdMatchFactoryInterface interface. They are not instantiated by the + * daemon directly! + * + * @author Florian Forster <octo at verplant.org> + * @see CollectdMatchFactoryInterface + * @see Collectd#registerMatch + */ +public interface CollectdMatchInterface +{ + /** + * Callback method for matches. + * + * This method is called to decide whether or not a given ValueList + * matches or not. How this is determined is the is the main part of + * this function. + * + * @return One of {@link Collectd#FC_MATCH_NO_MATCH} and {@link Collectd#FC_MATCH_MATCHES}. + * @see CollectdMatchFactoryInterface + */ + public int match (DataSet ds, ValueList vl); +} /* public interface CollectdMatchInterface */ diff --git a/bindings/java/org/collectd/api/CollectdNotificationInterface.java b/bindings/java/org/collectd/api/CollectdNotificationInterface.java new file mode 100644 index 00000000..d278fe21 --- /dev/null +++ b/bindings/java/org/collectd/api/CollectdNotificationInterface.java @@ -0,0 +1,33 @@ +/* + * collectd/java - org/collectd/api/CollectdNotificationInterface.java + * Copyright (C) 2009 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; only version 2 of the License is applicable. + * + * 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 + */ + +package org.collectd.api; + +/** + * Interface for objects implementing a notification method. + * + * @author Florian Forster <octo at verplant.org> + * @see Collectd#registerNotification + */ +public interface CollectdNotificationInterface +{ + public int notification (Notification n); +} diff --git a/bindings/java/org/collectd/api/CollectdReadInterface.java b/bindings/java/org/collectd/api/CollectdReadInterface.java new file mode 100644 index 00000000..67f1898b --- /dev/null +++ b/bindings/java/org/collectd/api/CollectdReadInterface.java @@ -0,0 +1,47 @@ +/* + * collectd/java - org/collectd/api/CollectdReadInterface.java + * Copyright (C) 2009 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; only version 2 of the License is applicable. + * + * 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 + */ + +package org.collectd.api; + +/** + * Interface for objects implementing a read method. + * + * Objects implementing this interface can be registered with the daemon. Their + * read method is then called periodically to acquire and submit values. + * + * @author Florian Forster <octo at verplant.org> + * @see Collectd#registerRead + */ +public interface CollectdReadInterface +{ + /** + * Callback method for read plugins. + * + * This method is called once every few seconds (depends on the + * configuration of the daemon). It is supposed to gather values in + * some way and submit them to the daemon using + * {@link Collectd#dispatchValues}. + * + * @return zero when successful, non-zero when an error occurred. + * @see Collectd#dispatchValues + */ + public int read (); +} diff --git a/bindings/java/org/collectd/api/CollectdShutdownInterface.java b/bindings/java/org/collectd/api/CollectdShutdownInterface.java new file mode 100644 index 00000000..108c54ed --- /dev/null +++ b/bindings/java/org/collectd/api/CollectdShutdownInterface.java @@ -0,0 +1,33 @@ +/* + * collectd/java - org/collectd/api/CollectdShutdownInterface.java + * Copyright (C) 2009 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; only version 2 of the License is applicable. + * + * 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 + */ + +package org.collectd.api; + +/** + * Interface for objects implementing a shutdown method. + * + * @author Florian Forster <octo at verplant.org> + * @see Collectd#registerShutdown + */ +public interface CollectdShutdownInterface +{ + public int shutdown (); +} diff --git a/bindings/java/org/collectd/api/CollectdTargetFactoryInterface.java b/bindings/java/org/collectd/api/CollectdTargetFactoryInterface.java new file mode 100644 index 00000000..65f61818 --- /dev/null +++ b/bindings/java/org/collectd/api/CollectdTargetFactoryInterface.java @@ -0,0 +1,49 @@ +/* + * collectd/java - org/collectd/api/CollectdTargetFactoryInterface.java + * Copyright (C) 2009 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; only version 2 of the License is applicable. + * + * 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 + */ + +package org.collectd.api; + +/** + * Interface for objects implementing a "target factory". + * + * Objects implementing this interface are used to create objects implementing + * the CollectdTargetInterface interface. + * + * @author Florian Forster <octo at verplant.org> + * @see CollectdTargetInterface + * @see Collectd#registerTarget + */ +public interface CollectdTargetFactoryInterface +{ + /** + * Create a new "target" object. + * + * This method uses the configuration provided as argument to create a + * new object which must implement the {@link CollectdTargetInterface} + * interface. + * + * This function corresponds to the {@code create} member of the + * {@code src/filter_chain.h:target_proc_t} struct. + * + * @return New {@link CollectdTargetInterface} object. + */ + public CollectdTargetInterface createTarget (OConfigItem ci); +} diff --git a/bindings/java/org/collectd/api/CollectdTargetInterface.java b/bindings/java/org/collectd/api/CollectdTargetInterface.java new file mode 100644 index 00000000..74412a32 --- /dev/null +++ b/bindings/java/org/collectd/api/CollectdTargetInterface.java @@ -0,0 +1,48 @@ +/* + * collectd/java - org/collectd/api/CollectdTargetInterface.java + * Copyright (C) 2009 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; only version 2 of the License is applicable. + * + * 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 + */ + +package org.collectd.api; + +/** + * Interface for objects implementing a target method. + * + * These objects are instantiated using objects which implement the + * CollectdTargetFactoryInterface interface. They are not instantiated by the + * daemon directly! + * + * @author Florian Forster <octo at verplant.org> + * @see CollectdTargetFactoryInterface + * @see Collectd#registerTarget + */ +public interface CollectdTargetInterface +{ + /** + * Callback method for targets. + * + * This method is called to perform some action on the given ValueList. + * What precisely is done depends entirely on the implementing class. + * + * @return One of: {@link Collectd#FC_TARGET_CONTINUE}, + * {@link Collectd#FC_TARGET_STOP}, {@link Collectd#FC_TARGET_RETURN} + * @see CollectdTargetFactoryInterface + */ + public int invoke (DataSet ds, ValueList vl); +} /* public interface CollectdTargetInterface */ diff --git a/bindings/java/org/collectd/api/CollectdWriteInterface.java b/bindings/java/org/collectd/api/CollectdWriteInterface.java new file mode 100644 index 00000000..28e0230b --- /dev/null +++ b/bindings/java/org/collectd/api/CollectdWriteInterface.java @@ -0,0 +1,33 @@ +/* + * collectd/java - org/collectd/api/CollectdWriteInterface.java + * Copyright (C) 2009 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; only version 2 of the License is applicable. + * + * 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 + */ + +package org.collectd.api; + +/** + * Interface for objects implementing a write method. + * + * @author Florian Forster <octo at verplant.org> + * @see Collectd#registerWrite + */ +public interface CollectdWriteInterface +{ + public int write (ValueList vl); +} diff --git a/bindings/java/org/collectd/api/DataSet.java b/bindings/java/org/collectd/api/DataSet.java new file mode 100644 index 00000000..98230730 --- /dev/null +++ b/bindings/java/org/collectd/api/DataSet.java @@ -0,0 +1,137 @@ +/* + * collectd/java - org/collectd/api/OConfigItem.java + * Copyright (C) 2009 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; only version 2 of the License is applicable. + * + * 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 + */ + +package org.collectd.api; + +import java.util.List; +import java.util.ArrayList; + +/** + * Java representation of collectd/src/plugin.h:data_set_t structure. + * + * @author Florian Forster <octo at verplant.org> + */ +public class DataSet +{ + private String _type; + private List _ds; + + private DataSet () + { + this._type = null; + this._ds = new ArrayList (); + } + + public DataSet (String type) + { + this._type = type; + this._ds = new ArrayList (); + } + + public DataSet (String type, DataSource dsrc) + { + this._type = type; + this._ds = new ArrayList (); + this._ds.add (dsrc); + } + + public DataSet (String type, List ds) + { + this._type = type; + this._ds = ds; + } + + public void setType (String type) + { + this._type = type; + } + + public String getType () + { + return (this._type); + } + + public void addDataSource (DataSource dsrc) + { + this._ds.add (dsrc); + } + + public List getDataSources () + { + return (this._ds); + } + + public String toString () + { + StringBuffer sb = new StringBuffer (); + int i; + + sb.append (this._type); + for (i = 0; i < this._ds.size (); i++) + { + if (i == 0) + sb.append ("\t"); + else + sb.append (", "); + sb.append (this._ds.get (i).toString ()); + } + + return (sb.toString ()); + } + + static public DataSet parseDataSet (String str) + { + DataSet ds = new DataSet (); + String[] fields; + int i; + + str = str.trim(); + if (str.length() == 0) { + return (null); + } + if (str.charAt(0) == '#') { + return (null); + } + + fields = str.split ("\\s+"); + if (fields.length < 2) + return (null); + + ds._type = fields[0]; + + for (i = 1; i < fields.length; i++) { + DataSource dsrc; + + dsrc = DataSource.parseDataSource (fields[i]); + if (dsrc == null) + break; + + ds._ds.add (dsrc); + } + + if (i < fields.length) + return (null); + + return (ds); + } /* DataSet parseDataSet */ +} /* class DataSet */ + +/* vim: set sw=4 sts=4 et : */ diff --git a/bindings/java/org/collectd/api/DataSource.java b/bindings/java/org/collectd/api/DataSource.java new file mode 100644 index 00000000..bfe8e2d0 --- /dev/null +++ b/bindings/java/org/collectd/api/DataSource.java @@ -0,0 +1,145 @@ +/* + * jcollectd + * Copyright (C) 2009 Hyperic, Inc. + * + * 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; only version 2 of the License is applicable. + * + * 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 + */ + +package org.collectd.api; + +/** + * Java representation of collectd/src/plugin.h:data_source_t structure. + */ +public class DataSource { + public static final int TYPE_COUNTER = 0; + public static final int TYPE_GAUGE = 1; + + static final String COUNTER = "COUNTER"; + static final String GAUGE = "GAUGE"; + + static final String NAN = "U"; + private static final String[] TYPES = { COUNTER, GAUGE }; + + String _name; + int _type; + double _min; + double _max; + + public DataSource (String name, int type, double min, double max) { + this._name = name; + this._type = TYPE_GAUGE; + if (type == TYPE_COUNTER) + this._type = TYPE_COUNTER; + this._min = min; + this._max = max; + } + + /* Needed in parseDataSource below. Other code should use the above + * constructor or `parseDataSource'. */ + private DataSource () { + this._type = TYPE_GAUGE; + } + + public String getName() { + return _name; + } + + public void setName(String name) { + _name = name; + } + + public int getType() { + return _type; + } + + public void setType(int type) { + _type = type; + } + + public double getMin() { + return _min; + } + + public void setMin(double min) { + _min = min; + } + + public double getMax() { + return _max; + } + + public void setMax(double max) { + _max = max; + } + + static double toDouble(String val) { + if (val.equals(NAN)) { + return Double.NaN; + } + else { + return Double.parseDouble(val); + } + } + + private String asString(double val) { + if (Double.isNaN(val)) { + return NAN; + } + else { + return String.valueOf(val); + } + } + + public String toString() { + StringBuffer sb = new StringBuffer(); + final char DLM = ':'; + sb.append(_name).append(DLM); + sb.append(TYPES[_type]).append(DLM); + sb.append(asString(_min)).append(DLM); + sb.append(asString(_max)); + return sb.toString(); + } + + static public DataSource parseDataSource (String str) + { + String[] fields; + int str_len = str.length (); + DataSource dsrc = new DataSource (); + + /* Ignore trailing commas. This makes it easier for parsing code. */ + if (str.charAt (str_len - 1) == ',') { + str = str.substring (0, str_len - 1); + } + + fields = str.split(":"); + if (fields.length != 4) + return (null); + + dsrc._name = fields[0]; + + if (fields[1].equals (DataSource.GAUGE)) { + dsrc._type = TYPE_GAUGE; + } + else { + dsrc._type = TYPE_COUNTER; + } + + dsrc._min = toDouble (fields[2]); + dsrc._max = toDouble (fields[3]); + + return (dsrc); + } /* DataSource parseDataSource */ +} + +/* vim: set sw=4 sts=4 et : */ diff --git a/bindings/java/org/collectd/api/Notification.java b/bindings/java/org/collectd/api/Notification.java new file mode 100644 index 00000000..cfc21863 --- /dev/null +++ b/bindings/java/org/collectd/api/Notification.java @@ -0,0 +1,88 @@ +/* + * jcollectd + * Copyright (C) 2009 Hyperic, Inc. + * + * 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; only version 2 of the License is applicable. + * + * 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 + */ + +package org.collectd.api; + +/** + * Java representation of collectd/src/plugin.h:notfication_t structure. + */ +public class Notification extends PluginData { + public static final int FAILURE = 1; + public static final int WARNING = 2; + public static final int OKAY = 4; + + public static String[] SEVERITY = { + "FAILURE", + "WARNING", + "OKAY", + "UNKNOWN" + }; + + private int _severity; + private String _message; + + public Notification () { + _severity = 0; + _message = "Initial notification message"; + } + + public Notification (PluginData pd) { + super (pd); + _severity = 0; + _message = "Initial notification message"; + } + + public void setSeverity (int severity) { + if ((severity == FAILURE) + || (severity == WARNING) + || (severity == OKAY)) + this._severity = severity; + } + + public int getSeverity() { + return _severity; + } + + public String getSeverityString() { + switch (_severity) { + case FAILURE: + return SEVERITY[0]; + case WARNING: + return SEVERITY[1]; + case OKAY: + return SEVERITY[2]; + default: + return SEVERITY[3]; + } + } + + public void setMessage (String message) { + this._message = message; + } + + public String getMessage() { + return _message; + } + + public String toString() { + StringBuffer sb = new StringBuffer(super.toString()); + sb.append(" [").append(getSeverityString()).append("] "); + sb.append(_message); + return sb.toString(); + } +} diff --git a/bindings/java/org/collectd/api/OConfigItem.java b/bindings/java/org/collectd/api/OConfigItem.java new file mode 100644 index 00000000..4c6a778d --- /dev/null +++ b/bindings/java/org/collectd/api/OConfigItem.java @@ -0,0 +1,91 @@ +/* + * collectd/java - org/collectd/api/OConfigItem.java + * Copyright (C) 2009 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; only version 2 of the License is applicable. + * + * 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 + */ + +package org.collectd.api; + +import java.util.List; +import java.util.ArrayList; + +/** + * Java representation of collectd/src/liboconfig/oconfig.h:oconfig_item_t structure. + * + * @author Florian Forster <octo at verplant.org> + */ +public class OConfigItem +{ + private String _key = null; + private List _values = new ArrayList (); + private List _children = new ArrayList (); + + public OConfigItem (String key) + { + _key = key; + } /* OConfigItem (String key) */ + + public String getKey () + { + return (_key); + } /* String getKey () */ + + public void addValue (OConfigValue cv) + { + _values.add (cv); + } /* void addValue (OConfigValue cv) */ + + public void addValue (String s) + { + _values.add (new OConfigValue (s)); + } /* void addValue (String s) */ + + public void addValue (Number n) + { + _values.add (new OConfigValue (n)); + } /* void addValue (String s) */ + + public void addValue (boolean b) + { + _values.add (new OConfigValue (b)); + } /* void addValue (String s) */ + + public List getValues () + { + return (_values); + } /* List getValues () */ + + public void addChild (OConfigItem ci) + { + _children.add (ci); + } /* void addChild (OConfigItem ci) */ + + public List getChildren () + { + return (_children); + } /* List getChildren () */ + + public String toString () + { + return (new String ("{ key: " + _key + "; " + + "values: " + _values.toString () + "; " + + "children: " + _children.toString () + "; }")); + } /* String toString () */ +} /* class OConfigItem */ + +/* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/bindings/java/org/collectd/api/OConfigValue.java b/bindings/java/org/collectd/api/OConfigValue.java new file mode 100644 index 00000000..1ebafff7 --- /dev/null +++ b/bindings/java/org/collectd/api/OConfigValue.java @@ -0,0 +1,96 @@ +/* + * collectd/java - org/collectd/api/OConfigValue.java + * Copyright (C) 2009 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; only version 2 of the License is applicable. + * + * 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 + */ + +package org.collectd.api; + +/** + * Java representation of collectd/src/liboconfig/oconfig.h:oconfig_value_t structure. + * + * @author Florian Forster <octo at verplant.org> + */ +public class OConfigValue +{ + public static final int OCONFIG_TYPE_STRING = 0; + public static final int OCONFIG_TYPE_NUMBER = 1; + public static final int OCONFIG_TYPE_BOOLEAN = 2; + + private int _type; + private String _value_string; + private Number _value_number; + private boolean _value_boolean; + + public OConfigValue (String s) + { + _type = OCONFIG_TYPE_STRING; + _value_string = s; + _value_number = null; + _value_boolean = false; + } /* OConfigValue (String s) */ + + public OConfigValue (Number n) + { + _type = OCONFIG_TYPE_NUMBER; + _value_string = null; + _value_number = n; + _value_boolean = false; + } /* OConfigValue (String s) */ + + public OConfigValue (boolean b) + { + _type = OCONFIG_TYPE_BOOLEAN; + _value_string = null; + _value_number = null; + _value_boolean = b; + } /* OConfigValue (String s) */ + + public int getType () + { + return (_type); + } /* int getType */ + + public String getString () + { + return (_value_string); + } /* String getString */ + + public Number getNumber () + { + return (_value_number); + } /* String getString */ + + public boolean getBoolean () + { + return (_value_boolean); + } /* String getString */ + + public String toString () + { + if (_type == OCONFIG_TYPE_STRING) + return (_value_string); + else if (_type == OCONFIG_TYPE_NUMBER) + return (_value_number.toString ()); + else if (_type == OCONFIG_TYPE_BOOLEAN) + return (Boolean.toString (_value_boolean)); + return (null); + } /* String toString () */ +} /* class OConfigValue */ + +/* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/bindings/java/org/collectd/api/PluginData.java b/bindings/java/org/collectd/api/PluginData.java new file mode 100644 index 00000000..26b0206d --- /dev/null +++ b/bindings/java/org/collectd/api/PluginData.java @@ -0,0 +1,127 @@ +/* + * jcollectd + * Copyright (C) 2009 Hyperic, Inc. + * + * 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; only version 2 of the License is applicable. + * + * 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 + */ + +package org.collectd.api; + +import java.util.Date; + +/** + * Shared members of value_list_t and notification_t structures. + */ +public class PluginData { + + protected long _time = 0; + protected String _host; + protected String _plugin; + protected String _pluginInstance = ""; + protected String _type = ""; + protected String _typeInstance = ""; + + public PluginData() { + + } + + public PluginData(PluginData pd) { + _time = pd._time; + _host = pd._host; + _plugin = pd._plugin; + _pluginInstance = pd._pluginInstance; + _type = pd._type; + _typeInstance = pd._typeInstance; + } + + public long getTime() { + return _time; + } + + public void setTime(long time) { + _time = time; + } + + public String getHost() { + return _host; + } + + public void setHost(String host) { + _host = host; + } + + public String getPlugin() { + return _plugin; + } + + public void setPlugin(String plugin) { + _plugin = plugin; + } + + public String getPluginInstance() { + return _pluginInstance; + } + + public void setPluginInstance(String pluginInstance) { + _pluginInstance = pluginInstance; + } + + public String getType() { + return _type; + } + + public void setType(String type) { + _type = type; + } + + public String getTypeInstance() { + return _typeInstance; + } + + public void setTypeInstance(String typeInstance) { + _typeInstance = typeInstance; + } + + public boolean defined(String val) { + return (val != null) && (val.length() > 0); + } + + public String getSource() { + final char DLM = '/'; + StringBuffer sb = new StringBuffer(); + if (defined(_host)) { + sb.append(_host); + } + if (defined(_plugin)) { + sb.append(DLM).append(_plugin); + } + if (defined(_pluginInstance)) { + sb.append(DLM).append(_pluginInstance); + } + if (defined(_type)) { + sb.append(DLM).append(_type); + } + if (defined(_typeInstance)) { + sb.append(DLM).append(_typeInstance); + } + return sb.toString(); + } + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append('[').append(new Date(_time)).append("] "); + sb.append(getSource()); + return sb.toString(); + } +} diff --git a/bindings/java/org/collectd/api/ValueList.java b/bindings/java/org/collectd/api/ValueList.java new file mode 100644 index 00000000..1baeff24 --- /dev/null +++ b/bindings/java/org/collectd/api/ValueList.java @@ -0,0 +1,122 @@ +/* + * jcollectd + * Copyright (C) 2009 Hyperic, Inc. + * + * 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; only version 2 of the License is applicable. + * + * 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 + */ + +package org.collectd.api; + +import java.util.ArrayList; +import java.util.List; + +/** + * Java representation of collectd/src/plugin.h:value_list_t structure. + */ +public class ValueList extends PluginData { + + private List _values = new ArrayList(); + private DataSet _ds; + + private long _interval = 0; + + public ValueList() { + + } + + public ValueList(PluginData pd) { + super(pd); + } + + public ValueList(ValueList vl) { + this((PluginData)vl); + _interval = vl._interval; + _values.addAll(vl.getValues()); + _ds = vl._ds; + } + + public List getValues() { + return _values; + } + + public void setValues(List values) { + _values = values; + } + + public void addValue(Number value) { + _values.add(value); + } + + /* Used by the network parsing code */ + public void clearValues () { + _values.clear (); + } + + /** + * @deprecated Use {@link #getDataSet()} instead. + */ + public List getDataSource() { + if (_ds == null) + return null; + return _ds.getDataSources (); + } + + public DataSet getDataSet () { + return _ds; + } + + public void setDataSet (DataSet ds) { + _ds = ds; + } + + /** + * @deprecated Use {@link #setDataSet(DataSet)} instead. + */ + public void setDataSource(List dsrc) { + _ds = new DataSet (_type, dsrc); + } + + public long getInterval() { + return _interval; + } + + public void setInterval(long interval) { + _interval = interval; + } + + public String toString() { + StringBuffer sb = new StringBuffer(super.toString()); + sb.append("=["); + List ds = getDataSource(); + int size = _values.size(); + for (int i=0; i + */ + +package org.collectd.java; + +import java.util.List; +import java.util.Date; + +import java.lang.management.ManagementFactory; +import java.lang.management.MemoryUsage; +import java.lang.management.MemoryMXBean; + +import javax.management.MBeanServerConnection; +import javax.management.remote.JMXConnector; +import javax.management.remote.JMXConnectorFactory; +import javax.management.remote.JMXServiceURL; + +import org.collectd.api.Collectd; +import org.collectd.api.DataSet; +import org.collectd.api.ValueList; +import org.collectd.api.Notification; +import org.collectd.api.OConfigItem; + +import org.collectd.api.CollectdConfigInterface; +import org.collectd.api.CollectdInitInterface; +import org.collectd.api.CollectdReadInterface; +import org.collectd.api.CollectdShutdownInterface; + +import org.collectd.api.OConfigValue; +import org.collectd.api.OConfigItem; + +public class JMXMemory implements CollectdConfigInterface, /* {{{ */ + CollectdInitInterface, + CollectdReadInterface, + CollectdShutdownInterface +{ + private String _jmx_service_url = null; + private MemoryMXBean _mbean = null; + + public JMXMemory () + { + Collectd.registerConfig ("JMXMemory", this); + Collectd.registerInit ("JMXMemory", this); + Collectd.registerRead ("JMXMemory", this); + Collectd.registerShutdown ("JMXMemory", this); + } + + private void submit (String plugin_instance, MemoryUsage usage) /* {{{ */ + { + ValueList vl; + + long mem_init; + long mem_used; + long mem_committed; + long mem_max; + + mem_init = usage.getInit (); + mem_used = usage.getUsed (); + mem_committed = usage.getCommitted (); + mem_max = usage.getMax (); + + Collectd.logDebug ("JMXMemory plugin: plugin_instance = " + plugin_instance + "; " + + "mem_init = " + mem_init + "; " + + "mem_used = " + mem_used + "; " + + "mem_committed = " + mem_committed + "; " + + "mem_max = " + mem_max + ";"); + + vl = new ValueList (); + + vl.setHost ("localhost"); + vl.setPlugin ("JMXMemory"); + vl.setPluginInstance (plugin_instance); + vl.setType ("memory"); + + if (mem_init >= 0) + { + vl.addValue (mem_init); + vl.setTypeInstance ("init"); + Collectd.dispatchValues (vl); + vl.clearValues (); + } + + if (mem_used >= 0) + { + vl.addValue (mem_used); + vl.setTypeInstance ("used"); + Collectd.dispatchValues (vl); + vl.clearValues (); + } + + if (mem_committed >= 0) + { + vl.addValue (mem_committed); + vl.setTypeInstance ("committed"); + Collectd.dispatchValues (vl); + vl.clearValues (); + } + + if (mem_max >= 0) + { + vl.addValue (mem_max); + vl.setTypeInstance ("max"); + Collectd.dispatchValues (vl); + vl.clearValues (); + } + } /* }}} void submit */ + + private int configServiceURL (OConfigItem ci) /* {{{ */ + { + List values; + OConfigValue cv; + + values = ci.getValues (); + if (values.size () != 1) + { + Collectd.logError ("JMXMemory plugin: The JMXServiceURL option needs " + + "exactly one string argument."); + return (-1); + } + + cv = values.get (0); + if (cv.getType () != OConfigValue.OCONFIG_TYPE_STRING) + { + Collectd.logError ("JMXMemory plugin: The JMXServiceURL option needs " + + "exactly one string argument."); + return (-1); + } + + _jmx_service_url = cv.getString (); + return (0); + } /* }}} int configServiceURL */ + + public int config (OConfigItem ci) /* {{{ */ + { + List children; + int i; + + Collectd.logDebug ("JMXMemory plugin: config: ci = " + ci + ";"); + + children = ci.getChildren (); + for (i = 0; i < children.size (); i++) + { + OConfigItem child; + String key; + + child = children.get (i); + key = child.getKey (); + if (key.equalsIgnoreCase ("JMXServiceURL")) + { + configServiceURL (child); + } + else + { + Collectd.logError ("JMXMemory plugin: Unknown config option: " + key); + } + } + + return (0); + } /* }}} int config */ + + public int init () /* {{{ */ + { + JMXServiceURL service_url; + JMXConnector connector; + MBeanServerConnection connection; + + if (_jmx_service_url == null) + { + Collectd.logError ("JMXMemory: _jmx_service_url == null"); + return (-1); + } + + try + { + service_url = new JMXServiceURL (_jmx_service_url); + connector = JMXConnectorFactory.connect (service_url); + connection = connector.getMBeanServerConnection (); + _mbean = ManagementFactory.newPlatformMXBeanProxy (connection, + ManagementFactory.MEMORY_MXBEAN_NAME, + MemoryMXBean.class); + } + catch (Exception e) + { + Collectd.logError ("JMXMemory: Creating MBean failed: " + e); + return (-1); + } + + return (0); + } /* }}} int init */ + + public int read () /* {{{ */ + { + if (_mbean == null) + { + Collectd.logError ("JMXMemory: _mbean == null"); + return (-1); + } + + submit ("heap", _mbean.getHeapMemoryUsage ()); + submit ("non_heap", _mbean.getNonHeapMemoryUsage ()); + + return (0); + } /* }}} int read */ + + public int shutdown () /* {{{ */ + { + System.out.print ("org.collectd.java.JMXMemory.Shutdown ();\n"); + _jmx_service_url = null; + _mbean = null; + return (0); + } /* }}} int shutdown */ +} /* }}} class JMXMemory */ + +/* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/clean.sh b/clean.sh index 5733f2ea..098669da 100755 --- a/clean.sh +++ b/clean.sh @@ -43,4 +43,8 @@ true \ && rm -f src/libping/config.h.in \ && rm -f src/libping/Makefile \ && rm -f src/libping/Makefile.in \ -&& rm -f src/libping/stamp-h2 +&& rm -f src/libping/stamp-h2 \ +&& rm -f -r src/libcollectdclient/.libs \ +&& rm -f src/libcollectdclient/*.o \ +&& rm -f src/libcollectdclient/*.la \ +&& rm -f src/libcollectdclient/*.lo diff --git a/configure.in b/configure.in index 795a9e12..287a9e56 100644 --- a/configure.in +++ b/configure.in @@ -67,13 +67,27 @@ fi if test "x$ac_system" = "xSolaris" then - CPPFLAGS="$CPPFLAGS -D_POSIX_PTHREAD_SEMANTICS" + AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1, [Define to enforce POSIX thread semantics under Solaris.]) fi # Where to install .pc files. pkgconfigdir="${libdir}/pkgconfig" AC_SUBST(pkgconfigdir) +# Check for standards compliance mode +AC_ARG_ENABLE(standards, + AS_HELP_STRING([--enable-standards], [Enable standards compliance mode]), + [enable_standards="$enableval"], + [enable_standards="no"]) +if test "x$enable_standards" = "xyes" +then + AC_DEFINE(_ISOC99_SOURCE, 1, [Define to enforce ISO C99 compliance.]) + AC_DEFINE(_POSIX_C_SOURCE, 200112L, [Define to enforce POSIX.1-2001 compliance.]) + AC_DEFINE(_XOPEN_SOURCE, 600, [Define to enforce X/Open 6 (XSI) compliance.]) + AC_DEFINE(_REENTRANT, 1, [Define to enable reentrancy interfaces.]) +fi +AM_CONDITIONAL(BUILD_FEATURE_STANDARDS, test "x$enable_standards" = "xyes") + # # Checks for header files. # @@ -355,7 +369,7 @@ AC_CHECK_HEADERS(linux/un.h, [], [], #endif ]) -AC_CHECK_HEADERS(pwd.h grp.h sys/un.h ctype.h limits.h sys/quota.h xfs/xqm.h fs_info.h fshelp.h paths.h mntent.h mnttab.h sys/fstyp.h sys/fs_types.h sys/mntent.h sys/mnttab.h sys/statfs.h sys/statvfs.h sys/vfs.h sys/vfstab.h kvm.h wordexp.h) +AC_CHECK_HEADERS(pwd.h grp.h sys/un.h ctype.h limits.h xfs/xqm.h fs_info.h fshelp.h paths.h mntent.h mnttab.h sys/fstyp.h sys/fs_types.h sys/mntent.h sys/mnttab.h sys/statfs.h sys/statvfs.h sys/vfs.h sys/vfstab.h kvm.h wordexp.h) # For the dns plugin AC_CHECK_HEADERS(arpa/nameser.h) @@ -914,7 +928,8 @@ AC_CHECK_MEMBERS([struct kinfo_proc.kp_proc, struct kinfo_proc.kp_eproc], ]) AC_CHECK_MEMBERS([struct udphdr.uh_dport, struct udphdr.uh_sport], [], [], -[#if HAVE_STDINT_H +[#define _BSD_SOURCE +#if HAVE_STDINT_H # include #endif #if HAVE_SYS_TYPES_H @@ -934,7 +949,8 @@ AC_CHECK_MEMBERS([struct udphdr.uh_dport, struct udphdr.uh_sport], [], [], #endif ]) AC_CHECK_MEMBERS([struct udphdr.dest, struct udphdr.source], [], [], -[#if HAVE_STDINT_H +[#define _BSD_SOURCE +#if HAVE_STDINT_H # include #endif #if HAVE_SYS_TYPES_H @@ -1224,6 +1240,175 @@ AC_DEFINE_UNQUOTED(COLLECT_LIBESMTP, [$collect_libesmtp], AM_CONDITIONAL(BUILD_WITH_LIBESMTP, test "x$with_libesmtp" = "xyes") # }}} +# --with-libganglia {{{ +AC_ARG_WITH(libganglia, [AS_HELP_STRING([--with-libganglia@<:@=PREFIX@:>@], [Path to libganglia.])], +[ + if test -f "$withval" && test -x "$withval" + then + with_libganglia_config="$withval" + with_libganglia="yes" + else if test -f "$withval/bin/ganglia-config" && test -x "$withval/bin/ganglia-config" + then + with_libganglia_config="$withval/bin/ganglia-config" + with_libganglia="yes" + else if test -d "$withval" + then + GANGLIA_CPPFLAGS="-I$withval/include" + GANGLIA_LDFLAGS="-L$withval/lib" + with_libganglia="yes" + else + with_libganglia_config="ganglia-config" + with_libganglia="$withval" + fi; fi; fi +], +[ + with_libganglia_config="ganglia-config" + with_libganglia="yes" +]) + +if test "x$with_libganglia" = "xyes" && test "x$with_libganglia_config" != "x" +then + if test "x$GANGLIA_CPPFLAGS" = "x" + then + GANGLIA_CPPFLAGS=`"$with_libganglia_config" --cflags 2>/dev/null` + fi + + if test "x$GANGLIA_LDFLAGS" = "x" + then + GANGLIA_LDFLAGS=`"$with_libganglia_config" --ldflags 2>/dev/null` + fi + + if test "x$GANGLIA_LIBS" = "x" + then + GANGLIA_LIBS=`"$with_libganglia_config" --libs 2>/dev/null` + fi +fi + +SAVE_CPPFLAGS="$CPPFLAGS" +SAVE_LDFLAGS="$LDFLAGS" +CPPFLAGS="$CPPFLAGS $GANGLIA_CPPFLAGS" +LDFLAGS="$LDFLAGS $GANGLIA_LDFLAGS" + +if test "x$with_libganglia" = "xyes" +then + AC_CHECK_HEADERS(gm_protocol.h, + [ + AC_DEFINE(HAVE_GM_PROTOCOL_H, 1, + [Define to 1 if you have the header file.]) + ], [with_libganglia="no (gm_protocol.h not found)"]) +fi + +if test "x$with_libganglia" = "xyes" +then + AC_CHECK_LIB(ganglia, xdr_Ganglia_value_msg, + [ + AC_DEFINE(HAVE_LIBGANGLIA, 1, + [Define to 1 if you have the ganglia library (-lganglia).]) + ], [with_libganglia="no (symbol xdr_Ganglia_value_msg not found)"]) +fi + +CPPFLAGS="$SAVE_CPPFLAGS" +LDFLAGS="$SAVE_LDFLAGS" + +AC_SUBST(GANGLIA_CPPFLAGS) +AC_SUBST(GANGLIA_LDFLAGS) +AC_SUBST(GANGLIA_LIBS) +AM_CONDITIONAL(BUILD_WITH_LIBGANGLIA, test "x$with_libganglia" = "xyes") +# }}} + +# --with-libgcrypt {{{ +GCRYPT_CPPFLAGS="$GCRYPT_CPPFLAGS" +GCRYPT_LDFLAGS="$GCRYPT_LDFLAGS" +GCRYPT_LIBS="$GCRYPT_LIBS" +AC_ARG_WITH(libgcrypt, [AS_HELP_STRING([--with-libgcrypt@<:@=PREFIX@:>@], [Path to libgcrypt.])], +[ + if test -f "$withval" && test -x "$withval" + then + with_libgcrypt_config="$withval" + with_libgcrypt="yes" + else if test -f "$withval/bin/gcrypt-config" && test -x "$withval/bin/gcrypt-config" + then + with_libgcrypt_config="$withval/bin/gcrypt-config" + with_libgcrypt="yes" + else if test -d "$withval" + then + GCRYPT_CPPFLAGS="$GCRYPT_CPPFLAGS -I$withval/include" + GCRYPT_LDFLAGS="$GCRYPT_LDFLAGS -L$withval/lib" + with_libgcrypt="yes" + else + with_libgcrypt_config="gcrypt-config" + with_libgcrypt="$withval" + fi; fi; fi +], +[ + with_libgcrypt_config="libgcrypt-config" + with_libgcrypt="yes" +]) + +if test "x$with_libgcrypt" = "xyes" && test "x$with_libgcrypt_config" != "x" +then + if test "x$GCRYPT_CPPFLAGS" = "x" + then + GCRYPT_CPPFLAGS=`"$with_libgcrypt_config" --cflags 2>/dev/null` + fi + + if test "x$GCRYPT_LDFLAGS" = "x" + then + gcrypt_exec_prefix=`"$with_libgcrypt_config" --exec-prefix 2>/dev/null` + GCRYPT_LDFLAGS="-L$gcrypt_exec_prefix/lib" + fi + + if test "x$GCRYPT_LIBS" = "x" + then + GCRYPT_LIBS=`"$with_libgcrypt_config" --libs 2>/dev/null` + fi +fi + +SAVE_CPPFLAGS="$CPPFLAGS" +SAVE_LDFLAGS="$LDFLAGS" +CPPFLAGS="$CPPFLAGS $GCRYPT_CPPFLAGS" +LDFLAGS="$LDFLAGS $GCRYPT_LDFLAGS" + +if test "x$with_libgcrypt" = "xyes" +then + if test "x$GCRYPT_CPPFLAGS" != "x" + then + AC_MSG_NOTICE([gcrypt CPPFLAGS: $GCRYPT_CPPFLAGS]) + fi + AC_CHECK_HEADERS(gcrypt.h, + [with_libgcrypt="yes"], + [with_libgcrypt="no (gcrypt.h not found)"]) +fi + +if test "x$with_libgcrypt" = "xyes" +then + if test "x$GCRYPT_LDFLAGS" != "x" + then + AC_MSG_NOTICE([gcrypt LDFLAGS: $GCRYPT_LDFLAGS]) + fi + AC_CHECK_LIB(gcrypt, gcry_md_hash_buffer, + [with_libgcrypt="yes"], + [with_libgcrypt="no (symbol gcry_md_hash_buffer not found)"]) + + if test "$with_libgcrypt" != "no"; then + AM_PATH_LIBGCRYPT(1:1.2.0,,with_libgcrypt="no (version 1.2.0+ required)") + fi +fi + +CPPFLAGS="$SAVE_CPPFLAGS" +LDFLAGS="$SAVE_LDFLAGS" + +if test "x$with_libgcrypt" = "xyes" +then + AC_DEFINE(HAVE_LIBGCRYPT, 1, [Define to 1 if you have the gcrypt library (-lgcrypt).]) +fi + +AC_SUBST(GCRYPT_CPPFLAGS) +AC_SUBST(GCRYPT_LDFLAGS) +AC_SUBST(GCRYPT_LIBS) +AM_CONDITIONAL(BUILD_WITH_LIBGCRYPT, test "x$with_libgcrypt" = "xyes") +# }}} + # --with-libiptc {{{ with_own_libiptc="no" AC_ARG_WITH(libiptc, [AS_HELP_STRING([--with-libiptc@<:@=PREFIX@:>@], [Path to libiptc.])], @@ -1291,6 +1476,163 @@ then fi # }}} +# --with-java {{{ +with_java_home="$JAVA_HOME" +with_java_vmtype="client" +with_java_cflags="" +with_java_libs="" +AC_ARG_WITH(java, [AS_HELP_STRING([--with-java@<:@=PREFIX@:>@], [Path to Java home.])], +[ + if test "x$withval" = "xno" + then + with_java="no" + else if test "x$withval" = "xyes" + then + with_java="yes" + else + with_java_home="$withval" + with_java="yes" + fi; fi +], +[with_java="yes"]) +if test "x$with_java" = "xyes" +then + if test -d "$with_java_home" + then + AC_MSG_CHECKING([for jni.h]) + TMPDIR=`find -L "$with_java_home" -name jni.h -exec 'dirname' '{}' ';' | head -n 1` + if test "x$TMPDIR" != "x" + then + AC_MSG_RESULT([found in $TMPDIR]) + JAVA_CPPFLAGS="$JAVA_CPPFLAGS -I$TMPDIR" + else + AC_MSG_RESULT([not found]) + fi + + AC_MSG_CHECKING([for jni_md.h]) + TMPDIR=`find -L "$with_java_home" -name jni_md.h -exec 'dirname' '{}' ';' | head -n 1` + if test "x$TMPDIR" != "x" + then + AC_MSG_RESULT([found in $TMPDIR]) + JAVA_CPPFLAGS="$JAVA_CPPFLAGS -I$TMPDIR" + else + AC_MSG_RESULT([not found]) + fi + + AC_MSG_CHECKING([for libjvm.so]) + TMPDIR=`find -L "$with_java_home" -name libjvm.so -exec 'dirname' '{}' ';' | head -n 1` + if test "x$TMPDIR" != "x" + then + AC_MSG_RESULT([found in $TMPDIR]) + JAVA_LDFLAGS="$JAVA_LDFLAGS -L$TMPDIR" + else + AC_MSG_RESULT([not found]) + fi + else if test "x$with_java_home" != "x" + then + AC_MSG_WARN([JAVA_HOME: No such directory: $with_java_home]) + fi; fi +fi + +if test "x$JAVA_CPPFLAGS" != "x" +then + AC_MSG_NOTICE([Building with JAVA_CPPFLAGS set to: $JAVA_CPPFLAGS]) +fi +if test "x$JAVA_CFLAGS" != "x" +then + AC_MSG_NOTICE([Building with JAVA_CFLAGS set to: $JAVA_CFLAGS]) +fi +if test "x$JAVA_LDFLAGS" != "x" +then + AC_MSG_NOTICE([Building with JAVA_LDFLAGS set to: $JAVA_LDFLAGS]) +fi + +SAVE_CPPFLAGS="$CPPFLAGS" +SAVE_CFLAGS="$CFLAGS" +SAVE_LDFLAGS="$LDFLAGS" +CPPFLAGS="$CPPFLAGS $JAVA_CPPFLAGS" +CFLAGS="$CFLAGS $JAVA_CFLAGS" +LDFLAGS="$LDFLAGS $JAVA_LDFLAGS" + +if test "x$with_java" = "xyes" +then + AC_CHECK_HEADERS(jni.h, [], [with_java="no (jni.h not found)"]) +fi +if test "x$with_java" = "xyes" +then + AC_CHECK_LIB(jvm, JNI_CreateJavaVM, + [with_java="yes"], + [with_java="no (libjvm not found)"], + [$JAVA_LIBS]) +fi +if test "x$with_java" = "xyes" +then + JAVA_LIBS="$JAVA_LIBS -ljvm" + AC_MSG_NOTICE([Building with JAVA_LIBS set to: $JAVA_LIBS]) +fi + +CPPFLAGS="$SAVE_CPPFLAGS" +CFLAGS="$SAVE_CFLAGS" +LDFLAGS="$SAVE_LDFLAGS" + +AC_SUBST(JAVA_CPPFLAGS) +AC_SUBST(JAVA_CFLAGS) +AC_SUBST(JAVA_LDFLAGS) +AC_SUBST(JAVA_LIBS) +AM_CONDITIONAL(BUILD_WITH_JAVA, test "x$with_java" = "xyes") +# }}} + +# --with-libmemcached {{{ +with_libmemcached_cppflags="" +with_libmemcached_ldflags="" +AC_ARG_WITH(libmemcached, [AS_HELP_STRING([--with-libmemcached@<:@=PREFIX@:>@], [Path to libmemcached.])], +[ + if test "x$withval" != "xno" && test "x$withval" != "xyes" + then + with_libmemcached_cppflags="-I$withval/include" + with_libmemcached_ldflags="-L$withval/lib" + with_libmemcached="yes" + else + with_libmemcached="$withval" + fi +], +[ + with_libmemcached="yes" +]) +if test "x$with_libmemcached" = "xyes" +then + SAVE_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $with_libmemcached_cppflags" + + AC_CHECK_HEADERS(libmemcached/memcached.h, [with_libmemcached="yes"], [with_libmemcached="no (libmemcached/memcached.h not found)"]) + + CPPFLAGS="$SAVE_CPPFLAGS" +fi +if test "x$with_libmemcached" = "xyes" +then + SAVE_CPPFLAGS="$CPPFLAGS" + SAVE_LDFLAGS="$LDFLAGS" + CPPFLAGS="$CPPFLAGS $with_libmemcached_cppflags" + LDFLAGS="$LDFLAGS $with_libmemcached_ldflags" + + AC_CHECK_LIB(memcached, memcached_create, [with_libmemcached="yes"], [with_libmemcached="no (Symbol 'memcached_create' not found)"]) + + CPPFLAGS="$SAVE_CPPFLAGS" + LDFLAGS="$SAVE_LDFLAGS" +fi +if test "x$with_libmemcached" = "xyes" +then + BUILD_WITH_LIBMEMCACHED_CPPFLAGS="$with_libmemcached_cppflags" + BUILD_WITH_LIBMEMCACHED_LDFLAGS="$with_libmemcached_ldflags" + BUILD_WITH_LIBMEMCACHED_LIBS="-lmemcached" + AC_SUBST(BUILD_WITH_LIBMEMCACHED_CPPFLAGS) + AC_SUBST(BUILD_WITH_LIBMEMCACHED_LDFLAGS) + AC_SUBST(BUILD_WITH_LIBMEMCACHED_LIBS) + AC_DEFINE(HAVE_LIBMEMCACHED, 1, [Define if libmemcached is present and usable.]) +fi +AM_CONDITIONAL(BUILD_WITH_LIBMEMCACHED, test "x$with_libmemcached" = "xyes") +# }}} + # --with-libmysql {{{ with_mysql_config="mysql_config" with_mysql_cflags="" @@ -1598,55 +1940,60 @@ fi # }}} # --with-liboping {{{ -with_own_liboping="no" -liboping_LDFLAGS="$LDFLAGS" -liboping_CPPFLAGS="$CPPFLAGS" AC_ARG_WITH(liboping, [AS_HELP_STRING([--with-liboping@<:@=PREFIX@:>@], [Path to liboping.])], [ - if test "x$withval" != "xno" && test "x$withval" != "xyes" + if test "x$withval" = "xyes" + then + with_liboping="yes" + else if test "x$withval" = "xno" + then + with_liboping="no" + else + with_liboping="yes" + LIBOPING_CPPFLAGS="$LIBOPING_CPPFLAGS -I$withval/include" + LIBOPING_LDFLAGS="$LIBOPING_LDFLAGS -L$withval/lib" + fi; fi +], +[with_liboping="yes"]) + +SAVE_CPPFLAGS="$CPPFLAGS" +SAVE_LDFLAGS="$LDFLAGS" + +CPPFLAGS="$CPPFLAGS $LIBOPING_CPPFLAGS" +LDFLAGS="$LDFLAGS $LIBOPING_LDFLAGS" + +if test "x$with_liboping" = "xyes" +then + if test "x$LIBOPING_CPPFLAGS" != "x" then - if test -d "$withval/lib" - then - liboping_LDFLAGS="$LDFLAGS -L$withval/lib" - fi - if test -d "$withval/include" - then - liboping_CPPFLAGS="$CPPFLAGS -I$withval/include" - fi + AC_MSG_NOTICE([liboping CPPFLAGS: $LIBOPING_CPPFLAGS]) fi - if test "x$withval" = "xno" - then - with_liboping="no" - with_own_liboping="no" - else if test "x$withval" = "xyes" + AC_CHECK_HEADERS(oping.h, + [with_liboping="yes"], + [with_liboping="no ('oping.h' not found)"]) +fi +if test "x$with_liboping" = "xyes" +then + if test "x$LIBOPING_LDFLAGS" != "x" then - with_liboping="yes" - fi; fi -], -[ - with_liboping="yes" -]) + AC_MSG_NOTICE([liboping LDFLAGS: $LIBOPING_LDFLAGS]) + fi + AC_CHECK_LIB(oping, ping_construct, + [with_liboping="yes"], + [with_liboping="no (symbol 'ping_construct' not found)"]) +fi + +CPPFLAGS="$SAVE_CPPFLAGS" +LDFLAGS="$SAVE_LDFLAGS" if test "x$with_liboping" = "xyes" then - save_LDFLAGS="$LDFLAGS" - save_CPPFLAGS="$CPPFLAGS" - LDFLAGS="$liboping_LDFLAGS" - CPPFLAGS="$liboping_CPPFLAGS" - AC_CHECK_LIB(oping, ping_construct, - [ - with_liboping="yes" - with_own_liboping="no" - ], - [ - with_liboping="yes" - with_own_liboping="yes" - LDFLAGS="$save_LDFLAGS" - CPPFLAGS="$save_CPPFLAGS" - ]) + BUILD_WITH_LIBOPING_CPPFLAGS="$LIBOPING_CPPFLAGS" + BUILD_WITH_LIBOPING_LDFLAGS="$LIBOPING_LDFLAGS" + AC_SUBST(BUILD_WITH_LIBOPING_CPPFLAGS) + AC_SUBST(BUILD_WITH_LIBOPING_LDFLAGS) fi AM_CONDITIONAL(BUILD_WITH_LIBOPING, test "x$with_liboping" = "xyes") -AM_CONDITIONAL(BUILD_WITH_OWN_LIBOPING, test "x$with_own_liboping" = "xyes") # }}} # --with-oracle {{{ @@ -1923,7 +2270,6 @@ then LDFLAGS=$SAVE_LDFLAGS fi -c_cv_have_broken_perl_load_module="no" if test "x$with_libperl" = "xyes" then SAVE_CFLAGS=$CFLAGS @@ -2064,6 +2410,10 @@ then [with_libpq="yes"], [with_libpq="no (symbol 'PQconnectdb' not found)"]) + AC_CHECK_LIB(pq, PQserverVersion, + [with_libpq="yes"], + [with_libpq="no (symbol 'PQserverVersion' not found)"]) + LDFLAGS="$SAVE_LDFLAGS" fi if test "x$with_libpq" = "xyes" @@ -2884,6 +3234,7 @@ dependency_error="no" plugin_ascent="no" plugin_battery="no" plugin_bind="no" +plugin_conntrack="no" plugin_cpu="no" plugin_cpufreq="no" plugin_df="no" @@ -2898,14 +3249,18 @@ plugin_load="no" plugin_memory="no" plugin_multimeter="no" plugin_nfs="no" +plugin_fscache="no" plugin_perl="no" plugin_processes="no" +plugin_protocols="no" plugin_serial="no" plugin_swap="no" plugin_tape="no" plugin_tcpconns="no" +plugin_ted="no" plugin_thermal="no" plugin_users="no" +plugin_uptime="no" plugin_vmem="no" plugin_vserver="no" plugin_wireless="no" @@ -2914,6 +3269,7 @@ plugin_wireless="no" if test "x$ac_system" = "xLinux" then plugin_battery="yes" + plugin_conntrack="yes" plugin_cpu="yes" plugin_cpufreq="yes" plugin_disk="yes" @@ -2923,11 +3279,14 @@ then plugin_load="yes" plugin_memory="yes" plugin_nfs="yes" + plugin_fscache="yes" plugin_processes="yes" + plugin_protocols="yes" plugin_serial="yes" plugin_swap="yes" plugin_tcpconns="yes" plugin_thermal="yes" + plugin_uptime="yes" plugin_vmem="yes" plugin_vserver="yes" plugin_wireless="yes" @@ -2951,6 +3310,11 @@ then fi # Solaris +if test "x$with_kstat" = "xyes" +then + plugin_uptime="yes" +fi + if test "x$with_devinfo$with_kstat" = "xyesyes" then plugin_cpu="yes" @@ -2995,7 +3359,9 @@ fi if test "x$have_sysctl" = "xyes" then plugin_cpu="yes" + plugin_memory="yes" plugin_swap="yes" + plugin_uptime="yes" fi if test "x$have_sysctlbyname" = "xyes" then @@ -3068,6 +3434,7 @@ fi if test "x$have_termios_h" = "xyes" then plugin_multimeter="yes" + plugin_ted="yes" fi if test "x$have_thread_info" = "xyes" @@ -3113,6 +3480,7 @@ AC_PLUGIN([apple_sensors], [$with_libiokit], [Apple's hardware sensors]) AC_PLUGIN([ascent], [$plugin_ascent], [AscentEmu player statistics]) AC_PLUGIN([battery], [$plugin_battery], [Battery statistics]) AC_PLUGIN([bind], [$plugin_bind], [ISC Bind nameserver statistics]) +AC_PLUGIN([conntrack], [$plugin_conntrack], [nf_conntrack statistics]) AC_PLUGIN([cpufreq], [$plugin_cpufreq], [CPU frequency statistics]) AC_PLUGIN([cpu], [$plugin_cpu], [CPU usage statistics]) AC_PLUGIN([csv], [yes], [CSV output plugin]) @@ -3125,12 +3493,14 @@ AC_PLUGIN([email], [yes], [EMail statistics]) AC_PLUGIN([entropy], [$plugin_entropy], [Entropy statistics]) AC_PLUGIN([exec], [yes], [Execution of external programs]) AC_PLUGIN([filecount], [yes], [Count files in directories]) +AC_PLUGIN([gmond], [$with_libganglia], [Ganglia plugin]) AC_PLUGIN([hddtemp], [yes], [Query hddtempd]) AC_PLUGIN([interface], [$plugin_interface], [Interface traffic statistics]) AC_PLUGIN([ipmi], [$plugin_ipmi], [IPMI sensor statistics]) AC_PLUGIN([iptables], [$with_libiptc], [IPTables rule counters]) AC_PLUGIN([ipvs], [$plugin_ipvs], [IPVS connection statistics]) AC_PLUGIN([irq], [$plugin_irq], [IRQ statistics]) +AC_PLUGIN([java], [$with_java], [Embed the Java Virtual Machine]) AC_PLUGIN([libvirt], [$plugin_libvirt], [Virtual machine statistics]) AC_PLUGIN([load], [$plugin_load], [System load]) AC_PLUGIN([logfile], [yes], [File logging plugin]) @@ -3138,6 +3508,7 @@ AC_PLUGIN([match_regex], [yes], [The regex match]) AC_PLUGIN([match_timediff], [yes], [The timediff match]) AC_PLUGIN([match_value], [yes], [The value match]) AC_PLUGIN([mbmon], [yes], [Query mbmond]) +AC_PLUGIN([memcachec], [$with_libmemcached], [memcachec statistics]) AC_PLUGIN([memcached], [yes], [memcached statistics]) AC_PLUGIN([memory], [$plugin_memory], [Memory usage]) AC_PLUGIN([multimeter], [$plugin_multimeter], [Read multimeter values]) @@ -3145,6 +3516,7 @@ AC_PLUGIN([mysql], [$with_libmysql], [MySQL statistics]) AC_PLUGIN([netlink], [$with_libnetlink], [Enhanced Linux network statistics]) AC_PLUGIN([network], [yes], [Network communication plugin]) AC_PLUGIN([nfs], [$plugin_nfs], [NFS statistics]) +AC_PLUGIN([fscache], [$plugin_fscache], [fscache statistics]) AC_PLUGIN([nginx], [$with_libcurl], [nginx statistics]) AC_PLUGIN([notify_desktop], [$with_libnotify], [Desktop notifications]) AC_PLUGIN([notify_email], [$with_libesmtp], [Email notifier]) @@ -3158,6 +3530,7 @@ AC_PLUGIN([ping], [$with_liboping], [Network latency statistics]) AC_PLUGIN([postgresql], [$with_libpq], [PostgreSQL database statistics]) AC_PLUGIN([powerdns], [yes], [PowerDNS statistics]) AC_PLUGIN([processes], [$plugin_processes], [Process statistics]) +AC_PLUGIN([protocols], [$plugin_protocols], [Protocol (IP, TCP, ...) statistics]) AC_PLUGIN([rrdcached], [$librrd_rrdc_update], [RRDTool output plugin]) AC_PLUGIN([rrdtool], [$with_librrd], [RRDTool output plugin]) AC_PLUGIN([sensors], [$with_libsensors], [lm_sensors statistics]) @@ -3165,6 +3538,7 @@ AC_PLUGIN([serial], [$plugin_serial], [serial port traffic]) AC_PLUGIN([snmp], [$with_libnetsnmp], [SNMP querying plugin]) AC_PLUGIN([swap], [$plugin_swap], [Swap usage statistics]) AC_PLUGIN([syslog], [$have_syslog], [Syslog logging plugin]) +AC_PLUGIN([table], [yes], [Parsing of tabular data]) AC_PLUGIN([tail], [yes], [Parsing of logfiles]) AC_PLUGIN([tape], [$plugin_tape], [Tape drive statistics]) AC_PLUGIN([target_notification], [yes], [The notification target]) @@ -3172,8 +3546,10 @@ AC_PLUGIN([target_replace], [yes], [The replace target]) AC_PLUGIN([target_set], [yes], [The set target]) AC_PLUGIN([tcpconns], [$plugin_tcpconns], [TCP connection statistics]) AC_PLUGIN([teamspeak2], [yes], [TeamSpeak2 server statistics]) +AC_PLUGIN([ted], [$plugin_ted], [Read The Energy Detective values]) AC_PLUGIN([thermal], [$plugin_thermal], [Linux ACPI thermal zone statistics]) AC_PLUGIN([unixsock], [yes], [Unixsock communication plugin]) +AC_PLUGIN([uptime], [$plugin_uptime], [Uptime statistics]) AC_PLUGIN([users], [$plugin_users], [User statistics]) AC_PLUGIN([uuid], [yes], [UUID as hostname plugin]) AC_PLUGIN([vmem], [$plugin_vmem], [Virtual memory statistics]) @@ -3181,6 +3557,86 @@ AC_PLUGIN([vserver], [$plugin_vserver], [Linux VServer statistics]) AC_PLUGIN([wireless], [$plugin_wireless], [Wireless statistics]) AC_PLUGIN([xmms], [$with_libxmms], [XMMS statistics]) +dnl Default configuration file +# Load either syslog or logfile +LOAD_PLUGIN_SYSLOG="" +LOAD_PLUGIN_LOGFILE="" + +AC_MSG_CHECKING([which default log plugin to load]) +default_log_plugin="none" +if test "x$enable_syslog" = "xyes" +then + default_log_plugin="syslog" +else + LOAD_PLUGIN_SYSLOG="##" +fi + +if test "x$enable_logfile" = "xyes" +then + if test "x$default_log_plugin" = "xnone" + then + default_log_plugin="logfile" + else + LOAD_PLUGIN_LOGFILE="#" + fi +else + LOAD_PLUGIN_LOGFILE="##" +fi +AC_MSG_RESULT([$default_log_plugin]) + +AC_SUBST(LOAD_PLUGIN_SYSLOG) +AC_SUBST(LOAD_PLUGIN_LOGFILE) + +DEFAULT_LOG_LEVEL="info" +if test "x$enable_debug" = "xyes" +then + DEFAULT_LOG_LEVEL="debug" +fi +AC_SUBST(DEFAULT_LOG_LEVEL) + +# Load only one of rrdtool, network, csv in the default config. +LOAD_PLUGIN_RRDTOOL="" +LOAD_PLUGIN_NETWORK="" +LOAD_PLUGIN_CSV="" + +AC_MSG_CHECKING([which default write plugin to load]) +default_write_plugin="none" +if test "x$enable_rrdtool" = "xyes" +then + default_write_plugin="rrdtool" +else + LOAD_PLUGIN_RRDTOOL="##" +fi + +if test "x$enable_network" = "xyes" +then + if test "x$default_write_plugin" = "xnone" + then + default_write_plugin="network" + else + LOAD_PLUGIN_NETWORK="#" + fi +else + LOAD_PLUGIN_NETWORK="##" +fi + +if test "x$enable_csv" = "xyes" +then + if test "x$default_write_plugin" = "xnone" + then + default_write_plugin="csv" + else + LOAD_PLUGIN_CSV="#" + fi +else + LOAD_PLUGIN_CSV="##" +fi +AC_MSG_RESULT([$default_write_plugin]) + +AC_SUBST(LOAD_PLUGIN_RRDTOOL) +AC_SUBST(LOAD_PLUGIN_NETWORK) +AC_SUBST(LOAD_PLUGIN_CSV) + dnl ip_vs.h if test "x$ac_system" = "xLinux" \ && test "x$have_net_ip_vs_h$have_ip_vs_h" = "xnono" @@ -3235,7 +3691,7 @@ AC_SUBST(LCC_VERSION_STRING) AC_CONFIG_FILES(src/libcollectdclient/lcc_features.h) -AC_OUTPUT(Makefile src/Makefile src/collectd.conf src/libiptc/Makefile src/libcollectdclient/Makefile src/libcollectdclient/libcollectdclient.pc src/liboconfig/Makefile src/liboping/Makefile bindings/Makefile) +AC_OUTPUT(Makefile src/Makefile src/collectd.conf src/libiptc/Makefile src/libcollectdclient/Makefile src/libcollectdclient/libcollectdclient.pc src/liboconfig/Makefile bindings/Makefile) if test "x$with_librrd" = "xyes" \ && test "x$librrd_threadsafe" != "xyes" @@ -3243,12 +3699,6 @@ then with_librrd="yes (warning: librrd is not thread-safe)" fi -if test "x$with_liboping" = "xyes" \ - && test "x$with_own_liboping" = "xyes" -then - with_liboping="yes (shipped version)" -fi - if test "x$with_libiptc" = "xyes" -a "x$with_own_libiptc" = "xyes" then with_libiptc="yes (shipped version)" @@ -3274,8 +3724,10 @@ Configuration: libcurl . . . . . . . $with_libcurl libdbi . . . . . . . $with_libdbi libesmtp . . . . . . $with_libesmtp + libgcrypt . . . . . . $with_libgcrypt libiokit . . . . . . $with_libiokit libiptc . . . . . . . $with_libiptc + libjvm . . . . . . . $with_java libkstat . . . . . . $with_kstat libkvm . . . . . . . $with_libkvm libmysql . . . . . . $with_libmysql @@ -3312,6 +3764,7 @@ Configuration: ascent . . . . . . . $enable_ascent battery . . . . . . . $enable_battery bind . . . . . . . . $enable_bind + conntrack . . . . . . $enable_conntrack cpu . . . . . . . . . $enable_cpu cpufreq . . . . . . . $enable_cpufreq csv . . . . . . . . . $enable_csv @@ -3324,12 +3777,14 @@ Configuration: entropy . . . . . . . $enable_entropy exec . . . . . . . . $enable_exec filecount . . . . . . $enable_filecount + gmond . . . . . . . . $enable_gmond hddtemp . . . . . . . $enable_hddtemp interface . . . . . . $enable_interface ipmi . . . . . . . . $enable_ipmi iptables . . . . . . $enable_iptables ipvs . . . . . . . . $enable_ipvs irq . . . . . . . . . $enable_irq + java . . . . . . . . $enable_java libvirt . . . . . . . $enable_libvirt load . . . . . . . . $enable_load logfile . . . . . . . $enable_logfile @@ -3337,6 +3792,7 @@ Configuration: match_timediff . . . $enable_match_timediff match_value . . . . . $enable_match_value mbmon . . . . . . . . $enable_mbmon + memcachec . . . . . . $enable_memcachec memcached . . . . . . $enable_memcached memory . . . . . . . $enable_memory multimeter . . . . . $enable_multimeter @@ -3344,6 +3800,7 @@ Configuration: netlink . . . . . . . $enable_netlink network . . . . . . . $enable_network nfs . . . . . . . . . $enable_nfs + fscache . . . . . . . $enable_fscache nginx . . . . . . . . $enable_nginx notify_desktop . . . $enable_notify_desktop notify_email . . . . $enable_notify_email @@ -3357,6 +3814,7 @@ Configuration: postgresql . . . . . $enable_postgresql powerdns . . . . . . $enable_powerdns processes . . . . . . $enable_processes + protocols . . . . . . $enable_protocols rrdcached . . . . . . $enable_rrdcached rrdtool . . . . . . . $enable_rrdtool sensors . . . . . . . $enable_sensors @@ -3364,6 +3822,7 @@ Configuration: snmp . . . . . . . . $enable_snmp swap . . . . . . . . $enable_swap syslog . . . . . . . $enable_syslog + table . . . . . . . . $enable_table tail . . . . . . . . $enable_tail tape . . . . . . . . $enable_tape target_notification . $enable_target_notification @@ -3371,8 +3830,10 @@ Configuration: target_set . . . . . $enable_target_set tcpconns . . . . . . $enable_tcpconns teamspeak2 . . . . . $enable_teamspeak2 + ted . . . . . . . . . $enable_ted thermal . . . . . . . $enable_thermal unixsock . . . . . . $enable_unixsock + uptime . . . . . . . $enable_uptime users . . . . . . . . $enable_users uuid . . . . . . . . $enable_uuid vmem . . . . . . . . $enable_vmem diff --git a/contrib/collectd-unixsock.py b/contrib/collectd-unixsock.py new file mode 100644 index 00000000..2d7430d2 --- /dev/null +++ b/contrib/collectd-unixsock.py @@ -0,0 +1,111 @@ +#-*- coding: ISO-8859-1 -*- +# collect.py: the python collectd-unixsock module. +# +# Requires collectd to be configured with the unixsock plugin, like so: +# +# LoadPlugin unixsock +# +# SocketFile "/var/run/collectd-unixsock" +# SocketPerms "0775" +# +# +# Copyright (C) 2008 Clay Loveless +# +# This software is provided 'as-is', without any express or implied +# warranty. In no event will the author be held liable for any damages +# arising from the use of this software. +# +# Permission is granted to anyone to use this software for any purpose, +# including commercial applications, and to alter it and redistribute it +# freely, subject to the following restrictions: +# +# 1. The origin of this software must not be misrepresented; you must not +# claim that you wrote the original software. If you use this software +# in a product, an acknowledgment in the product documentation would be +# appreciated but is not required. +# 2. Altered source versions must be plainly marked as such, and must not be +# misrepresented as being the original software. +# 3. This notice may not be removed or altered from any source distribution. + +import socket, string + +class Collect(object): + + def __init__(self, path='/var/run/collectd-unixsock'): + self._sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + self._path = path + self._sock.connect(self._path) + + def list(self): + numvalues = self._cmd('LISTVAL') + lines = [] + if numvalues: + lines = self._readlines(numvalues) + return lines + + def get(self, val, flush=True): + numvalues = self._cmd('GETVAL "' + val + '"') + lines = [] + if numvalues: + lines = self._readlines(numvalues) + if flush: + self._cmd('FLUSH identifier="' + val + '"') + return lines + + def _cmd(self, c): + self._sock.send(c + "\n") + stat = string.split(self._readline()) + status = int(stat[0]) + if status: + return status + return False + + ''' + _readline and _readlines methods borrowed from the _fileobject class + in sockets.py, tweaked a little bit for use in the collectd context. + ''' + def _readline(self): + data = '' + buf = [] + recv = self._sock.recv + while data != "\n": + data = recv(1) + if not data: + break + if data != "\n": + buf.append(data) + return ''.join(buf) + + def _readlines(self, sizehint=0): + total = 0 + list = [] + while True: + line = self._readline() + if not line: + break + list.append(line) + total = len(list) + if sizehint and total >= sizehint: + break + return list + + def __del__(self): + self._sock.close() + + + +if __name__ == '__main__': + + ''' + Example usage: + Collect values from socket and dump to STDOUT. + ''' + + c = Collect('/var/run/collectd-unixsock') + list = c.list() + + for val in list: + stamp, key = string.split(val) + glines = c.get(key) + print stamp + ' ' + key + ' ' + ', '.join(glines) + diff --git a/contrib/collection.cgi b/contrib/collection.cgi index d3a284f8..eeda241d 100755 --- a/contrib/collection.cgi +++ b/contrib/collection.cgi @@ -1301,6 +1301,18 @@ sub load_graph_definitions 'GPRINT:max:MAX:%4.1lf Max,', 'GPRINT:avg:LAST:%4.1lf Last\l' ], + conntrack => ['-v', 'Entries', + 'DEF:avg={file}:entropy:AVERAGE', + 'DEF:min={file}:entropy:MIN', + 'DEF:max={file}:entropy:MAX', + "AREA:max#$HalfBlue", + "AREA:min#$Canvas", + "LINE1:avg#$FullBlue:Count", + 'GPRINT:min:MIN:%4.0lf Min,', + 'GPRINT:avg:AVERAGE:%4.0lf Avg,', + 'GPRINT:max:MAX:%4.0lf Max,', + 'GPRINT:avg:LAST:%4.0lf Last\l' + ], entropy => ['-v', 'Bits', 'DEF:avg={file}:entropy:AVERAGE', 'DEF:min={file}:entropy:MIN', diff --git a/contrib/collection3/etc/collection.conf b/contrib/collection3/etc/collection.conf index 9497d8e3..492bfa27 100644 --- a/contrib/collection3/etc/collection.conf +++ b/contrib/collection3/etc/collection.conf @@ -131,6 +131,13 @@ GraphWidth 400 RRDVerticalLabel "Queries/s" RRDFormat "%6.1lf" + + DataSources conntrack + DSName conntrack Conntrack count + RRDTitle "nf_conntrack connections on {hostname}" + RRDVerticalLabel "Count" + RRDFormat "%4.0lf" + DataSources entropy DSName entropy Entropy bits @@ -277,7 +284,7 @@ GraphWidth 400 Module GenericStacked DataSources value - RRDTitle "MySQL commands" + RRDTitle "MySQL commands ({plugin_instance})" RRDVerticalLabel "Invocations" RRDFormat "%6.2lf" @@ -361,7 +368,7 @@ GraphWidth 400 Module GenericStacked DataSources value - RRDTitle "MySQL handler" + RRDTitle "MySQL handler ({plugin_instance})" RRDVerticalLabel "Invocations" RRDFormat "%6.2lf" DSName commit commit @@ -391,7 +398,7 @@ GraphWidth 400 DataSources rx tx DSName rx RX DSName tx TX - RRDTitle "MySQL Traffic" + RRDTitle "MySQL Traffic ({plugin_instance})" RRDVerticalLabel "Bits per second" RRDFormat "%5.1lf%s" Scale 8 diff --git a/contrib/fedora/collectd.spec b/contrib/fedora/collectd.spec index 35eb8bec..a35923c0 100644 --- a/contrib/fedora/collectd.spec +++ b/contrib/fedora/collectd.spec @@ -119,6 +119,9 @@ exit 0 %attr(0644,root,root) %{_libdir}/%{name}/battery.so* %attr(0644,root,root) %{_libdir}/%{name}/battery.la +%attr(0644,root,root) %{_libdir}/%{name}/conntrack.so* +%attr(0644,root,root) %{_libdir}/%{name}/conntrack.la + %attr(0644,root,root) %{_libdir}/%{name}/cpufreq.so* %attr(0644,root,root) %{_libdir}/%{name}/cpufreq.la diff --git a/contrib/php-collection/browser.js b/contrib/php-collection/browser.js index a343cba8..4ddc424d 100644 --- a/contrib/php-collection/browser.js +++ b/contrib/php-collection/browser.js @@ -35,6 +35,7 @@ function toggleDiv(divID) { label.removeChild(label.childNodes[--childCnt]); label.appendChild(document.createTextNode(label_txt)); } + GraphPositionToolbox(null); } var req = null; @@ -110,9 +111,22 @@ function refillSelect(options, select) { newOption.value = options[i].firstChild ? options[i].firstChild.data : ''; if (keepSelection && newOption.value == oldValue) newOption.setAttribute('selected', 'selected'); - if (keepSelection && optCnt == 1 && newOption.value == '@') { + if (newOption.value[0] == '@') { newOption.setAttribute('style', 'font-style: italic'); - newOption.appendChild(document.createTextNode('Meta graph')); + if (newOption.value == '@' || newOption.value == '@merge') + newOption.appendChild(document.createTextNode('Meta graph')); + else if (newOption.value == '@all') + newOption.appendChild(document.createTextNode('All entries')); + else if (newOption.value == '@merge_sum') + newOption.appendChild(document.createTextNode('Meta summed graph')); + else if (newOption.value == '@merge_avg') + newOption.appendChild(document.createTextNode('Meta averaged graph')); + else if (newOption.value == '@merge_stack') + newOption.appendChild(document.createTextNode('Meta stacked graph')); + else if (newOption.value == '@merge_line') + newOption.appendChild(document.createTextNode('Meta lines graph')); + else + newOption.appendChild(document.createTextNode(newOption.value)); } else newOption.appendChild(document.createTextNode(newOption.value)); select.appendChild(newOption); @@ -284,8 +298,25 @@ function GraphAppend() { var time_list = document.getElementById('timespan'); var timespan = time_list.selectedIndex >= 0 ? time_list.options[time_list.selectedIndex].value : ''; var tinyLegend = document.getElementById('tinylegend').checked; - var logarithmic = document.getElementById('logarithmic').checked - GraphDoAppend(host, plugin, pinst, type, tinst, timespan, tinyLegend, logarithmic); + var logarithmic = document.getElementById('logarithmic').checked; + if (host[0] == '@' || plugin[0] == '@' || pinst[0] == '@' || type[0] == '@' || (tinst[0] == '@' && tinst.substr(0, 5) != '@merge')) { + var query = 'action=list_graphs&host='+encodeURIComponent(host)+'&plugin='+encodeURIComponent(plugin)+'&plugin_instance='+encodeURIComponent(pinst); + query = query+'&type='+encodeURIComponent(type)+'&type_instance='+encodeURIComponent(tinst)+'×pan='+encodeURIComponent(timespan); + query = query+(logarithmic ? '&logarithmic=1' : '')+(tinyLegend ? '&tinylegend=1' : ''); + loadXMLDoc(dhtml_url, query); + } else + GraphDoAppend(host, plugin, pinst, type, tinst, timespan, tinyLegend, logarithmic); +} + +function ListOfGraph(response) { + var graphs = response ? response.getElementsByTagName('graph') : null; + if (graphs && graphs.length > 0) { + for (i = 0; i < graphs.length; i++) + GraphDoAppend(graphs[i].getAttribute('host'), graphs[i].getAttribute('plugin'), graphs[i].getAttribute('plugin_instance'), + graphs[i].getAttribute('type'), graphs[i].getAttribute('type_instance'), graphs[i].getAttribute('timespan'), + graphs[i].getAttribute('tinyLegend') == '1', graphs[i].getAttribute('logarithmic') == '1'); + } else + alert('No graph found for adding'); } function GraphDoAppend(host, plugin, pinst, type, tinst, timespan, tinyLegend, logarithmic) { @@ -319,58 +350,12 @@ function GraphDoAppend(host, plugin, pinst, type, tinst, timespan, tinyLegend, l newGraph.setAttribute('class', 'graph'); newGraph.setAttribute('id', graph_id); // Graph cell + graph - newDiv = document.createElement('div'); - newDiv.setAttribute('class', 'graph_img'); newImg = document.createElement('img'); newImg.setAttribute('src', graph_src); newImg.setAttribute('alt', graph_alt); newImg.setAttribute('title', graph_title); - newDiv.appendChild(newImg); - newGraph.appendChild(newDiv); - // Graph tools - newDiv = document.createElement('div'); - newDiv.setAttribute('class', 'graph_opts'); - // - move up - newImg = document.createElement('img'); - newImg.setAttribute('src', 'move-up.png'); - newImg.setAttribute('alt', 'UP'); - newImg.setAttribute('title', 'Move graph up'); - newA = document.createElement('a'); - newA.setAttribute('href', 'javascript:GraphMoveUp("'+graph_id+'")'); - newA.appendChild(newImg); - newDiv.appendChild(newA); - newDiv.appendChild(document.createElement('br')); - // - refresh - newImg = document.createElement('img'); - newImg.setAttribute('src', 'refresh.png'); - newImg.setAttribute('alt', 'R'); - newImg.setAttribute('title', 'Refresh graph'); - newA = document.createElement('a'); - newA.setAttribute('href', 'javascript:GraphRefresh("'+graph_id+'")'); - newA.appendChild(newImg); - newDiv.appendChild(newA); - newDiv.appendChild(document.createElement('br')); - // - remove - newImg = document.createElement('img'); - newImg.setAttribute('src', 'delete.png'); - newImg.setAttribute('alt', 'RM'); - newImg.setAttribute('title', 'Remove graph'); - newA = document.createElement('a'); - newA.setAttribute('href', 'javascript:GraphRemove("'+graph_id+'")'); - newA.appendChild(newImg); - newDiv.appendChild(newA); - newDiv.appendChild(document.createElement('br')); - // - move down - newImg = document.createElement('img'); - newImg.setAttribute('src', 'move-down.png'); - newImg.setAttribute('alt', 'DN'); - newImg.setAttribute('title', 'Move graph down'); - newA = document.createElement('a'); - newA.setAttribute('href', 'javascript:GraphMoveDown("'+graph_id+'")'); - newA.appendChild(newImg); - newDiv.appendChild(newA); - newGraph.appendChild(newDiv); - + newImg.setAttribute('onclick', 'GraphToggleTools("'+graph_id+'")'); + newGraph.appendChild(newImg); graphs.appendChild(newGraph); } document.getElementById('nograph').style.display = 'none'; @@ -389,32 +374,159 @@ function GraphDropAll() { RefreshButtons(); } +function GraphToggleTools(graph) { + var graphId = document.getElementById('ge_graphid').value; + var ref_img = null; + if (graphId == graph || graph == '') { + ref_img = null; + } else { + var graphDiv = document.getElementById(graph); + var imgs = graphDiv ? graphDiv.getElementsByTagName('img') : null; + var imgCnt = imgs ? imgs.length : 0; + while (imgCnt > 0) + if (imgs[--imgCnt].parentNode.getAttribute('class') == 'graph') + ref_img = imgs[imgCnt]; + } + if (ref_img) { + var ts_sel = document.getElementById('ge_timespan'); + var src_url = ref_img.src; + var ge = document.getElementById('ge'); + // Fix field values + var ts = src_url.match(/×pan=[^&]*/); + ts = ts ? ts[0].substr(10) : ''; + document.getElementById('ge_graphid').value = graph; + document.getElementById('ge_tinylegend').checked = src_url.match(/&tinylegend=1/); + document.getElementById('ge_logarithmic').checked = src_url.match(/&logarithmic=1/); + for (i = 0; i < ts_sel.options.length; i++) + if (ts_sel.options[i].value == ts) { + ts_sel.selectedIndex = i; + break; + } + // show tools box and position it properly + ge.style.display = 'table'; + GraphPositionToolbox(ref_img); + } else { + // hide tools box + document.getElementById('ge').style.display = 'none'; + document.getElementById('ge_graphid').value = ''; + } +} + +function GraphPositionToolbox(ref_img) { + var ge = document.getElementById('ge'); + if (ge.style.display != 'none') { + var wl = 0; var wt = 0; + var x = ref_img; + if (ref_img == null) { + var graphDiv = document.getElementById(document.getElementById('ge_graphid').value); + var imgs = graphDiv ? graphDiv.getElementsByTagName('img') : null; + var imgCnt = imgs ? imgs.length : 0; + while (imgCnt > 0) + if (imgs[--imgCnt].parentNode.getAttribute('class') == 'graph') + ref_img = imgs[imgCnt]; + + if (ref_img == null) { + document.getElementById('ge_graphid').value = ''; + ge.style.display = 'none'; + return; + } else + x = ref_img; + } + while (x != null) { + wl += x.offsetLeft; + wt += x.offsetTop; + x = x.offsetParent; + } + ge.style.left = (wl + (ref_img.offsetWidth - ge.offsetWidth) / 2)+'px'; + ge.style.top = (wt + (ref_img.offsetHeight - ge.offsetHeight) / 2)+'px'; + } +} + +function GraphRefreshAll() { + var imgs = document.getElementById('graphs').getElementsByTagName('img'); + var imgCnt = imgs.length; + var now = new Date(); + var newTS = '&ts='+now.getTime(); + while (imgCnt > 0) + if (imgs[--imgCnt].parentNode.getAttribute('class') == 'graph') { + var oldSrc = imgs[imgCnt].src; + var newSrc = oldSrc.replace(/&ts=[0-9]+/, newTS); + if (newSrc == oldSrc) + newSrc = newSrc + newTS; + imgs[imgCnt].setAttribute('src', newSrc); + } +} + function GraphRefresh(graph) { + var graphElement = null; if (graph == null) { - var imgs = document.getElementById('graphs').getElementsByTagName('img'); + var graphId = document.getElementById('ge_graphid').value; + if (graphId != '') + graphElement = document.getElementById(graphId); + } else + graphElement = document.getElementById(graph); + if (graphElement != null) { + var imgs = graphElement.getElementsByTagName('img'); var imgCnt = imgs.length; - var now = new Date(); - var newTS = '&ts='+now.getTime(); while (imgCnt > 0) - if (imgs[--imgCnt].parentNode.getAttribute('class') == 'graph_img') { + if (imgs[--imgCnt].parentNode.getAttribute('class') == 'graph') { + var now = new Date(); + var newTS = '&ts='+now.getTime(); var oldSrc = imgs[imgCnt].src; var newSrc = oldSrc.replace(/&ts=[0-9]+/, newTS); if (newSrc == oldSrc) - newSrc = newSrc + newTS; + newSrc = newSrc+newTS; imgs[imgCnt].setAttribute('src', newSrc); + break; } - } else if (document.getElementById(graph)) { - var imgs = document.getElementById(graph).getElementsByTagName('img'); + } +} + +function GraphAdjust(graph) { + var graphId = graph == null ? document.getElementById('ge_graphid').value : graph; + var graphElement = document.getElementById(graphId); + if (graphElement != null) { + var time_list = document.getElementById('ge_timespan'); + var timespan = time_list.selectedIndex >= 0 ? time_list.options[time_list.selectedIndex].value : ''; + var tinyLegend = document.getElementById('ge_tinylegend').checked; + var logarithmic = document.getElementById('ge_logarithmic').checked + var imgs = graphElement.getElementsByTagName('img'); var imgCnt = imgs.length; + var ref_img = null; while (imgCnt > 0) - if (imgs[--imgCnt].parentNode.getAttribute('class') == 'graph_img') { + if (imgs[--imgCnt].parentNode.getAttribute('class') == 'graph') { var now = new Date(); var newTS = '&ts='+now.getTime(); var oldSrc = imgs[imgCnt].src; - var newSrc = oldSrc.replace(/&ts=[0-9]+/, newTS); + var newSrc = oldSrc.replace(/&ts=[^&]*/, newTS); if (newSrc == oldSrc) newSrc = newSrc+newTS; + newSrc = newSrc.replace(/&logarithmic=[^&]*/, ''); + if (logarithmic) + newSrc += '&logarithmic=1'; + newSrc = newSrc.replace(/&tinylegend=[^&]*/, ''); + if (tinyLegend) + newSrc += '&tinylegend=1'; + newSrc = newSrc.replace(/×pan=[^&]*/, ''); + if (timespan) + newSrc += '×pan='+encodeURIComponent(timespan); imgs[imgCnt].setAttribute('src', newSrc); + + var myList = Array(); + for (i = 0; i < graphList.length; i++) + if (graphList[i].substring(0, graphId.length) == graphId && graphList[i].charAt(graphId.length) == ' ') { + newSrc = graphList[i]; + newSrc = newSrc.replace(/&logarithmic=[^&]*/, ''); + newSrc = newSrc.replace(/&tinylegend=[^&]*/, ''); + newSrc = newSrc.replace(/×pan=[^&]*/, ''); + newSrc = newSrc+(logarithmic ? '&logarithmic=1' : '')+(tinyLegend ? '&tinylegend=1' : '')+'×pan='+encodeURIComponent(timespan); + myList.push(newSrc); + continue; + } else + myList.push(graphList[i]); + graphList = myList; + window.setTimeout("GraphPositionToolbox(null)", 10); + // GraphPositionToolbox(imgs[imgCnt]); break; } } @@ -422,15 +534,18 @@ function GraphRefresh(graph) { function GraphRemove(graph) { var graphs = document.getElementById('graphs'); - if (document.getElementById(graph)) { - graphs.removeChild(document.getElementById(graph)); + var graphId = graph == null ? document.getElementById('ge_graphid').value : graph; + var graphElement = document.getElementById(graphId); + if (graphElement) { + GraphToggleTools(''); + graphs.removeChild(graphElement); RefreshButtons(); if (graphs.getElementsByTagName('div').length == 1) document.getElementById('nograph').style.display = 'block'; var myList = Array(); for (i = 0; i < graphList.length; i++) - if (graphList[i].substring(0, graph.length) == graph && graphList[i].charAt(graph.length) == ' ') + if (graphList[i].substring(0, graphId.length) == graphId && graphList[i].charAt(graphId.length) == ' ') continue; else myList.push(graphList[i]); @@ -440,13 +555,14 @@ function GraphRemove(graph) { function GraphMoveUp(graph) { var graphs = document.getElementById('graphs'); + var graphId = graph == null ? document.getElementById('ge_graphid').value : graph; var childCnt = graphs.childNodes.length; var prevGraph = null; for (i = 0; i < childCnt; i++) if (graphs.childNodes[i].nodeName == 'div' || graphs.childNodes[i].nodeName == 'DIV') { if (graphs.childNodes[i].id == 'nograph') { // Skip - } else if (graphs.childNodes[i].id == graph) { + } else if (graphs.childNodes[i].id == graphId) { var myGraph = graphs.childNodes[i]; if (prevGraph) { graphs.removeChild(myGraph); @@ -457,7 +573,7 @@ function GraphMoveUp(graph) { prevGraph = graphs.childNodes[i]; } for (i = 0; i < graphList.length; i++) - if (graphList[i].substring(0, graph.length) == graph && graphList[i].charAt(graph.length) == ' ') { + if (graphList[i].substring(0, graphId.length) == graphId && graphList[i].charAt(graphId.length) == ' ') { if (i > 0) { var tmp = graphList[i-1]; graphList[i-1] = graphList[i]; @@ -465,10 +581,12 @@ function GraphMoveUp(graph) { } break; } + GraphPositionToolbox(null); } function GraphMoveDown(graph) { var graphs = document.getElementById('graphs'); + var graphId = graph == null ? document.getElementById('ge_graphid').value : graph; var childCnt = graphs.childNodes.length; var nextGraph = null; var myGraph = null; @@ -476,7 +594,7 @@ function GraphMoveDown(graph) { if (graphs.childNodes[i].nodeName == 'div' || graphs.childNodes[i].nodeName == 'DIV') { if (graphs.childNodes[i].id == 'nograph') { // Skip - } else if (graphs.childNodes[i].id == graph) { + } else if (graphs.childNodes[i].id == graphId) { myGraph = graphs.childNodes[i]; } else if (myGraph) { nextGraph = graphs.childNodes[i]; @@ -486,7 +604,7 @@ function GraphMoveDown(graph) { } } for (i = 0; i < graphList.length; i++) - if (graphList[i].substring(0, graph.length) == graph && graphList[i].charAt(graph.length) == ' ') { + if (graphList[i].substring(0, graphId.length) == graphId && graphList[i].charAt(graphId.length) == ' ') { if (i+1 < graphList.length) { var tmp = graphList[i+1]; graphList[i+1] = graphList[i]; @@ -494,6 +612,7 @@ function GraphMoveDown(graph) { } break; } + GraphPositionToolbox(null); } function GraphListFromCookie(lname) { diff --git a/contrib/php-collection/definitions.php b/contrib/php-collection/definitions.php index cb3e803e..c84aabea 100644 --- a/contrib/php-collection/definitions.php +++ b/contrib/php-collection/definitions.php @@ -386,6 +386,18 @@ function load_graph_definitions($logarithmic = false, $tinylegend = false) { 'GPRINT:avg:AVERAGE:%4.1lf Avg,', 'GPRINT:max:MAX:%4.1lf Max,', 'GPRINT:avg:LAST:%4.1lf Last\l'); + $GraphDefs['conntrack'] = array( + '-v', 'Entries', + 'DEF:avg={file}:entropy:AVERAGE', + 'DEF:min={file}:entropy:MIN', + 'DEF:max={file}:entropy:MAX', + "AREA:max#$HalfBlue", + "AREA:min#$Canvas", + "LINE1:avg#$FullBlue:Count", + 'GPRINT:min:MIN:%4.0lf Min,', + 'GPRINT:avg:AVERAGE:%4.0lf Avg,', + 'GPRINT:max:MAX:%4.0lf Max,', + 'GPRINT:avg:LAST:%4.0lf Last\l'); $GraphDefs['entropy'] = array( '-v', 'Bits', 'DEF:avg={file}:entropy:AVERAGE', @@ -1578,6 +1590,7 @@ function load_graph_definitions($logarithmic = false, $tinylegend = false) { $MetaGraphDefs['tcp_connections'] = 'meta_graph_tcp_connections'; $MetaGraphDefs['dns_opcode'] = 'meta_graph_dns_event'; $MetaGraphDefs['dns_qtype'] = 'meta_graph_dns_event'; + $MetaGraphDefs['dns_qtype_cached'] = 'meta_graph_dns_event'; $MetaGraphDefs['dns_rcode'] = 'meta_graph_dns_event'; $MetaGraphDefs['dns_request'] = 'meta_graph_dns_event'; $MetaGraphDefs['dns_resolver'] = 'meta_graph_dns_event'; @@ -1745,7 +1758,10 @@ function meta_graph_memory($host, $plugin, $plugin_instance, $type, $type_instan $sources[] = array('name'=>$inst, 'file'=>$file); } - return collectd_draw_meta_stack($opts, $sources); + if ($plugin == 'bind') + return collectd_draw_meta_line($opts, $sources); + else + return collectd_draw_meta_stack($opts, $sources); } function meta_graph_vs_threads($host, $plugin, $plugin_instance, $type, $type_instances, $opts = array()) { diff --git a/contrib/php-collection/functions.php b/contrib/php-collection/functions.php index f555751a..fa2badce 100644 --- a/contrib/php-collection/functions.php +++ b/contrib/php-collection/functions.php @@ -61,23 +61,173 @@ function collectd_compare_host($a, $b) { return 0; } -/** - * Fetch list of hosts found in collectd's datadirs. - * @return Sorted list of hosts (sorted by label from rigth to left) - */ -function collectd_list_hosts() { +function collectd_walk(&$options) { global $config; - $hosts = array(); foreach($config['datadirs'] as $datadir) - if ($d = @opendir($datadir)) { - while (($dent = readdir($d)) !== false) - if ($dent != '.' && $dent != '..' && is_dir($datadir.'/'.$dent) && preg_match(REGEXP_HOST, $dent)) - $hosts[] = $dent; - closedir($d); + if ($dh = @opendir($datadir)) { + while (($hdent = readdir($dh)) !== false) { + if ($hdent == '.' || $hdent == '..' || !is_dir($datadir.'/'.$hdent)) + continue; + if (!preg_match(REGEXP_HOST, $hdent)) + continue; + if (isset($options['cb_host']) && ($options['cb_host'] === false || !$options['cb_host']($options, $hdent))) + continue; + + if ($dp = @opendir($datadir.'/'.$hdent)) { + while (($pdent = readdir($dp)) !== false) { + if ($pdent == '.' || $pdent == '..' || !is_dir($datadir.'/'.$hdent.'/'.$pdent)) + continue; + if ($i = strpos($pdent, '-')) { + $plugin = substr($pdent, 0, $i); + $pinst = substr($pdent, $i+1); + } else { + $plugin = $pdent; + $pinst = ''; + } + if (isset($options['cb_plugin']) && ($options['cb_plugin'] === false || !$options['cb_plugin']($options, $hdent, $plugin))) + continue; + if (isset($options['cb_pinst']) && ($options['cb_pinst'] === false || !$options['cb_pinst']($options, $hdent, $plugin, $pinst))) + continue; + + if ($dt = @opendir($datadir.'/'.$hdent.'/'.$pdent)) { + while (($tdent = readdir($dt)) !== false) { + if ($tdent == '.' || $tdent == '..' || !is_file($datadir.'/'.$hdent.'/'.$pdent.'/'.$tdent)) + continue; + if (substr($tdent, strlen($tdent)-4) != '.rrd') + continue; + $tdent = substr($tdent, 0, strlen($tdent)-4); + if ($i = strpos($tdent, '-')) { + $type = substr($tdent, 0, $i); + $tinst = substr($tdent, $i+1); + } else { + $type = $tdent; + $tinst = ''; + } + if (isset($options['cb_type']) && ($options['cb_type'] === false || !$options['cb_type']($options, $hdent, $plugin, $pinst, $type))) + continue; + if (isset($options['cb_tinst']) && ($options['cb_tinst'] === false || !$options['cb_tinst']($options, $hdent, $plugin, $pinst, $type, $tinst))) + continue; + } + closedir($dt); + } + } + closedir($dp); + } + } + closedir($dh); } else error_log('Failed to open datadir: '.$datadir); - $hosts = array_unique($hosts); + return true; +} + +function _collectd_list_cb_host(&$options, $host) { + if ($options['cb_plugin'] === false) { + $options['result'][] = $host; + return false; + } else if (isset($options['filter_host'])) { + if ($options['filter_host'] == '@all') { + return true; // We take anything + } else if (substr($options['filter_host'], 0, 2) == '@.') { + if ($host == substr($options['filter_host'], 2) || substr($host, 0, 1-strlen($options['filter_host'])) == substr($options['filter_host'], 1)) + return true; // Host part of domain + else + return false; + } else if ($options['filter_host'] == $host) { + return true; + } else + return false; + } else + return true; +} + +function _collectd_list_cb_plugin(&$options, $host, $plugin) { + if ($options['cb_pinst'] === false) { + $options['result'][] = $plugin; + return false; + } else if (isset($options['filter_plugin'])) { + if ($options['filter_plugin'] == '@all') + return true; + else if ($options['filter_plugin'] == $plugin) + return true; + else + return false; + } else + return true; +} + +function _collectd_list_cb_pinst(&$options, $host, $plugin, $pinst) { + if ($options['cb_type'] === false) { + $options['result'][] = $pinst; + return false; + } else if (isset($options['filter_pinst'])) { + if ($options['filter_pinst'] == '@all') + return true; + else if (strncmp($options['filter_pinst'], '@merge_', 7) == 0) + return true; + else if ($options['filter_pinst'] == $pinst) + return true; + else + return false; + } else + return true; +} + +function _collectd_list_cb_type(&$options, $host, $plugin, $pinst, $type) { + if ($options['cb_tinst'] === false) { + $options['result'][] = $type; + return false; + } else if (isset($options['filter_type'])) { + if ($options['filter_type'] == '@all') + return true; + else if ($options['filter_type'] == $type) + return true; + else + return false; + } else + return true; +} + +function _collectd_list_cb_tinst(&$options, $host, $plugin, $pinst, $type, $tinst) { + $options['result'][] = $tinst; + return false; +} + +function _collectd_list_cb_graph(&$options, $host, $plugin, $pinst, $type, $tinst) { + if (isset($options['filter_tinst'])) { + if ($options['filter_tinst'] == '@all') { + } else if ($options['filter_tinst'] == $tinst) { + } else if (strncmp($options['filter_tinst'], '@merge', 6) == 0) { + // Need to exclude @merge with non-existent meta graph + } else + return false; + } + if (isset($options['filter_pinst']) && strncmp($options['filter_pinst'], '@merge', 6) == 0) + $pinst = $options['filter_pinst']; + if (isset($options['filter_tinst']) && strncmp($options['filter_tinst'], '@merge', 6) == 0) + $tinst = $options['filter_tinst']; + $ident = collectd_identifier($host, $plugin, $pinst, $type, $tinst); + if (!in_array($ident, $options['ridentifiers'])) { + $options['ridentifiers'][] = $ident; + $options['result'][] = array('host'=>$host, 'plugin'=>$plugin, 'pinst'=>$pinst, 'type'=>$type, 'tinst'=>$tinst); + } +} + +/** + * Fetch list of hosts found in collectd's datadirs. + * @return Sorted list of hosts (sorted by label from rigth to left) + */ +function collectd_list_hosts() { + $options = array( + 'result' => array(), + 'cb_host' => '_collectd_list_cb_host', + 'cb_plugin' => false, + 'cb_pinst' => false, + 'cb_type' => false, + 'cb_tinst' => false + ); + collectd_walk($options); + $hosts = array_unique($options['result']); usort($hosts, 'collectd_compare_host'); return $hosts; } @@ -87,123 +237,66 @@ function collectd_list_hosts() { * @arg_host Name of host for which to return plugins * @return Sorted list of plugins (sorted alphabetically) */ -function collectd_list_plugins($arg_host) { - global $config; - - $plugins = array(); - foreach ($config['datadirs'] as $datadir) - if (preg_match(REGEXP_HOST, $arg_host) && ($d = @opendir($datadir.'/'.$arg_host))) { - while (($dent = readdir($d)) !== false) - if ($dent != '.' && $dent != '..' && is_dir($datadir.'/'.$arg_host.'/'.$dent)) { - if ($i = strpos($dent, '-')) - $plugins[] = substr($dent, 0, $i); - else - $plugins[] = $dent; - } - closedir($d); - } - $plugins = array_unique($plugins); +function collectd_list_plugins($arg_host, $arg_plugin = null) { + $options = array( + 'result' => array(), + 'cb_host' => '_collectd_list_cb_host', + 'cb_plugin' => '_collectd_list_cb_plugin', + 'cb_pinst' => is_null($arg_plugin) ? false : '_collectd_list_cb_pinst', + 'cb_type' => false, + 'cb_tinst' => false, + 'filter_host' => $arg_host, + 'filter_plugin' => $arg_plugin + ); + collectd_walk($options); + $plugins = array_unique($options['result']); sort($plugins); return $plugins; } /** - * Fetch list of plugin instances found in collectd's datadirs for given host+plugin - * @arg_host Name of host - * @arg_plugin Name of plugin - * @return Sorted list of plugin instances (sorted alphabetically) - */ -function collectd_list_pinsts($arg_host, $arg_plugin) { - global $config; - - $pinsts = array(); - foreach ($config['datadirs'] as $datadir) - if (preg_match(REGEXP_HOST, $arg_host) && ($d = opendir($datadir.'/'.$arg_host))) { - while (($dent = readdir($d)) !== false) - if ($dent != '.' && $dent != '..' && is_dir($datadir.'/'.$arg_host.'/'.$dent)) { - if ($i = strpos($dent, '-')) { - $plugin = substr($dent, 0, $i); - $pinst = substr($dent, $i+1); - } else { - $plugin = $dent; - $pinst = ''; - } - if ($plugin == $arg_plugin) - $pinsts[] = $pinst; - } - closedir($d); - } - $pinsts = array_unique($pinsts); - sort($pinsts); - return $pinsts; -} - -/** * Fetch list of types found in collectd's datadirs for given host+plugin+instance * @arg_host Name of host * @arg_plugin Name of plugin * @arg_pinst Plugin instance * @return Sorted list of types (sorted alphabetically) */ -function collectd_list_types($arg_host, $arg_plugin, $arg_pinst) { - global $config; - - $types = array(); - $my_plugin = $arg_plugin . (strlen($arg_pinst) ? '-'.$arg_pinst : ''); - if (!preg_match(REGEXP_PLUGIN, $my_plugin)) - return $types; - foreach ($config['datadirs'] as $datadir) - if (preg_match(REGEXP_HOST, $arg_host) && ($d = @opendir($datadir.'/'.$arg_host.'/'.$my_plugin))) { - while (($dent = readdir($d)) !== false) - if ($dent != '.' && $dent != '..' && is_file($datadir.'/'.$arg_host.'/'.$my_plugin.'/'.$dent) && substr($dent, strlen($dent)-4) == '.rrd') { - $dent = substr($dent, 0, strlen($dent)-4); - if ($i = strpos($dent, '-')) - $types[] = substr($dent, 0, $i); - else - $types[] = $dent; - } - closedir($d); - } - $types = array_unique($types); +function collectd_list_types($arg_host, $arg_plugin, $arg_pinst, $arg_type = null) { + $options = array( + 'result' => array(), + 'cb_host' => '_collectd_list_cb_host', + 'cb_plugin' => '_collectd_list_cb_plugin', + 'cb_pinst' => '_collectd_list_cb_pinst', + 'cb_type' => '_collectd_list_cb_type', + 'cb_tinst' => is_null($arg_type) ? false : '_collectd_list_cb_tinst', + 'filter_host' => $arg_host, + 'filter_plugin' => $arg_plugin, + 'filter_pinst' => $arg_pinst, + 'filter_type' => $arg_type + ); + collectd_walk($options); + $types = array_unique($options['result']); sort($types); return $types; } -/** - * Fetch list of type instances found in collectd's datadirs for given host+plugin+instance+type - * @arg_host Name of host - * @arg_plugin Name of plugin - * @arg_pinst Plugin instance - * @arg_type Type - * @return Sorted list of type instances (sorted alphabetically) - */ -function collectd_list_tinsts($arg_host, $arg_plugin, $arg_pinst, $arg_type) { - global $config; - - $tinsts = array(); - $my_plugin = $arg_plugin . (strlen($arg_pinst) ? '-'.$arg_pinst : ''); - if (!preg_match(REGEXP_PLUGIN, $my_plugin)) - return $types; - foreach ($config['datadirs'] as $datadir) - if (preg_match(REGEXP_HOST, $arg_host) && ($d = @opendir($datadir.'/'.$arg_host.'/'.$my_plugin))) { - while (($dent = readdir($d)) !== false) - if ($dent != '.' && $dent != '..' && is_file($datadir.'/'.$arg_host.'/'.$my_plugin.'/'.$dent) && substr($dent, strlen($dent)-4) == '.rrd') { - $dent = substr($dent, 0, strlen($dent)-4); - if ($i = strpos($dent, '-')) { - $type = substr($dent, 0, $i); - $tinst = substr($dent, $i+1); - } else { - $type = $dent; - $tinst = ''; - } - if ($type == $arg_type) - $tinsts[] = $tinst; - } - closedir($d); - } - $tinsts = array_unique($tinsts); - sort($tinsts); - return $tinsts; +function collectd_list_graphs($arg_host, $arg_plugin, $arg_pinst, $arg_type, $arg_tinst) { + $options = array( + 'result' => array(), + 'ridentifiers' => array(), + 'cb_host' => '_collectd_list_cb_host', + 'cb_plugin' => '_collectd_list_cb_plugin', + 'cb_pinst' => '_collectd_list_cb_pinst', + 'cb_type' => '_collectd_list_cb_type', + 'cb_tinst' => '_collectd_list_cb_graph', + 'filter_host' => $arg_host, + 'filter_plugin' => $arg_plugin, + 'filter_pinst' => $arg_pinst, + 'filter_type' => $arg_type, + 'filter_tinst' => $arg_tinst == '@' ? '@merge' : $arg_tinst + ); + collectd_walk($options); + return $options['result']; } /** diff --git a/contrib/php-collection/graph.php b/contrib/php-collection/graph.php index 17749e06..b9fefa6a 100644 --- a/contrib/php-collection/graph.php +++ b/contrib/php-collection/graph.php @@ -164,7 +164,7 @@ $logscale = (boolean)read_var('logarithmic', $_GET, false); $tinylegend = (boolean)read_var('tinylegend', $_GET, false); // Check that at least 1 RRD exists for the specified request -$all_tinst = collectd_list_tinsts($host, $plugin, $pinst, $type); +$all_tinst = collectd_list_types($host, $plugin, $pinst, $type); if (count($all_tinst) == 0) return error404($graph_identifier, "No rrd file found for graphing"); @@ -182,7 +182,7 @@ if ($tinylegend) $opts['tinylegend'] = 1; $rrd_cmd = false; -if (isset($MetaGraphDefs[$type])) { +if ((is_null($tinst) || $tinst == '@merge') && isset($MetaGraphDefs[$type])) { $identifiers = array(); foreach ($all_tinst as &$atinst) $identifiers[] = collectd_identifier($host, $plugin, is_null($pinst) ? '' : $pinst, $type, $atinst); diff --git a/contrib/php-collection/index.php b/contrib/php-collection/index.php index 1abf40d5..5953fbd3 100644 --- a/contrib/php-collection/index.php +++ b/contrib/php-collection/index.php @@ -39,6 +39,22 @@ function dhtml_response_list(&$items, $method) { print(""); } +function dhtml_response_graphs(&$graphs, $method) { + header("Content-Type: text/xml"); + + print(''."\n"); + print("\n"); + printf(" %s\n", htmlspecialchars($method)); + print(" \n"); + foreach ($graphs as &$graph) + printf(' '."\n", + htmlspecialchars($graph['host']), htmlspecialchars($graph['plugin']), htmlspecialchars($graph['pinst']), + htmlspecialchars($graph['type']), htmlspecialchars($graph['tinst']), htmlspecialchars($graph['timespan']), + htmlspecialchars($graph['logarithmic']), htmlspecialchars($graph['tinyLegend'])); + print(" \n"); + print(""); +} + /** * Product page body with selection fields */ @@ -66,7 +82,7 @@ function build_page() {