Merge branch 'collectd-4.10'
authorFlorian Forster <octo@leeloo.lan.home.verplant.org>
Sun, 13 Jun 2010 19:44:21 +0000 (21:44 +0200)
committerFlorian Forster <octo@leeloo.lan.home.verplant.org>
Sun, 13 Jun 2010 19:44:21 +0000 (21:44 +0200)
configure.in
contrib/GenericJMX.conf
contrib/collectd2html.pl
src/bind.c
src/collectd.conf.in
src/collectd.conf.pod
src/libcollectdclient/client.c
src/powerdns.c
src/processes.c
src/python.c
src/snmp.c

index 1af4eff..22910aa 100644 (file)
@@ -1020,7 +1020,7 @@ fi
 AC_MSG_CHECKING([if have htonll defined])
 
     have_htonll="no"
-    AC_RUN_IFELSE([
+    AC_LINK_IFELSE([
        AC_LANG_PROGRAM([
 #include <sys/types.h>
 #include <netinet/in.h>
index f4dd8f0..1d3fe56 100644 (file)
 #      </Value>
     </MBean>
 
+    ######################################
+    # Define the "jmx_memory" type as:   #
+    #   jmx_memory  value:GAUGE:0:U      #
+    # See types.db(5) for details.       #
+    ######################################
+
     # Generic heap/nonheap memory usage.
     <MBean "memory">
       ObjectName "java.lang:type=Memory"
 
       # Creates four values: committed, init, max, used
       <Value>
-        Type "memory"
+        Type "jmx_memory"
         #InstancePrefix ""
         #InstanceFrom ""
         Table true
 
       # Creates four values: committed, init, max, used
       <Value>
-        Type "memory"
+        Type "jmx_memory"
         #InstancePrefix ""
         #InstanceFrom ""
         Table true
         Attribute "NonHeapMemoryUsage"
+        InstancePrefix "nonheap-"
       </Value>
     </MBean>
 
       InstanceFrom "name"
 
       <Value>
-        Type "memory"
+        Type "jmx_memory"
         #InstancePrefix ""
         #InstanceFrom ""
         Table true
index 7953d67..fe4e2bd 100644 (file)
@@ -44,7 +44,7 @@ use Getopt::Long qw(:config no_ignore_case bundling pass_through);
 my $DIR       = "/var/lib/collectd";
 my $HOST      = undef;
 my $IMG_FMT   = "PNG";
-my $RECURSIVE = 0;
+my $RECURSIVE = 1;
 
 GetOptions (
     "host=s"         => \$HOST,
@@ -63,12 +63,12 @@ if (defined($HOST) && ($DIR !~ m/\/$HOST\/?$/) && (-d "$DIR/$HOST")) {
 
 my @COLORS = (0xff7777, 0x7777ff, 0x55ff55, 0xffcc77, 0xff77ff, 0x77ffff,
        0xffff77, 0x55aaff);
-my @tmp = `/bin/hostname`; chomp(@tmp);
+my @tmp = `/bin/hostname -f`; chomp(@tmp);
 $HOST = $tmp[0] if (! defined $HOST);
 my $svg_p = ($IMG_FMT eq "SVG");
 my $IMG_SFX = $svg_p ? ".svg" : ".png";
 my $IMG_DIR = "${HOST}.dir";
-my $HTML = "${HOST}.html";
+my $HTML = "${HOST}.xhtml";
 
 ################################################################################
 #
@@ -118,14 +118,20 @@ open(OUT, ">$HTML");
 my $title="Rrd plot for $HOST";
 
 print OUT <<END;
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
-   "http://www.w3.org/TR/html4/loose.dtd">
-<html>
+<!DOCTYPE html PUBLIC
+  "-//W3C//DTD XHTML 1.1//EN"
+  "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
 <head>
+<style type="text/css" media="screen">
+.graph { text-align: center; }
+object.graph { width: 670; height: 179; }
+</style>
 <title>$title</title>
+<meta http-equiv="Content-Type"
+      content="application/xhtml+xml; charset=us-ascii" />
 </head>
 <body>
-<center>
 END
 
 # list interesting rrd
@@ -140,27 +146,28 @@ else {
 }
 chomp(@list);
 
-foreach my $rrd (sort @list){
+@list = sort @list;
+foreach my $rrd (@list){
        $rrd =~ m/^$DIR\/(.*)\.rrd$/;
        push(@rrds, $1);
 }
 
 # table of contents
 print OUT <<END;
-<A name="top"></A><H1>$title</H1>
-<P>
+<h1><a id="top">$title</a></h1>
+<p>
 END
 
 foreach my $bn (@rrds){
        my $cleaned_bn = $bn;
        $cleaned_bn =~ tr/%\//__/;
        print OUT <<END;
-<A href="#$cleaned_bn">$bn</A>
+<a href="#$cleaned_bn">$bn</a>
 END
 }
 
 print OUT <<END;
-</P>
+</p>
 END
 
 # graph interesting rrd
@@ -205,7 +212,7 @@ for (my $i = 0; $i < scalar(@rrds); ++$i) {
        my $cleaned_bn = $bn;
        $cleaned_bn =~ tr/%\//__/;
        print OUT <<END;
-<A name="$cleaned_bn"></A><H1>$bn</H1>
+<h2><a id="$cleaned_bn">$bn</a></h2>
 END
 
        # graph various ranges
@@ -222,24 +229,28 @@ END
                my $cleaned_img = $img; $cleaned_img =~ s/%/%25/g;
                if (! $svg_p) {
                        print OUT <<END;
-<P><IMG src="$cleaned_img" alt="${bn} $span"></P>
+<p class="graph"><img src="$cleaned_img" alt="${bn} $span" /></p>
 END
                } else {
                        print OUT <<END;
-<P><object data="$cleaned_img" type="image/svg+xml"
-           width="670" height="179">
-  ${bn} $span</object></P>
+<p class="graph"><object data="$cleaned_img" type="image/svg+xml">
+  ${bn} $span</object></p>
 END
                }
        }
 
        print OUT <<END;
-<A href="#top">[top]</A>
+<p><a href="#top">[top]</a></p>
 END
 }
 
 print OUT <<END;
-</center>
+<hr />
+<p>
+  <a href="http://validator.w3.org/check?uri=referer"><img
+     src="http://www.w3.org/Icons/valid-xhtml10"
+     alt="Valid XHTML 1.0 Strict" height="31" width="88" /></a>
+</p>
 </body>
 </html>
 END
index 6388774..6e0b907 100644 (file)
  *   Florian Forster <octo at verplant.org>
  **/
 
-#define _XOPEN_SOURCE 600 /* glibc2 needs this for strptime */
+#include "config.h"
+
+#ifndef _XOPEN_SOURCE
+# define _XOPEN_SOURCE 600 /* glibc2 needs this for strptime */
+#endif
 
 #include "collectd.h"
 #include "common.h"
index 38284ed..9cdecc0 100644 (file)
@@ -17,6 +17,7 @@
 #PluginDir   "@prefix@/lib/@PACKAGE_NAME@"
 #TypesDB     "@prefix@/share/@PACKAGE_NAME@/types.db"
 #Interval     10
+#Timeout      2
 #ReadThreads  5
 
 ##############################################################################
@@ -34,6 +35,7 @@
 #      LogLevel @DEFAULT_LOG_LEVEL@
 #      File STDOUT
 #      Timestamp true
+#      PrintSeverity false
 #</Plugin>
 
 #<Plugin syslog>
@@ -88,6 +90,7 @@
 #@BUILD_PLUGIN_MEMCACHEC_TRUE@LoadPlugin memcachec
 #@BUILD_PLUGIN_MEMCACHED_TRUE@LoadPlugin memcached
 @BUILD_PLUGIN_MEMORY_TRUE@@BUILD_PLUGIN_MEMORY_TRUE@LoadPlugin memory
+#@BUILD_PLUGIN_MODBUS_TRUE@LoadPlugin modbus
 #@BUILD_PLUGIN_MULTIMETER_TRUE@LoadPlugin multimeter
 #@BUILD_PLUGIN_MYSQL_TRUE@LoadPlugin mysql
 #@BUILD_PLUGIN_NETAPP_TRUE@LoadPlugin netapp
 #              MTime "-5m"
 #              Size "+10k"
 #              Recursive true
+#              IncludeHidden false
 #      </Directory>
 #</Plugin>
 
 #              Key "page_key"
 #              <Match>
 #                      Regex "(\\d+) bytes sent"
+#                      ExcludeRegex "<lines to be excluded>"
 #                      DSType CounterAdd
 #                      Type "ipt_octets"
 #                      Instance "type_instance"
 #      Port "11211"
 #</Plugin>
 
+#<Plugin modbus>
+#      <Data "data_name">
+#              RegisterBase 1234
+#              RegisterType float
+#              Type gauge
+#              Instance "..."
+#      </Data>
+#
+#      <Host "name">
+#              Address "addr"
+#              Port "1234"
+#              Interval 60
+#
+#              <Slave 1>
+#                      Instance "foobar" # optional
+#                      Collect "data_name"
+#              </Slave>
+#      </Host>
+#</Plugin>
+
 #<Plugin mysql>
 #      <Database db_name>
 #              Host "database.serv.er"
 #</Plugin>
 
 @LOAD_PLUGIN_NETWORK@<Plugin network>
+#      # client setup:
 @LOAD_PLUGIN_NETWORK@  Server "ff18::efc0:4a42" "25826"
-@LOAD_PLUGIN_NETWORK@  Server "239.192.74.66" "25826"
-#      Listen "ff18::efc0:4a42" "25826"
-#      Listen "239.192.74.66" "25826"
+@LOAD_PLUGIN_NETWORK@  <Server "239.192.74.66" "25826">
+#              SecurityLevel Encrypt
+#              Username "user"
+#              Password "secret"
+#              Interface "eth0"
+@LOAD_PLUGIN_NETWORK@  </Server>
 #      TimeToLive "128"
-#      Forward false
-#      CacheFlush 1800
+#
+#      # server setup:
+#      Listen "ff18::efc0:4a42" "25826"
+#      <Listen "239.192.74.66" "25826">
+#              SecurityLevel Sign
+#              AuthFile "/etc/collectd/passwd"
+#              Interface "eth0"
+#      </Listen>
+#      MaxPacketSize 1024
+#
+#      # proxy setup (client and server as above):
+#      Forward true
+#
+#      # statistics about the network plugin itself
 #      ReportStats false
+#
+#      # "garbage collection"
+#      CacheFlush 1800
 @LOAD_PLUGIN_NETWORK@</Plugin>
 
 #<Plugin nginx>
 
 #<Plugin openvpn>
 #      StatusFile "/etc/openvpn/openvpn-status.log"
+#      ImprovedNamingSchema false
+#      CollectCompression true
+#      CollectIndividualUsers true
+#      CollectUserCount false
 #</Plugin>
 
 #<Plugin oracle>
 #              Query magic
 #      </Database>
 #      <Database bar>
+#              Interval 60
 #              Service "service_name"
 #              Query backend # predefined
 #              Query rt36_tickets
 #      <URL "http://example.com/collectd-post">
 #              User "collectd"
 #              Password "weCh3ik0"
+#              VerifyPeer true
+#              VerifyHost true
+#              CACert "/etc/ssl/ca.crt"
+#              Format "Command"
+#              StoreRates false
 #      </URL>
 #</Plugin>
 
index 98b9298..dd08e28 100644 (file)
@@ -2532,7 +2532,7 @@ I<libgcrypt>.
 Set the outgoing interface for IP packets. This applies at least
 to IPv6 packets and if possible to IPv4. If this option is not applicable,
 undefined or a non-existent interface name is specified, the default
-behaviour is to let the kernel choose the appropriate interface. Be warned
+behavior is to let the kernel choose the appropriate interface. Be warned
 that the manual selection of an interface for unicast traffic is only
 necessary in rare cases.
 
@@ -2589,7 +2589,7 @@ the file is being read, it is locked using L<fcntl(2)>.
 Set the incoming interface for IP packets explicitly. This applies at least
 to IPv6 packets and if possible to IPv4. If this option is not applicable,
 undefined or a non-existent interface name is specified, the default
-behaviour is, to let the kernel choose the appropriate interface. Thus incoming
+behavior is, to let the kernel choose the appropriate interface. Thus incoming
 traffic gets only accepted, if it arrives on the given interface.
 
 =back
@@ -2956,7 +2956,7 @@ because aggregating this data in a save manner is tricky. Defaults to B<true>.
 =item B<CollectUserCount> B<true>|B<false>
 
 When enabled, the number of currently connected clients or users is collected.
-This is expecially interesting when B<CollectIndividualUsers> is disabled, but
+This is especially interesting when B<CollectIndividualUsers> is disabled, but
 can be configured independently from that option. Defaults to B<false>.
 
 =back
@@ -3028,6 +3028,83 @@ refer to them from.
 This plugin embeds a Perl-interpreter into collectd and provides an interface
 to collectd's plugin system. See L<collectd-perl(5)> for its documentation.
 
+=head2 Plugin C<pinba>
+
+The I<Pinba plugin> receives profiling information from I<Pinba>, an extension
+for the I<PHP> interpreter. At the end of executing a script, i.e. after a
+PHP-based webpage has been delivered, the extension will send a UDP packet
+containing timing information, peak memory usage and so on. The plugin will
+wait for such packets, parse them and account the provided information, which
+is then dispatched to the daemon once per interval.
+
+Synopsis:
+
+ <Plugin pinba>
+   Address "::0"
+   Port "30002"
+   # Overall statistics for the website.
+   <View "www-total">
+     Server "www.example.com"
+   </View>
+   # Statistics for www-a only
+   <View "www-a">
+     Host "www-a.example.com"
+     Server "www.example.com"
+   </View>
+   # Statistics for www-b only
+   <View "www-b">
+     Host "www-b.example.com"
+     Server "www.example.com"
+   </View>
+ </Plugin>
+
+The plugin provides the following configuration options:
+
+=over 4
+
+=item B<Address> I<Node>
+
+Configures the address used to open a listening socket. By default, plugin will
+bind to the I<any> address C<::0>.
+
+=item B<Port> I<Service>
+
+Configures the port (service) to bind to. By default the default Pinba port
+"30002" will be used. The option accepts service names in addition to port
+numbers and thus requires a I<string> argument.
+
+=item E<lt>B<View> I<Name>E<gt> block
+
+The packets sent by the Pinba extension include the hostname of the server, the
+server name (the name of the virtual host) and the script that was executed.
+Using B<View> blocks it is possible to separate the data into multiple groups
+to get more meaningful statistics. Each packet is added to all matching groups,
+so that a packet may be accounted for more than once.
+
+=over 4
+
+=item B<Host> I<Host>
+
+Matches the hostname of the system the webserver / script is running on. This
+will contain the result of the L<gethostname(2)> system call. If not
+configured, all hostnames will be accepted.
+
+=item B<Server> I<Server>
+
+Matches the name of the I<virtual host>, i.e. the contents of the
+C<$_SERVER["SERVER_NAME"]> variable when within PHP. If not configured, all
+server names will be accepted.
+
+=item B<Script> I<Script>
+
+Matches the name of the I<script name>, i.e. the contents of the
+C<$_SERVER["SCRIPT_NAME"]> variable when within PHP. If not configured, all
+script names will be accepted.
+
+=back
+
+=back
+
 =head2 Plugin C<ping>
 
 The I<Ping> plugin starts a new thread which sends ICMP "ping" packets to the
@@ -3081,7 +3158,7 @@ operating systems.
 
 =item B<MaxMissed> I<Packets>
 
-Trigger a DNS resolv after the host has not replied to I<Packets> packets. This
+Trigger a DNS resolve after the host has not replied to I<Packets> packets. This
 enables the use of dynamic DNS services (like dyndns.org) with the ping plugin.
 
 Default: B<-1> (disabled)
index 63d4e9d..0c748ba 100644 (file)
@@ -777,9 +777,9 @@ int lcc_putval (lcc_connection_t *c, const lcc_value_list_t *vl) /* {{{ */
     SSTRCATF (command, " interval=%i", vl->interval);
 
   if (vl->time > 0)
-    SSTRCATF (command, "%u", (unsigned int) vl->time);
+    SSTRCATF (command, " %u", (unsigned int) vl->time);
   else
-    SSTRCAT (command, "N");
+    SSTRCAT (command, " N");
 
   for (i = 0; i < vl->values_len; i++)
   {
index 3e7ebb3..29f6bca 100644 (file)
 #define FUNC_ERROR(func) do { char errbuf[1024]; ERROR ("powerdns plugin: %s failed: %s", func, sstrerror (errno, errbuf, sizeof (errbuf))); } while (0)
 
 #define SERVER_SOCKET  LOCALSTATEDIR"/run/pdns.controlsocket"
-#define SERVER_COMMAND "SHOW *"
+#define SERVER_COMMAND "SHOW * \n"
 
 #define RECURSOR_SOCKET  LOCALSTATEDIR"/run/pdns_recursor.controlsocket"
 #define RECURSOR_COMMAND "get noerror-answers nxdomain-answers " \
   "servfail-answers sys-msec user-msec qa-latency cache-entries cache-hits " \
-  "cache-misses questions"
+  "cache-misses questions\n"
 
 struct list_item_s;
 typedef struct list_item_s list_item_t;
@@ -439,6 +439,11 @@ static int powerdns_get_data_stream (list_item_t *item, /* {{{ */
     return (-1);
   }
 
+  struct timeval timeout;
+  timeout.tv_sec=5;
+  timeout.tv_usec=0;
+  status = setsockopt (sd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof (timeout));
+
   status = connect (sd, (struct sockaddr *) &item->sockaddr,
       sizeof (item->sockaddr));
   if (status != 0)
@@ -531,7 +536,7 @@ static int powerdns_read_server (list_item_t *item) /* {{{ */
   int fields_num;
 
   if (item->command == NULL)
-    item->command = strdup ("SHOW *");
+    item->command = strdup (SERVER_COMMAND);
   if (item->command == NULL)
   {
     ERROR ("powerdns plugin: strdup failed.");
@@ -612,7 +617,7 @@ static int powerdns_update_recursor_command (list_item_t *li) /* {{{ */
   else
   {
     sstrncpy (buffer, "get ", sizeof (buffer));
-    status = strjoin (&buffer[4], sizeof (buffer) - strlen ("get "),
+    status = strjoin (&buffer[strlen("get ")], sizeof (buffer) - strlen ("get "),
        li->fields, li->fields_num,
        /* seperator = */ " ");
     if (status < 0)
@@ -620,6 +625,14 @@ static int powerdns_update_recursor_command (list_item_t *li) /* {{{ */
       ERROR ("powerdns plugin: strjoin failed.");
       return (-1);
     }
+    buffer[sizeof (buffer) - 1] = 0;
+    int i = strlen (buffer);
+    if (i < sizeof (buffer) - 2)
+    {
+      buffer[i++] = ' ';
+      buffer[i++] = '\n';
+      buffer[i++] = '\0';
+    }
   }
 
   buffer[sizeof (buffer) - 1] = 0;
index c642e58..8a3df64 100644 (file)
@@ -1797,6 +1797,11 @@ static int ps_read (void)
                        pse.vmem_code = 0;
                        pse.stack_size =  0;
 
+                       pse.io_rchar = -1;
+                       pse.io_wchar = -1;
+                       pse.io_syscr = -1;
+                       pse.io_syscw = -1;
+
                        ps_list_add (cmdline, cargs, &pse);
                } /* for (i = 0 .. nprocs) */
 
index 00516fb..6be727e 100644 (file)
@@ -371,6 +371,7 @@ static int cpy_write_callback(const data_set_t *ds, const value_list_t *value_li
                        }
                        if (PyErr_Occurred() != NULL) {
                                cpy_log_exception("value building for write callback");
+                               Py_DECREF(list);
                                CPY_RETURN_FROM_THREADS 0;
                        }
                }
@@ -427,7 +428,7 @@ static int cpy_write_callback(const data_set_t *ds, const value_list_t *value_li
                        }
                        free(table);
                }
-               v = PyObject_New(Values, (void *) &ValuesType);
+               v = PyObject_New(Values, (void *) &ValuesType); /* New reference. */
                sstrncpy(v->data.host, value_list->host, sizeof(v->data.host));
                sstrncpy(v->data.type, value_list->type, sizeof(v->data.type));
                sstrncpy(v->data.type_instance, value_list->type_instance, sizeof(v->data.type_instance));
@@ -438,6 +439,7 @@ static int cpy_write_callback(const data_set_t *ds, const value_list_t *value_li
                v->values = list;
                v->meta = dict;
                ret = PyObject_CallFunctionObjArgs(c->callback, v, c->data, (void *) 0); /* New reference. */
+               Py_XDECREF(v);
                if (ret == NULL) {
                        cpy_log_exception("write callback");
                } else {
@@ -453,7 +455,7 @@ static int cpy_notification_callback(const notification_t *notification, user_da
        Notification *n;
 
        CPY_LOCK_THREADS
-               n = PyObject_New(Notification, (void *) &NotificationType);
+               n = PyObject_New(Notification, (void *) &NotificationType); /* New reference. */
                sstrncpy(n->data.host, notification->host, sizeof(n->data.host));
                sstrncpy(n->data.type, notification->type, sizeof(n->data.type));
                sstrncpy(n->data.type_instance, notification->type_instance, sizeof(n->data.type_instance));
@@ -463,6 +465,7 @@ static int cpy_notification_callback(const notification_t *notification, user_da
                sstrncpy(n->message, notification->message, sizeof(n->message));
                n->severity = notification->severity;
                ret = PyObject_CallFunctionObjArgs(c->callback, n, c->data, (void *) 0); /* New reference. */
+               Py_XDECREF(n);
                if (ret == NULL) {
                        cpy_log_exception("notification callback");
                } else {
@@ -896,6 +899,11 @@ static int cpy_init(void) {
        static pthread_t thread;
        sigset_t sigset;
        
+       if (!Py_IsInitialized()) {
+               WARNING("python: Plugin loaded but not configured.");
+               plugin_unregister_shutdown("python");
+               return 0;
+       }
        PyEval_InitThreads();
        /* Now it's finally OK to use python threads. */
        for (c = cpy_init_callbacks; c; c = c->next) {
index fdb7c65..1c2828c 100644 (file)
@@ -755,7 +755,21 @@ static value_t csnmp_value_list_to_value (struct variable_list *vl, int type,
   }
   else
   {
-    WARNING ("snmp plugin: I don't know the ASN type `%i'", (int) vl->type);
+    char oid_buffer[1024];
+
+    memset (oid_buffer, 0, sizeof (oid_buffer));
+    snprint_objid (oid_buffer, sizeof (oid_buffer) - 1,
+       vl->name, vl->name_length);
+
+#ifdef ASN_NULL
+    if (vl->type == ASN_NULL)
+      INFO ("snmp plugin: OID \"%s\" is undefined (type ASN_NULL)",
+         oid_buffer);
+    else
+#endif
+      WARNING ("snmp plugin: I don't know the ASN type \"%i\" (OID: %s)",
+         (int) vl->type, oid_buffer);
+
     defined = 0;
   }
 
@@ -952,7 +966,7 @@ static int csnmp_strvbcopy (char *dst, /* {{{ */
   for (i = 0; i < num_chars; i++)
   {
     /* Check for control characters. */
-    if ((src[i] >= 0) && (src[i] < 32))
+    if ((unsigned char)src[i] < 32)
       return (csnmp_strvbcopy_hexstring (dst, vb, dst_size));
     dst[i] = src[i];
   }