Merge branch 'collectd-4.2'
authorFlorian Forster <octo@huhu.verplant.org>
Thu, 13 Dec 2007 07:16:16 +0000 (08:16 +0100)
committerFlorian Forster <octo@huhu.verplant.org>
Thu, 13 Dec 2007 07:16:16 +0000 (08:16 +0100)
Conflicts:

src/utils_llist.c

1  2 
src/collectd-perl.pod
src/collectd.conf.pod
src/logfile.c
src/utils_avltree.c
src/utils_llist.c

diff --combined src/collectd-perl.pod
@@@ -21,6 -21,9 +21,6 @@@ for collectd in Perl. This is a lot mor
  Perl-script every time you want to read a value with the C<exec plugin> (see
  L<collectd-exec(5)>) and provides a lot more functionality, too.
  
 -Please note that this is still considered to be experimental and subject to
 -change between minor releases.
 -
  =head1 CONFIGURATION
  
  =over 4
@@@ -47,10 -50,6 +47,10 @@@ using the B<-d:Package> command line op
  
  See L<perldebug> for detailed documentation about debugging Perl.
  
 +This option does not prevent collectd from daemonizing, so you should start
 +collectd with the B<-f> command line option. Else you will not be able to use
 +the command line driven interface of the debugger.
 +
  =item B<IncludeDir> I<Dir>
  
  Adds I<Dir> to the B<@INC> array. This is the same as using the B<-IDir>
@@@ -61,7 -60,7 +61,7 @@@ only has effect on plugins loaded afte
  
  =head1 WRITING YOUR OWN PLUGINS
  
- Writing your own plugins is quite simply. collectd manages plugins by means of
+ Writing your own plugins is quite simple. collectd manages plugins by means of
  B<dispatch functions> which call the appropriate B<callback functions>
  registered by the plugins. Any plugin basically consists of the implementation
  of these callback functions and initializing code which registers the
@@@ -104,9 -103,6 +104,9 @@@ be used to clean up the plugin (e.g. cl
  
  =back
  
 +Any function may set the B<$@> variable to describe errors in more detail. The
 +message will be passed on to the user using collectd's logging mechanism.
 +
  See the documentation of the B<plugin_register> method in the section
  "METHODS" below for the number and types of arguments passed to each
  B<callback function>. This section also explains how to register B<callback
@@@ -190,22 -186,16 +190,22 @@@ depending on the value of I<type>. (Ple
  is the value passed as I<name> here and has nothing to do with the I<type>
  argument which simply tells B<plugin_register> what is being registered.)
  
 -The last argument, I<data>, is either a function- or an array-reference. If
 -I<type> is B<TYPE_DATASET>, then the I<data> argument must be an
 +The last argument, I<data>, is either a function name or an array-reference.
 +If I<type> is B<TYPE_DATASET>, then the I<data> argument must be an
  array-reference which points to an array of hashes. Each hash describes one
  data-source. For the exact layout see B<Data-Set> above. Please note that
  there is a large number of predefined data-sets available in the B<types.db>
  file which are automatically registered with collectd.
  
  If the I<type> argument is any of the other types (B<TYPE_INIT>, B<TYPE_READ>,
 -...) then I<data> is expected to be a function reference. These functions are
 -called in the various stages of the daemon and are passed the following
 +...) then I<data> is expected to be a function name. If the name is not
 +prefixed with the plugin's package name collectd will add it automatically.
 +The interface slightly differs from the C interface (which expects a function
 +pointer instead) because Perl does not support to share references to
 +subroutines between threads.
 +
 +These functions are called in the various stages of the daemon (see the
 +section "WRITING YOUR OWN PLUGINS" above) and are passed the following
  arguments:
  
  =over 4
@@@ -257,25 -247,6 +257,25 @@@ B<LOG_NOTICE>, B<LOG_INFO> and B<LOG_DE
  
  =back
  
 +=head1 GLOBAL VARIABLES
 +
 +=over 4
 +
 +=item B<$hostname_g>
 +
 +As the name suggests this variable keeps the hostname of the system collectd
 +is running on. The value might be influenced by the B<Hostname> or
 +B<FQDNLookup> configuration options (see L<collectd.conf(5)> for details).
 +
 +=item B<$interval_g>
 +
 +This variable keeps the interval in seconds in which the read functions are
 +queried (see the B<Interval> configuration option).
 +
 +=back
 +
 +Any changes to these variables will be globally visible in collectd.
 +
  =head1 EXPORTS
  
  By default no symbols are exported. However, the following export tags are
@@@ -349,16 -320,6 +349,16 @@@ available (B<:all> will export all of t
  
  =back
  
 +=item B<:globals>
 +
 +=over 4
 +
 +=item B<$hostname_g>
 +
 +=item B<$interval_g>
 +
 +=back
 +
  =back
  
  =head1 EXAMPLES
@@@ -395,44 -356,18 +395,44 @@@ A very simple write function will look 
  
  To register those functions with collectd:
  
 -  plugin_register (TYPE_READ, "foobar", \&foobar_read);
 -  plugin_register (TYPE_WRITE, "foobar", \&foobar_write);
 +  plugin_register (TYPE_READ, "foobar", "foobar_read");
 +  plugin_register (TYPE_WRITE, "foobar", "foobar_write");
  
  See the section "DATA TYPES" above for a complete documentation of the data
  types used by the read and write functions.
  
 -=head1 BUGS
 +=head1 CAVEATS
 +
 +=over 4
 +
 +=item
  
 -This plugin does not yet work correctly if collectd uses multiple threads.
 -Perl does not allow multiple threads to access a single interpreter at the
 -same time. As a temporary workaround you should use a single read thread only
 -(see collectd's B<ReadThread> configuration option).
 +collectd is heavily multi-threaded. Each collectd thread accessing the perl
 +plugin will be mapped to a Perl interpreter thread (see L<threads(3perl)>).
 +Any such thread will be created and destroyed transparently and on-the-fly.
 +
 +Hence, any plugin has to be thread-safe if it provides several entry points
 +from collectd (i.E<nbsp>e. if it registers more than one callback). Please
 +note that no data is shared between threads by default. You have to use the
 +B<threads::shared> module to do so.
 +
 +=item
 +
 +Each function name registered with collectd has to be available before the
 +first thread has been created (i.E<nbsp>e. basically at compile time). This
 +basically means that hacks (yes, I really consider this to be a hack) like
 +C<*foo = \&bar; plugin_register (TYPE_READ, "plugin", "foo");> most likely
 +will not work. This is due to the fact that the symbol table is not shared
 +across different threads.
 +
 +=item
 +
 +Each plugin is usually only loaded once and kept in memory for performance
 +reasons. Therefore, END blocks are only executed once when collectd shuts
 +down. You should not rely on END blocks anyway - use B<shutdown functions>
 +instead.
 +
 +=back
  
  =head1 SEE ALSO
  
@@@ -440,8 -375,6 +440,8 @@@ L<collectd(1)>
  L<collectd.conf(5)>,
  L<collectd-exec(5)>,
  L<perl(1)>,
 +L<threads(3perl)>,
 +L<threads::shared(3perl)>,
  L<perldebug(1)>
  
  =head1 AUTHOR
diff --combined src/collectd.conf.pod
@@@ -32,6 -32,10 +32,10 @@@ ignored. Values are either string, encl
  B<false>. String containing of only alphanumeric characters and underscores do
  not need to be quoted.
  
+ Plugins are loaded in the order listed in this config file. It is a good idea
+ to load any logging plugins first in order to catch messages from plugins
+ during configuration.
  =head1 GLOBAL OPTIONS
  
  =over 4
@@@ -73,33 -77,16 +77,33 @@@ Set the file that contains the data-se
  =item B<Interval> I<Seconds>
  
  Configures the interval in which to query the read plugins. Obviously smaller
 -values lead to a higher system load produces by collectd, while higher values
 +values lead to a higher system load produced by collectd, while higher values
  lead to more coarse statistics.
  
  =item B<ReadThreads> I<Num>
  
 -Number of threads to start for reading plugins. The default value if B<5>, but
 +Number of threads to start for reading plugins. The default value is B<5>, but
  you may want to increase this if you have more than five plugins that take a
  long time to read. Mostly those are plugin that do network-IO. Setting this to
  a value higher than the number of plugins you've loaded is totally useless.
  
 +=item B<Hostname> I<Name>
 +
 +Sets the hostname that identifies a host. If you omit this setting, the
 +hostname will be determinded using the L<gethostname(2)> system call.
 +
 +=item B<FQDNLookup> B<true|false>
 +
 +If B<Hostname> is determined automatically this setting controls whether or not
 +the daemon should try to figure out the "fully qualified domain name", FQDN.
 +This is done using a lookup of the name returned by C<gethostname>.
 +
 +Using this feature (i.E<nbsp>e. setting this option to B<true>) is recommended.
 +However, to preserve backwards compatibility the default is set to B<false>.
 +The sample config file that is installed with C<makeE<nbsp>install> includes a
 +line which sets this option, though, so that default installations will have
 +this setting enabled.
 +
  =back
  
  =head1 PLUGIN OPTIONS
@@@ -192,12 -179,6 +196,12 @@@ installed and an "cpu governor" (that'
  Set the directory to store CSV-files under. Per default CSV-files are generated
  beneath the daemon's working directory, i.E<nbsp>e. the B<BaseDir>.
  
 +=item B<StoreRates> B<true|false>
 +
 +If set to B<true>, convert counter values to rates. If set to B<false> (the
 +default) counter values are stored as is, i.E<nbsp>e. as an increasing integer
 +number.
 +
  =back
  
  =head2 Plugin C<df>
@@@ -252,7 -233,7 +256,7 @@@ Sets the socket-file which is to be cre
  
  =item B<SocketGroup> I<Group>
  
- If running as root change the group of the UNIX-socket after it has been 
+ If running as root change the group of the UNIX-socket after it has been
  created. Defaults to B<collectd>.
  
  =item B<SocketPerms> I<Permissions>
@@@ -378,82 -359,6 +382,82 @@@ and all other interrupts are collected
  
  =back
  
 +=head2 Plugin C<libvirt>
 +
 +This plugin allows CPU, disk and network load to be collected for virtualized
 +guests on the machine. This means that these characteristics can be collected
 +for guest systems without installing any software on them - collectd only runs
 +on the hosting system. The statistics are collected through libvirt
 +(L<http://libvirt.org/>).
 +
 +Only I<Connection> is required.
 +
 +=over 4
 +
 +=item B<Connection> I<uri>
 +
 +Connect to the hypervisor given by I<uri>. For example if using Xen use:
 +
 + Connection "xen:///"
 +
 +Details which URIs allowed are given at L<http://libvirt.org/uri.html>.
 +
 +=item B<RefreshInterval> I<seconds>
 +
 +Refresh the list of domains and devices every I<seconds>. The default is 60
 +seconds. Setting this to be the same or smaller than the I<Interval> will cause
 +the list of domains and devices to be refreshed on every iteration.
 +
 +Refreshing the devices in particular is quite a costly operation, so if your
 +virtualization setup is static you might consider increasing this.
 +
 +=item B<Domain> I<name>
 +
 +=item B<BlockDevice> I<name:dev>
 +
 +=item B<InterfaceDevice> I<name:dev>
 +
 +=item B<IgnoreSelected> I<true>|I<false>
 +
 +Select which domains and devices are collected.
 +
 +If I<IgnoreSelected> is not given or I<false> then only the listed domains and
 +disk/network devices are collected.
 +
 +If I<IgnoreSelected> is I<true> then the test is reversed and the listed
 +domains and disk/network devices are ignored, while the rest are collected.
 +
 +The domain name and device names may use a regular expression, if the name is
 +surrounded by I</.../> and collectd was compiled with support for regexps.
 +
 +The default is to collect statistics for all domains and all their devices.
 +
 +Example:
 +
 + BlockDevice "/:hdb/"
 + IgnoreSelected "true"
 +
 +Ignore all I<hdb> devices on any domain, but other block devices (eg. I<hda>)
 +will be collected.
 +
 +=item B<HostnameFormat> B<name|uuid|hostname|...>
 +
 +When the libvirt plugin logs data, it sets the hostname of the collected data
 +according to this setting. The default is to use the guest name as provided by
 +the hypervisor, which is equal to setting B<name>.
 +
 +B<uuid> means use the guest's UUID. This is useful if you want to track the
 +same guest across migrations.
 +
 +B<hostname> means to use the global B<Hostname> setting, which is probably not
 +useful on its own because all guests will appear to have the same name.
 +
 +You can also specify combinations of these fields. For example B<name uuid>
 +means to concatenate the guest name and UUID (with a literal colon character
 +between, thus I<"foo:1234-1234-1234-1234">).
 +
 +=back
 +
  =head2 Plugin C<logfile>
  
  =over 4
@@@ -480,7 -385,7 +484,7 @@@ Prefix all lines printed by the curren
  
  The C<mbmon plugin> uses mbmon to retrieve temperature, voltage, etc.
  
 -Be default collectd connects to B<localhost> (127.0.0.1), port B<411/tcp>.  The
 +Be default collectd connects to B<localhost> (127.0.0.1), port B<411/tcp>. The
  B<Host> and B<Port> options can be used to change these values, see below.
  C<mbmon> has to be running to work correctly. If C<mbmon> is not running
  timeouts may appear which may interfere with other statistics..
@@@ -597,7 -502,7 +601,7 @@@ QDiscs and classes are identified by th
  Filters don't necessarily have a handle, therefore the parent's handle is used.
  The notation used in collectd differs from that used in tc(1) in that it
  doesn't skip the major or minor number if it's zero and doesn't print special
 -ids by their name.  So, for example, a qdisc may be identified by
 +ids by their name. So, for example, a qdisc may be identified by
  C<pfifo_fast-1:0> even though the minor number of B<all> qdiscs is zero and
  thus not displayed by tc(1).
  
@@@ -735,13 -640,6 +739,13 @@@ Hostname of the host running B<ntpd>. D
  
  UDP-Port to connect to. Defaults to B<123>.
  
 +=item B<ReverseLookups> B<true>|B<false>
 +
 +Sets wether or not to perform reverse lookups on peers. Since the name or
 +IP-address may be used in a filename it is recommended to disable reverse
 +lookups. The default is to do reverse lookups to preserve backwards
 +compatibility, though.
 +
  =back
  
  =head2 Plugin C<nut>
@@@ -964,7 -862,7 +968,7 @@@ Sets the socket-file which is to be cre
  
  =item B<SocketGroup> I<Group>
  
- If running as root change the group of the UNIX-socket after it has been 
+ If running as root change the group of the UNIX-socket after it has been
  created. Defaults to B<collectd>.
  
  =item B<SocketPerms> I<Permissions>
@@@ -975,47 -873,6 +979,47 @@@ L<chmod(1)>. Defaults to B<0770>
  
  =back
  
 +=head2 Plugin C<uuid>
 +
 +This plugin, if loaded, causes the Hostname to be taken from the machine's
 +UUID. The UUID is a universally unique designation for the machine, usually
 +taken from the machine's BIOS. This is most useful if the machine is running in
 +a virtual environment such as Xen, in which case the UUID is preserved across
 +shutdowns and migration.
 +
 +The following methods are used to find the machine's UUID, in order:
 +
 +=over 4
 +
 +=item
 +
 +Check I</etc/uuid> (or I<UUIDFile>).
 +
 +=item
 +
 +Check for UUID from HAL (L<http://www.freedesktop.org/wiki/Software/hal>) if
 +present.
 +
 +=item
 +
 +Check for UUID from C<dmidecode> / SMBIOS.
 +
 +=item
 +
 +Check for UUID from Xen hypervisor.
 +
 +=back
 +
 +If no UUID can be found then the hostname is not modified.
 +
 +=over 4
 +
 +=item B<UUIDFile> I<Path>
 +
 +Take the UUID from the given file (default I</etc/uuid>).
 +
 +=back
 +
  =head2 Plugin C<vserver>
  
  This plugin doesn't have any options. B<VServer> support is only available for
diff --combined src/logfile.c
@@@ -26,8 -26,6 +26,8 @@@
  
  #include <pthread.h>
  
 +#define DEFAULT_LOGFILE LOCALSTATEDIR"/log/collectd.log"
 +
  #if COLLECT_DEBUG
  static int log_level = LOG_DEBUG;
  #else
@@@ -72,7 -70,7 +72,7 @@@ static int logfile_config (const char *
                sfree (log_file);
                log_file = strdup (value);
        }
-       else if (0 == strcasecmp (key, "File")) {
+       else if (0 == strcasecmp (key, "Timestamp")) {
                if ((strcasecmp (value, "false") == 0)
                                || (strcasecmp (value, "no") == 0)
                                || (strcasecmp (value, "off") == 0))
@@@ -109,12 -107,7 +109,12 @@@ static void logfile_log (int severity, 
  
        pthread_mutex_lock (&file_lock);
  
 -      if ((log_file == NULL) || (strcasecmp (log_file, "stderr") == 0))
 +      if (log_file == NULL)
 +      {
 +              fh = fopen (DEFAULT_LOGFILE, "a");
 +              do_close = 1;
 +      }
 +      else if (strcasecmp (log_file, "stderr") == 0)
                fh = stderr;
        else if (strcasecmp (log_file, "stdout") == 0)
                fh = stdout;
        {
                        char errbuf[1024];
                        fprintf (stderr, "logfile plugin: fopen (%s) failed: %s\n",
 -                                      (log_file == NULL) ? "<null>" : log_file,
 +                                      (log_file == NULL) ? DEFAULT_LOGFILE : log_file,
                                        sstrerror (errno, errbuf, sizeof (errbuf)));
        }
        else
diff --combined src/utils_avltree.c
@@@ -518,7 -518,7 +518,7 @@@ int avl_insert (avl_tree_t *t, void *ke
                if (cmp == 0)
                {
                        free_node (new);
 -                      return (-1);
 +                      return (1);
                }
                else if (cmp < 0)
                {
@@@ -581,13 -581,12 +581,12 @@@ int avl_get (avl_tree_t *t, const void 
  {
        avl_node_t *n;
  
-       assert (value != NULL);
        n = search (t, key);
        if (n == NULL)
                return (-1);
  
-       *value = n->value;
+       if (value != NULL)
+               *value = n->value;
  
        return (0);
  }
diff --combined src/utils_llist.c
@@@ -35,7 -35,6 +35,7 @@@ struct llist_
  {
        llentry_t *head;
        llentry_t *tail;
 +      int size;
  };
  
  /*
@@@ -68,16 -67,22 +68,16 @@@ void llist_destroy (llist_t *l
        free (l);
  }
  
 -llentry_t *llentry_create (const char *key, void *value)
 +llentry_t *llentry_create (char *key, void *value)
  {
        llentry_t *e;
  
        e = (llentry_t *) malloc (sizeof (llentry_t));
 -      if (e == NULL)
 -              return (NULL);
 -
 -      e->key   = strdup (key);
 -      e->value = value;
 -      e->next  = NULL;
 -
 -      if (e->key == NULL)
 +      if (e)
        {
 -              free (e);
 -              return (NULL);
 +              e->key   = key;
 +              e->value = value;
 +              e->next  = NULL;
        }
  
        return (e);
@@@ -85,6 -90,7 +85,6 @@@
  
  void llentry_destroy (llentry_t *e)
  {
 -      free (e->key);
        free (e);
  }
  
@@@ -98,15 -104,15 +98,19 @@@ void llist_append (llist_t *l, llentry_
                l->tail->next = e;
  
        l->tail = e;
 +
 +      ++(l->size);
  }
  
  void llist_prepend (llist_t *l, llentry_t *e)
  {
        e->next = l->head;
        l->head = e;
+       if (l->tail == NULL)
+               l->tail = e;
++
 +      ++(l->size);
  }
  
  void llist_remove (llist_t *l, llentry_t *e)
                l->head = e->next;
        if (l->tail == e)
                l->tail = prev;
 +
 +      --(l->size);
 +}
 +
 +int llist_size (llist_t *l)
 +{
 +      return (l ? l->size : 0);
  }
  
  llentry_t *llist_search (llist_t *l, const char *key)