Merge branch 'collectd-4.6'
authorFlorian Forster <octo@leeloo.lan.home.verplant.org>
Mon, 9 Mar 2009 17:48:12 +0000 (18:48 +0100)
committerFlorian Forster <octo@leeloo.lan.home.verplant.org>
Mon, 9 Mar 2009 17:48:12 +0000 (18:48 +0100)
1  2 
README
src/collectd.conf.pod
src/rrdtool.c

diff --combined README
--- 1/README
--- 2/README
+++ b/README
@@@ -179,9 -179,6 +179,9 @@@ Feature
      - 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.
  
@@@ -544,12 -541,24 +544,24 @@@ Crosscompilin
    that the compiled binary actually behaves as it should, but since NANs
    are likely never passed to the libm you have a good chance to be lucky.
  
+   Likewise, collectd needs to know the layout of doubles in memory, in order
+   to craft uniform network packets over different architectures. For this, it
+   needs to know how to convert doubles into the memory layout used by x86. The
+   configure script tries to figure this out by compiling and running a few
+   small test programs. This is of course not possible when cross-compiling.
+   You can use the `--with-fp-layout' option to tell the configure script which
+   conversion method to assume. Valid arguments are:
+     * `nothing'    (12345678 -> 12345678)
+     * `endianflip' (12345678 -> 87654321)
+     * `intswap'    (12345678 -> 56781234)
  
  Contact
  -------
  
-   For questions, bugreports, development information and basically all other
-   concerns please send an email to collectd's mailinglist at
+   For questions, bug reports, development information and basically all other
+   concerns please send an email to collectd's mailing list at
    <collectd at verplant.org>.
  
    For live discussion and more personal contact visit us in IRC, we're in
@@@ -563,5 -572,6 +575,6 @@@ Autho
    Sebastian tokkee Harl <sh at tokkee.org>,
    and many contributors (see `AUTHORS').
  
-   Please send bugreports and patches to the mailinglist, see `Contact' above.
+   Please send bug reports and patches to the mailing list, see `Contact'
+   above.
  
diff --combined src/collectd.conf.pod
@@@ -454,7 -454,7 +454,7 @@@ finance page and dispatch the value to 
        <Match>
          Regex "<span +class=\"pr\"[^>]*> *([0-9]*\\.[0-9]+) *</span>"
          DSType "GaugeAverage"
-       # Note: `stock_value' is not a standard type.
+         # Note: `stock_value' is not a standard type.
          Type "stock_value"
          Instance "AMD"
        </Match>
@@@ -606,6 -606,9 +606,9 @@@ like this
  use a more strict database server, you may have to select from a dummy table or
  something.)
  
+ Please note that some databases, for example B<Oracle>, will fail if you
+ include a semicolon at the end of the statement.
  =item B<MinVersion> I<Version>
  
  =item B<MaxVersion> I<Value>
@@@ -662,7 -665,7 +665,7 @@@ separated by dashes I<("-")>
  
  Specifies the columns whose values will be used to create the "type-instance"
  for each row. If you specify more than one column, the value of all columns
 -will be join together with the dashes I<("-")> as separation character.
 +will be joined together with dashes I<("-")> as separation characters.
  
  The plugin itself does not check whether or not all built instances are
  different. It's your responsibility to assure that each is unique. This is
@@@ -1083,62 -1086,6 +1086,62 @@@ and all other interrupts are collected
  
  =back
  
 +=head2 Plugin C<java>
 +
 +The I<Java> plugin makes it possible to write extensions for collectd in Java.
 +This section only discusses the syntax and semantic of the configuration
 +options. For more in-depth information on the I<Java> plugin, please read
 +L<collectd-java(5)>.
 +
 +Synopsis:
 +
 + <Plugin "java">
 +   JVMArg "-verbose:jni"
 +   JVMArg "-Djava.class.path=/opt/collectd/lib/collectd/bindings/java"
 +   LoadPlugin "org.collectd.java.Foobar"
 +   <Plugin "org.collectd.java.Foobar">
 +     # To be parsed by the plugin
 +   </Plugin>
 + </Plugin>
 +
 +Available configuration options:
 +
 +=over 4
 +
 +=item B<JVMArg> I<Argument>
 +
 +Argument that is to be passed to the I<Java Virtual Machine> (JVM). This works
 +exactly the way the arguments to the I<java> binary on the command line work.
 +Execute C<javaE<nbsp>--help> for details.
 +
 +Please note that B<all> these options must appear B<before> (i.E<nbsp>e. above)
 +any other options! When another option is found, the JVM will be started and
 +later options will have to be ignored!
 +
 +=item B<LoadPlugin> I<JavaClass>
 +
 +Instantiates a new I<JavaClass> object. The constructor of this object very
 +likely then registers one or more callback methods with the server.
 +
 +See L<collectd-java(5)> for details.
 +
 +When the first such option is found, the virtual machine (JVM) is created. This
 +means that all B<JVMArg> options must appear before (i.E<nbsp>e. above) all
 +B<LoadPlugin> options!
 +
 +=item B<Plugin> I<Name>
 +
 +The entire block is passed to the Java plugin as an
 +I<org.collectd.api.OConfigItem> object.
 +
 +For this to work, the plugin has to register a configuration callback first,
 +see L<collectd-java(5)/"config callback">. This means, that the B<Plugin> block
 +must appear after the appropriate B<LoadPlugin> block. Also note, that I<Name>
 +depends on the (Java) plugin registering the callback and is completely
 +independent from the I<JavaClass> argument passed to B<LoadPlugin>.
 +
 +=back
 +
  =head2 Plugin C<libvirt>
  
  This plugin allows CPU, disk and network load to be collected for virtualized
@@@ -1794,13 -1741,6 +1797,13 @@@ to collectd's plugin system. See L<coll
  
  =head2 Plugin C<ping>
  
 +The I<Ping> plugin starts a new thread which sends ICMP "ping" packets to the
 +configured hosts periodically and measures the network latency. Whenever the
 +C<read> function of the plugin is called, it submits the average latency, the
 +standard deviation and the drop rate for each host.
 +
 +Available configuration options:
 +
  =over 4
  
  =item B<Host> I<IP-address>
  Host to ping periodically. This option may be repeated several times to ping
  multiple hosts.
  
 +=item B<Interval> I<Seconds>
 +
 +Sets the interval in which to send ICMP echo packets to the configured hosts.
 +This is B<not> the interval in which statistics are queries from the plugin but
 +the interval in which the hosts are "pinged". Therefore, the setting here
 +should be smaller than or equal to the global B<Interval> setting. Fractional
 +times, such as "1.24" are allowed.
 +
 +Default: B<1.0>
 +
 +=item B<Timeout> I<Seconds>
 +
 +Time to wait for a response from the host to which an ICMP packet had been
 +sent. If a reply was not received after I<Seconds> seconds, the host is assumed
 +to be down or the packet to be dropped. This setting must be smaller than the
 +B<Interval> setting above for the plugin to work correctly. Fractional
 +arguments are accepted.
 +
 +Default: B<0.9>
 +
  =item B<TTL> I<0-255>
  
  Sets the Time-To-Live of generated ICMP packets.
@@@ -2314,39 -2234,6 +2317,39 @@@ slashes
  
  =back
  
 +=head2 Plugin C<protocols>
 +
 +Collects a lot of information about various network protocols, such as I<IP>,
 +I<TCP>, I<UDP>, etc.
 +
 +Available configuration options:
 +
 +=over 4
 +
 +=item B<Value> I<Selector>
 +
 +Selects whether or not to select a specific value. The string being matched is
 +of the form "I<Protocol>:I<ValueName>", where I<Protocol> will be used as the
 +plugin instance and I<ValueName> will be used as type instance. An example of
 +the string being used would be C<Tcp:RetransSegs>.
 +
 +You can use regular expressions to match a large number of values with just one
 +configuration option. To select all "extended" I<TCP> values, you could use the
 +following statement:
 +
 +  Value "/^TcpExt:/"
 +
 +Whether only matched values are selected or all matched values are ignored
 +depends on the B<IgnoreSelected>. By default, only matched values are selected.
 +If no value is configured at all, all values will be selected.
 +
 +=item B<IgnoreSelected> B<true>|B<false>
 +
 +If set to B<true>, inverts the selection made by B<Value>, i.E<nbsp>e. all
 +matching values will be ignored.
 +
 +=back
 +
  =head2 Plugin C<rrdcached>
  
  The C<rrdcached> plugin uses the RRDTool accelerator daemon, L<rrdcached(1)>,
@@@ -2552,109 -2439,9 +2555,109 @@@ debugging support
  
  =back
  
 +=head2 Plugin C<table>
 +
 +The C<table plugin> provides generic means to parse tabular data and dispatch
 +user specified values. Values are selected based on column numbers. For
 +example, this plugin may be used to get values from the Linux L<proc(5)>
 +filesystem or CSV (comma separated values) files.
 +
 +  <Plugin table>
 +    <Table "/proc/slabinfo">
 +      Instance "slabinfo"
 +      Separator " "
 +      <Result>
 +        Type gauge
 +        InstancePrefix "active_objs"
 +        InstancesFrom 0
 +        ValuesFrom 1
 +      </Result>
 +      <Result>
 +        Type gauge
 +        InstancePrefix "objperslab"
 +        InstancesFrom 0
 +        ValuesFrom 4
 +      </Result>
 +    </Table>
 +  </Plugin>
 +
 +The configuration consists of one or more B<Table> blocks, each of which
 +configures one file to parse. Within each B<Table> block, there are one or
 +more B<Result> blocks, which configure which data to select and how to
 +interpret it.
 +
 +The following options are available inside a B<Table> block:
 +
 +=over 4
 +
 +=item B<Instance> I<instance>
 +
 +If specified, I<instance> is used as the plugin instance. So, in the above
 +example, the plugin name C<table-slabinfo> would be used. If omitted, the
 +filename of the table is used instead, with all special characters replaced
 +with an underscore (C<_>).
 +
 +=item B<Separator> I<string>
 +
 +Any character of I<string> is interpreted as a delimiter between the different
 +columns of the table. A sequence of two or more contiguous delimiters in the
 +table is considered to be a single delimiter, i.E<nbsp>e. there cannot be any
 +empty columns. The plugin uses the L<strtok_r(3)> function to parse the lines
 +of a table - see its documentation for more details. This option is mandatory.
 +
 +A horizontal tab, newline and carriage return may be specified by C<\\t>,
 +C<\\n> and C<\\r> respectively. Please note that the double backslashes are
 +required because of collectd's config parsing.
 +
 +=back
 +
 +The following options are available inside a B<Result> block:
 +
 +=over 4
 +
 +=item B<Type> I<type>
 +
 +Sets the type used to dispatch the values to the daemon. Detailed information
 +about types and their configuration can be found in L<types.db(5)>. This
 +option is mandatory.
 +
 +=item B<InstancePrefix> I<prefix>
 +
 +If specified, prepend I<prefix> to the type instance. If omitted, only the
 +B<InstancesFrom> option is considered for the type instance.
 +
 +=item B<InstancesFrom> I<column0> [I<column1> ...]
 +
 +If specified, the content of the given columns (identified by the column
 +number starting at zero) will be used to create the type instance for each
 +row. Multiple values (and the instance prefix) will be joined together with
 +dashes (I<->) as separation character. If omitted, only the B<InstancePrefix>
 +option is considered for the type instance.
 +
 +The plugin itself does not check whether or not all built instances are
 +different. It’s your responsibility to assure that each is unique. This is
 +especially true, if you do not specify B<InstancesFrom>: B<You> have to make
 +sure that the table only contains one row.
 +
 +If neither B<InstancePrefix> nor B<InstancesFrom> is given, the type instance
 +will be empty.
 +
 +=item B<ValuesFrom> I<column0> [I<column1> ...]
 +
 +Specifies the columns (identified by the column numbers starting at zero)
 +whose content is used as the actual data for the data sets that are dispatched
 +to the daemon. How many such columns you need is determined by the B<Type>
 +setting above. If you specify too many or not enough columns, the plugin will
 +complain about that and no data will be submitted to the daemon. The plugin
 +uses L<strtoll(3)> and L<strtod(3)> to parse counter and gauge values
 +respectively, so anything supported by those functions is supported by the
 +plugin as well. This option is mandatory.
 +
 +=back
 +
  =head2 Plugin C<tail>
  
 -The C<tail plugin> plugins follows logfiles, just like L<tail(1)> does, parses
 +The C<tail plugin> follows logfiles, just like L<tail(1)> does, parses
  each line and dispatches found values. What is matched can be configured by the
  user using (extended) regular expressions, as described in L<regex(7)>.
  
diff --combined src/rrdtool.c
@@@ -111,8 -111,7 +111,8 @@@ static rrd_queue_t    *queue_head = NUL
  static rrd_queue_t    *queue_tail = NULL;
  static rrd_queue_t    *flushq_head = NULL;
  static rrd_queue_t    *flushq_tail = NULL;
 -static pthread_t       queue_thread = 0;
 +static pthread_t       queue_thread;
 +static int             queue_thread_running = 1;
  static pthread_mutex_t queue_lock = PTHREAD_MUTEX_INITIALIZER;
  static pthread_cond_t  queue_cond = PTHREAD_COND_INITIALIZER;
  
@@@ -280,6 -279,7 +280,7 @@@ static void *rrd_queue_thread (void __a
                rrd_cache_t *cache_entry;
                char **values;
                int    values_num;
+               int    status;
                int    i;
  
                  pthread_mutex_lock (&queue_lock);
                  while (true)
                  {
                    struct timespec ts_wait;
-                   int status;
  
                    while ((flushq_head == NULL) && (queue_head == NULL)
                        && (do_shutdown == 0))
                 * we make a copy of it's values */
                pthread_mutex_lock (&cache_lock);
  
-               c_avl_get (cache, queue_entry->filename, (void *) &cache_entry);
+               status = c_avl_get (cache, queue_entry->filename,
+                               (void *) &cache_entry);
  
-               values = cache_entry->values;
-               values_num = cache_entry->values_num;
+               if (status == 0)
+               {
+                       values = cache_entry->values;
+                       values_num = cache_entry->values_num;
  
-               cache_entry->values = NULL;
-               cache_entry->values_num = 0;
-               cache_entry->flags = FLAG_NONE;
+                       cache_entry->values = NULL;
+                       cache_entry->values_num = 0;
+                       cache_entry->flags = FLAG_NONE;
+               }
  
                pthread_mutex_unlock (&cache_lock);
  
+               if (status != 0)
+               {
+                       sfree (queue_entry->filename);
+                       sfree (queue_entry);
+                       continue;
+               }
                /* Update `tv_next_update' */
                if (write_rate > 0.0) 
                  {
                /* Write the values to the RRD-file */
                srrd_update (queue_entry->filename, NULL,
                                values_num, (const char **)values);
 -              DEBUG ("rrdtool plugin: queue thread: Wrote %i values to %s",
 -                              values_num, queue_entry->filename);
 +              DEBUG ("rrdtool plugin: queue thread: Wrote %i value%s to %s",
 +                              values_num, (values_num == 1) ? "" : "s",
 +                              queue_entry->filename);
  
                for (i = 0; i < values_num; i++)
                {
@@@ -627,6 -636,15 +638,15 @@@ static int rrd_cache_insert (const cha
  
        pthread_mutex_lock (&cache_lock);
  
+       /* This shouldn't happen, but it did happen at least once, so we'll be
+        * careful. */
+       if (cache == NULL)
+       {
+               pthread_mutex_unlock (&cache_lock);
+               WARNING ("rrdtool plugin: cache == NULL.");
+               return (-1);
+       }
        c_avl_get (cache, filename, (void *) &rc);
  
        if (rc == NULL)
@@@ -748,8 -766,7 +768,8 @@@ static int rrd_compare_numeric (const v
                return (0);
  } /* int rrd_compare_numeric */
  
 -static int rrd_write (const data_set_t *ds, const value_list_t *vl)
 +static int rrd_write (const data_set_t *ds, const value_list_t *vl,
 +              user_data_t __attribute__((unused)) *user_data)
  {
        struct stat  statbuf;
        char         filename[512];
        return (status);
  } /* int rrd_write */
  
 -static int rrd_flush (int timeout, const char *identifier)
 +static int rrd_flush (int timeout, const char *identifier,
 +              user_data_t __attribute__((unused)) *user_data)
  {
        pthread_mutex_lock (&cache_lock);
  
@@@ -975,28 -991,14 +995,28 @@@ static int rrd_shutdown (void
        pthread_cond_signal (&queue_cond);
        pthread_mutex_unlock (&queue_lock);
  
 +      if ((queue_thread_running != 0)
 +                      && ((queue_head != NULL) || (flushq_head != NULL)))
 +      {
 +              INFO ("rrdtool plugin: Shutting down the queue thread. "
 +                              "This may take a while.");
 +      }
 +      else if (queue_thread_running != 0)
 +      {
 +              INFO ("rrdtool plugin: Shutting down the queue thread.");
 +      }
 +
        /* Wait for all the values to be written to disk before returning. */
 -      if (queue_thread != 0)
 +      if (queue_thread_running != 0)
        {
                pthread_join (queue_thread, NULL);
 -              queue_thread = 0;
 +              memset (&queue_thread, 0, sizeof (queue_thread));
 +              queue_thread_running = 0;
                DEBUG ("rrdtool plugin: queue_thread exited.");
        }
  
 +      /* TODO: Maybe it'd be a good idea to free the cache here.. */
 +
        return (0);
  } /* int rrd_shutdown */
  
@@@ -1041,14 -1043,12 +1061,14 @@@ static int rrd_init (void
  
        pthread_mutex_unlock (&cache_lock);
  
 -      status = pthread_create (&queue_thread, NULL, rrd_queue_thread, NULL);
 +      status = pthread_create (&queue_thread, /* attr = */ NULL,
 +                      rrd_queue_thread, /* args = */ NULL);
        if (status != 0)
        {
                ERROR ("rrdtool plugin: Cannot create queue-thread.");
                return (-1);
        }
 +      queue_thread_running = 1;
  
        DEBUG ("rrdtool plugin: rrd_init: datadir = %s; stepsize = %i;"
                        " heartbeat = %i; rrarows = %i; xff = %lf;",
@@@ -1066,7 -1066,7 +1086,7 @@@ void module_register (void
        plugin_register_config ("rrdtool", rrd_config,
                        config_keys, config_keys_num);
        plugin_register_init ("rrdtool", rrd_init);
 -      plugin_register_write ("rrdtool", rrd_write);
 -      plugin_register_flush ("rrdtool", rrd_flush);
 +      plugin_register_write ("rrdtool", rrd_write, /* user_data = */ NULL);
 +      plugin_register_flush ("rrdtool", rrd_flush, /* user_data = */ NULL);
        plugin_register_shutdown ("rrdtool", rrd_shutdown);
  }