Merge branch 'collectd-4.6' into collectd-4.7
authorFlorian Forster <octo@leeloo.lan.home.verplant.org>
Thu, 20 Aug 2009 11:52:34 +0000 (13:52 +0200)
committerFlorian Forster <octo@leeloo.lan.home.verplant.org>
Thu, 20 Aug 2009 11:52:34 +0000 (13:52 +0200)
Conflicts:
src/apache.c

1  2 
src/apache.c
src/bind.c
src/collectd.conf.in

diff --combined src/apache.c
@@@ -1,8 -1,7 +1,8 @@@
  /**
   * collectd - src/apache.c
 - * Copyright (C) 2006-2008  Florian octo Forster
 - * Copyright (C) 2007  Florent EppO Monbillard
 + * Copyright (C) 2006-2009  Florian octo Forster
 + * Copyright (C) 2007       Florent EppO Monbillard
 + * Copyright (C) 2009       Amit Gupta
   *
   * 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
@@@ -21,7 -20,6 +21,7 @@@
   *   Florian octo Forster <octo at verplant.org>
   *   Florent EppO Monbillard <eppo at darox.net>
   *   - connections/lighttpd extension
 + *   Amit Gupta <amit.gupta221 at gmail.com>
   **/
  
  #include "collectd.h"
  
  #include <curl/curl.h>
  
 -static char *url         = NULL;
 -static char *user        = NULL;
 -static char *pass        = NULL;
 -static char *verify_peer = NULL;
 -static char *verify_host = NULL;
 -static char *cacert      = NULL;
 -
 -static CURL *curl = NULL;
 -
 -static char  *apache_buffer = NULL;
 -static size_t apache_buffer_size = 0;
 -static size_t apache_buffer_fill = 0;
 -static char   apache_curl_error[CURL_ERROR_SIZE];
 -
 -static const char *config_keys[] =
 +enum server_enum
  {
 -      "URL",
 -      "User",
 -      "Password",
 -      "VerifyPeer",
 -      "VerifyHost",
 -      "CACert"
 +      APACHE = 0,
 +      LIGHTTPD
  };
 -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys);
 +
 +struct apache_s
 +{
 +      int server_type;
 +      char *name;
 +      char *host;
 +      char *url;
 +      char *user;
 +      char *pass;
 +      int   verify_peer;
 +      int   verify_host;
 +      char *cacert;
 +      char *server; /* user specific server type */
 +      char *apache_buffer;
 +      char apache_curl_error[CURL_ERROR_SIZE];
 +      size_t apache_buffer_size;
 +      size_t apache_buffer_fill;
 +      CURL *curl;
 +}; /* apache_s */
 +
 +typedef struct apache_s apache_t;
 +
 +/* TODO: Remove this prototype */
 +static int apache_read_host (user_data_t *user_data);
 +
 +static void apache_free (apache_t *st)
 +{
 +      if (st == NULL)
 +              return;
 +
 +      sfree (st->name);
 +      sfree (st->host);
 +      sfree (st->url);
 +      sfree (st->user);
 +      sfree (st->pass);
 +      sfree (st->cacert);
 +      sfree (st->server);
 +      sfree (st->apache_buffer);
 +      if (st->curl) {
 +              curl_easy_cleanup(st->curl);
 +              st->curl = NULL;
 +      }
 +} /* apache_free */
  
  static size_t apache_curl_callback (void *buf, size_t size, size_t nmemb,
 -              void __attribute__((unused)) *stream)
 +              void *user_data)
  {
        size_t len = size * nmemb;
 +      apache_t *st;
 +
 +      st = user_data;
 +      if (st == NULL)
 +      {
 +              ERROR ("apache plugin: apache_curl_callback: "
 +                              "user_data pointer is NULL.");
 +              return (0);
 +      }
  
        if (len <= 0)
                return (len);
  
 -      if ((apache_buffer_fill + len) >= apache_buffer_size)
 +      if ((st->apache_buffer_fill + len) >= st->apache_buffer_size)
        {
                char *temp;
  
 -              temp = (char *) realloc (apache_buffer,
 -                              apache_buffer_fill + len + 1);
 +              temp = (char *) realloc (st->apache_buffer,
 +                              st->apache_buffer_fill + len + 1);
                if (temp == NULL)
                {
                        ERROR ("apache plugin: realloc failed.");
                        return (0);
                }
 -              apache_buffer = temp;
 -              apache_buffer_size = apache_buffer_fill + len + 1;
 +              st->apache_buffer = temp;
 +              st->apache_buffer_size = st->apache_buffer_fill + len + 1;
        }
  
 -      memcpy (apache_buffer + apache_buffer_fill, (char *) buf, len);
 -      apache_buffer_fill += len;
 -      apache_buffer[apache_buffer_fill] = 0;
 +      memcpy (st->apache_buffer + st->apache_buffer_fill, (char *) buf, len);
 +      st->apache_buffer_fill += len;
 +      st->apache_buffer[st->apache_buffer_fill] = 0;
  
        return (len);
 -}
 +} /* int apache_curl_callback */
  
 -static int config_set (char **var, const char *value)
 +static size_t apache_header_callback (void *buf, size_t size, size_t nmemb,
 +              void *user_data)
  {
 -      if (*var != NULL)
 +      size_t len = size * nmemb;
 +      apache_t *st;
 +
 +      st = user_data;
 +      if (st == NULL)
        {
 -              free (*var);
 -              *var = NULL;
 +              ERROR ("apache plugin: apache_header_callback: "
 +                              "user_data pointer is NULL.");
 +              return (0);
        }
  
 -      if ((*var = strdup (value)) == NULL)
 -              return (1);
 +      if (len <= 0)
 +              return (len);
 +
 +      /* look for the Server header */
 +      if (strncasecmp (buf, "Server: ", strlen ("Server: ")) != 0)
 +              return (len);
 +
 +      if (strstr (buf, "Apache") != NULL)
 +              st->server_type = APACHE;
 +      else if (strstr (buf, "lighttpd") != NULL)
 +              st->server_type = LIGHTTPD;
        else
 -              return (0);
 -}
 +      {
 +              const char *hdr = buf;
 +
 +              hdr += strlen ("Server: ");
 +              NOTICE ("apache plugin: Unknown server software: %s", hdr);
 +      }
  
 -static int config (const char *key, const char *value)
 +      return (len);
 +} /* apache_header_callback */
 +
 +/* Configuration handling functiions
 + * <Plugin apache>
 + *   <Instance "instance_name">
 + *     URL ...
 + *   </Instance>
 + *   URL ...
 + * </Plugin>
 + */
 +static int config_set_string (char **ret_string, /* {{{ */
 +                                  oconfig_item_t *ci)
  {
 -      if (strcasecmp (key, "url") == 0)
 -              return (config_set (&url, value));
 -      else if (strcasecmp (key, "user") == 0)
 -              return (config_set (&user, value));
 -      else if (strcasecmp (key, "password") == 0)
 -              return (config_set (&pass, value));
 -      else if (strcasecmp (key, "verifypeer") == 0)
 -              return (config_set (&verify_peer, value));
 -      else if (strcasecmp (key, "verifyhost") == 0)
 -              return (config_set (&verify_host, value));
 -      else if (strcasecmp (key, "cacert") == 0)
 -              return (config_set (&cacert, value));
 -      else
 +      char *string;
 +
 +      if ((ci->values_num != 1)
 +                      || (ci->values[0].type != OCONFIG_TYPE_STRING))
 +      {
 +              WARNING ("apache plugin: The `%s' config option "
 +                              "needs exactly one string argument.", ci->key);
                return (-1);
 -}
 +      }
 +
 +      string = strdup (ci->values[0].value.string);
 +      if (string == NULL)
 +      {
 +              ERROR ("apache plugin: strdup failed.");
 +              return (-1);
 +      }
 +
 +      if (*ret_string != NULL)
 +              free (*ret_string);
 +      *ret_string = string;
 +
 +      return (0);
 +} /* }}} int config_set_string */
  
 -static int init (void)
 +static int config_set_boolean (int *ret_boolean, /* {{{ */
 +                                  oconfig_item_t *ci)
  {
 -      static char credentials[1024];
 +      if ((ci->values_num != 1)
 +                      || ((ci->values[0].type != OCONFIG_TYPE_BOOLEAN)
 +                              && (ci->values[0].type != OCONFIG_TYPE_STRING)))
 +      {
 +              WARNING ("apache plugin: The `%s' config option "
 +                              "needs exactly one boolean argument.", ci->key);
 +              return (-1);
 +      }
  
 -      if (url == NULL)
 +      if (ci->values[0].type != OCONFIG_TYPE_BOOLEAN)
 +      {
 +              if (ci->values[0].value.boolean)
 +                      *ret_boolean = 1;
 +              else
 +                      *ret_boolean = 0;
 +      }
 +      else /* if (ci->values[0].type != OCONFIG_TYPE_STRING) */
        {
 -              WARNING ("apache plugin: init: No URL configured, returning "
 -                              "an error.");
 +              char *string = ci->values[0].value.string;
 +              if ((strcasecmp ("true", string) == 0)
 +                              || (strcasecmp ("yes", string) == 0)
 +                              || (strcasecmp ("on", string) == 0))
 +                      *ret_boolean = 1;
 +              else if ((strcasecmp ("false", string) == 0)
 +                              || (strcasecmp ("no", string) == 0)
 +                              || (strcasecmp ("off", string) == 0))
 +                      *ret_boolean = 0;
 +              else
 +              {
 +                      ERROR ("apache plugin: Cannot parse string "
 +                                      "as boolean value: %s", string);
 +                      return (-1);
 +              }
 +      }
 +
 +      return (0);
 +} /* }}} int config_set_boolean */
 +
 +static int config_add (oconfig_item_t *ci)
 +{
 +      apache_t *st;
 +      int i;
 +      int status;
 +
 +      if ((ci->values_num != 1)
 +              || (ci->values[0].type != OCONFIG_TYPE_STRING))
 +      {
 +              WARNING ("apache plugin: The `%s' config option "
 +                      "needs exactly one string argument.", ci->key);
                return (-1);
        }
  
 -      if (curl != NULL)
 +      st = (apache_t *) malloc (sizeof (*st));
 +      if (st == NULL)
        {
 -              curl_easy_cleanup (curl);
 +              ERROR ("apache plugin: malloc failed.");
 +              return (-1);
        }
  
 -      if ((curl = curl_easy_init ()) == NULL)
 +      memset (st, 0, sizeof (*st));
 +
 +      status = config_set_string (&st->name, ci);
 +      if (status != 0)
        {
 -              ERROR ("apache plugin: init: `curl_easy_init' failed.");
 +              sfree (st);
 +              return (status);
 +      }
 +      assert (st->name != NULL);
 +
 +      for (i = 0; i < ci->children_num; i++)
 +      {
 +              oconfig_item_t *child = ci->children + i;
 +
 +              if (strcasecmp ("URL", child->key) == 0)
 +                      status = config_set_string (&st->url, child);
 +              else if (strcasecmp ("Host", child->key) == 0)
 +                      status = config_set_string (&st->host, child);
 +              else if (strcasecmp ("User", child->key) == 0)
 +                      status = config_set_string (&st->user, child);
 +              else if (strcasecmp ("Password", child->key) == 0)
 +                      status = config_set_string (&st->pass, child);
 +              else if (strcasecmp ("VerifyPeer", child->key) == 0)
 +                      status = config_set_boolean (&st->verify_peer, child);
 +              else if (strcasecmp ("VerifyHost", child->key) == 0)
 +                      status = config_set_boolean (&st->verify_host, child);
 +              else if (strcasecmp ("CACert", child->key) == 0)
 +                      status = config_set_string (&st->cacert, child);
 +              else if (strcasecmp ("Server", child->key) == 0)
 +                      status = config_set_string (&st->server, child);
 +              else
 +              {
 +                      WARNING ("apache plugin: Option `%s' not allowed here.",
 +                                      child->key);
 +                      status = -1;
 +              }
 +
 +              if (status != 0)
 +                      break;
 +      }
 +
 +      /* Check if struct is complete.. */
 +      if ((status == 0) && (st->url == NULL))
 +      {
 +              ERROR ("apache plugin: Instance `%s': "
 +                              "No URL has been configured.",
 +                              st->name);
 +              status = -1;
 +      }
 +
 +      if (status == 0)
 +      {
 +              user_data_t ud;
 +              char callback_name[3*DATA_MAX_NAME_LEN];
 +
 +              memset (&ud, 0, sizeof (ud));
 +              ud.data = st;
 +              ud.free_func = (void *) apache_free;
 +
 +              memset (callback_name, 0, sizeof (callback_name));
 +              ssnprintf (callback_name, sizeof (callback_name),
 +                              "apache/%s/%s",
 +                              (st->host != NULL) ? st->host : hostname_g,
 +                              (st->name != NULL) ? st->name : "default"),
 +
 +              status = plugin_register_complex_read (callback_name,
 +                              /* callback  = */ apache_read_host,
 +                              /* interval  = */ NULL,
 +                              /* user_data = */ &ud);
 +      }
 +
 +      if (status != 0)
 +      {
 +              apache_free(st);
                return (-1);
        }
  
 -      curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, apache_curl_callback);
 -      curl_easy_setopt (curl, CURLOPT_USERAGENT, PACKAGE_NAME"/"PACKAGE_VERSION);
 -      curl_easy_setopt (curl, CURLOPT_ERRORBUFFER, apache_curl_error);
 +      return (0);
 +} /* int config_add */
  
 -      if (user != NULL)
 +static int config (oconfig_item_t *ci)
 +{
 +      int status = 0;
 +      int i;
 +      oconfig_item_t *lci = NULL; /* legacy config */
 +
 +      for (i = 0; i < ci->children_num; i++)
 +      {
 +              oconfig_item_t *child = ci->children + i;
 +
 +              if (strcasecmp ("Instance", child->key) == 0 && child->children_num > 0)
 +                      config_add (child);
 +              else
 +              {
 +                      /* legacy mode - convert to <Instance ...> config */
 +                      if (lci == NULL)
 +                      {
 +                              lci = malloc (sizeof(*lci));
 +                              if (lci == NULL)
 +                              {
 +                                      ERROR ("apache plugin: malloc failed.");
 +                                      return (-1);
 +                              }
 +                              memset (lci, '\0', sizeof (*lci));
 +                      }
 +
 +                      lci->children_num++;
 +                      lci->children =
 +                              realloc (lci->children,
 +                                       lci->children_num * sizeof (*child));
 +                      if (lci->children == NULL)
 +                      {
 +                              ERROR ("apache plugin: realloc failed.");
 +                              return (-1);
 +                      }
 +                      memcpy (&lci->children[lci->children_num-1], child, sizeof (*child));
 +              }
 +      } /* for (ci->children) */
 +
 +      if (lci)
 +      {
 +              /* create a <Instance ""> entry */
 +              lci->key = "Instance";
 +              lci->values_num = 1;
 +              lci->values = (oconfig_value_t *) malloc (lci->values_num * sizeof (oconfig_value_t));
 +              lci->values[0].type = OCONFIG_TYPE_STRING;
 +              lci->values[0].value.string = "";
 +
 +              status = config_add (lci);
 +              sfree (lci->values);
 +              sfree (lci->children);
 +              sfree (lci);
 +      }
 +
 +      return status;
 +} /* int config */
 +
 +/* initialize curl for each host */
 +static int init_host (apache_t *st) /* {{{ */
 +{
 +      static char credentials[1024];
 +
 +      assert (st->url != NULL);
 +      /* (Assured by `config_add') */
 +
 +      if (st->curl != NULL)
 +      {
 +              curl_easy_cleanup (st->curl);
 +              st->curl = NULL;
 +      }
 +
 +      if ((st->curl = curl_easy_init ()) == NULL)
 +      {
 +              ERROR ("apache plugin: init_host: `curl_easy_init' failed.");
 +              return (-1);
 +      }
 +
 +      curl_easy_setopt (st->curl, CURLOPT_WRITEFUNCTION, apache_curl_callback);
 +      curl_easy_setopt (st->curl, CURLOPT_WRITEDATA, st);
 +
 +      /* not set as yet if the user specified string doesn't match apache or
 +       * lighttpd, then ignore it. Headers will be parsed to find out the
 +       * server type */
 +      st->server_type = -1;
 +
 +      if (st->server != NULL)
 +      {
 +              if (strcasecmp(st->server, "apache") == 0)
 +                      st->server_type = APACHE;
 +              else if (strcasecmp(st->server, "lighttpd") == 0)
 +                      st->server_type = LIGHTTPD;
 +              else
 +                      WARNING ("apache plugin: Unknown `Server' setting: %s",
 +                                      st->server);
 +      }
 +
 +      /* if not found register a header callback to determine the server_type */
 +      if (st->server_type == -1)
 +      {
 +              curl_easy_setopt (st->curl, CURLOPT_HEADERFUNCTION, apache_header_callback);
 +              curl_easy_setopt (st->curl, CURLOPT_WRITEHEADER, st);
 +      }
 +
 +      curl_easy_setopt (st->curl, CURLOPT_USERAGENT, PACKAGE_NAME"/"PACKAGE_VERSION);
 +      curl_easy_setopt (st->curl, CURLOPT_ERRORBUFFER, st->apache_curl_error);
 +
 +      if (st->user != NULL)
        {
                int status;
  
                status = ssnprintf (credentials, sizeof (credentials), "%s:%s",
 -                              user, (pass == NULL) ? "" : pass);
 +                              st->user, (st->pass == NULL) ? "" : st->pass);
                if ((status < 0) || ((size_t) status >= sizeof (credentials)))
                {
 -                      ERROR ("apache plugin: init: Returning an error "
 +                      ERROR ("apache plugin: init_host: Returning an error "
                                        "because the credentials have been "
                                        "truncated.");
 +                      curl_easy_cleanup (st->curl);
 +                      st->curl = NULL;
                        return (-1);
                }
  
 -              curl_easy_setopt (curl, CURLOPT_USERPWD, credentials);
 +              curl_easy_setopt (st->curl, CURLOPT_USERPWD, credentials);
        }
  
 -      curl_easy_setopt (curl, CURLOPT_URL, url);
 -      curl_easy_setopt (curl, CURLOPT_FOLLOWLOCATION, 1);
 +      curl_easy_setopt (st->curl, CURLOPT_URL, st->url);
++      curl_easy_setopt (st->curl, CURLOPT_FOLLOWLOCATION, 1);
  
 -      if ((verify_peer == NULL) || (strcmp (verify_peer, "true") == 0))
 +      if (st->verify_peer != 0)
        {
 -              curl_easy_setopt (curl, CURLOPT_SSL_VERIFYPEER, 1);
 +              curl_easy_setopt (st->curl, CURLOPT_SSL_VERIFYPEER, 1);
        }
        else
        {
 -              curl_easy_setopt (curl, CURLOPT_SSL_VERIFYPEER, 0);
 +              curl_easy_setopt (st->curl, CURLOPT_SSL_VERIFYPEER, 0);
        }
  
 -      if ((verify_host == NULL) || (strcmp (verify_host, "true") == 0))
 +      if (st->verify_host != 0)
        {
 -              curl_easy_setopt (curl, CURLOPT_SSL_VERIFYHOST, 2);
 +              curl_easy_setopt (st->curl, CURLOPT_SSL_VERIFYHOST, 2);
        }
        else
        {
 -              curl_easy_setopt (curl, CURLOPT_SSL_VERIFYHOST, 0);
 +              curl_easy_setopt (st->curl, CURLOPT_SSL_VERIFYHOST, 0);
        }
  
 -      if (cacert != NULL)
 +      if (st->cacert != NULL)
        {
 -              curl_easy_setopt (curl, CURLOPT_CAINFO, cacert);
 +              curl_easy_setopt (st->curl, CURLOPT_CAINFO, st->cacert);
        }
  
        return (0);
 -} /* int init */
 +} /* }}} int init_host */
  
 -static void submit_counter (const char *type, const char *type_instance,
 -              counter_t value)
 +static void submit_value (const char *type, const char *type_instance,
 +              value_t value, apache_t *st)
  {
 -      value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
  
 -      values[0].counter = value;
 -
 -      vl.values = values;
 +      vl.values = &value;
        vl.values_len = 1;
 -      sstrncpy (vl.host, hostname_g, sizeof (vl.host));
 +
 +      sstrncpy (vl.host, (st->host != NULL) ? st->host : hostname_g,
 +                      sizeof (vl.host));
 +
        sstrncpy (vl.plugin, "apache", sizeof (vl.plugin));
 -      sstrncpy (vl.plugin_instance, "", sizeof (vl.plugin_instance));
 -      sstrncpy (vl.type, type, sizeof (vl.type));
 +      if (st->name != NULL)
 +              sstrncpy (vl.plugin_instance, st->name,
 +                              sizeof (vl.plugin_instance));
  
 +      sstrncpy (vl.type, type, sizeof (vl.type));
        if (type_instance != NULL)
                sstrncpy (vl.type_instance, type_instance,
                                sizeof (vl.type_instance));
  
        plugin_dispatch_values (&vl);
 +} /* void submit_value */
 +
 +static void submit_counter (const char *type, const char *type_instance,
 +              counter_t c, apache_t *st)
 +{
 +      value_t v;
 +      v.counter = c;
 +      submit_value (type, type_instance, v, st);
  } /* void submit_counter */
  
  static void submit_gauge (const char *type, const char *type_instance,
 -              gauge_t value)
 +              gauge_t g, apache_t *st)
  {
 -      value_t values[1];
 -      value_list_t vl = VALUE_LIST_INIT;
 -
 -      values[0].gauge = value;
 +      value_t v;
 +      v.gauge = g;
 +      submit_value (type, type_instance, v, st);
 +} /* void submit_gauge */
  
 -      vl.values = values;
 -      vl.values_len = 1;
 -      sstrncpy (vl.host, hostname_g, sizeof (vl.host));
 -      sstrncpy (vl.plugin, "apache", sizeof (vl.plugin));
 -      sstrncpy (vl.plugin_instance, "", sizeof (vl.plugin_instance));
 -      sstrncpy (vl.type, type, sizeof (vl.type));
 -
 -      if (type_instance != NULL)
 -              sstrncpy (vl.type_instance, type_instance,
 -                              sizeof (vl.type_instance));
 -
 -      plugin_dispatch_values (&vl);
 -} /* void submit_counter */
 -
 -static void submit_scoreboard (char *buf)
 +static void submit_scoreboard (char *buf, apache_t *st)
  {
        /*
         * Scoreboard Key:
 -       * "_" Waiting for Connection, "S" Starting up, "R" Reading Request,
 +       * "_" Waiting for Connection, "S" Starting up,
 +       * "R" Reading Request for apache and read-POST for lighttpd,
         * "W" Sending Reply, "K" Keepalive (read), "D" DNS Lookup,
         * "C" Closing connection, "L" Logging, "G" Gracefully finishing,
         * "I" Idle cleanup of worker, "." Open slot with no current process
 +       * Lighttpd specific legends -
 +       * "E" hard error, "." connect, "h" handle-request,
 +       * "q" request-start, "Q" request-end, "s" response-start
 +       * "S" response-end, "r" read
         */
        long long open      = 0LL;
        long long waiting   = 0LL;
        long long finishing = 0LL;
        long long idle_cleanup = 0LL;
  
 -      int i;
 +      /* lighttpd specific */
 +      long long hard_error     = 0LL;
 +      long long lighttpd_read  = 0LL;
 +      long long handle_request = 0LL;
 +      long long request_start  = 0LL;
 +      long long request_end    = 0LL;
 +      long long response_start = 0LL;
 +      long long response_end   = 0LL;
  
 +      int i;
        for (i = 0; buf[i] != '\0'; i++)
        {
                if (buf[i] == '.') open++;
                else if (buf[i] == 'L') logging++;
                else if (buf[i] == 'G') finishing++;
                else if (buf[i] == 'I') idle_cleanup++;
 +              else if (buf[i] == 'r') lighttpd_read++;
 +              else if (buf[i] == 'h') handle_request++;
 +              else if (buf[i] == 'E') hard_error++;
 +              else if (buf[i] == 'q') request_start++;
 +              else if (buf[i] == 'Q') request_end++;
 +              else if (buf[i] == 's') response_start++;
 +              else if (buf[i] == 'S') response_end++;
        }
  
 -      submit_gauge ("apache_scoreboard", "open"     , open);
 -      submit_gauge ("apache_scoreboard", "waiting"  , waiting);
 -      submit_gauge ("apache_scoreboard", "starting" , starting);
 -      submit_gauge ("apache_scoreboard", "reading"  , reading);
 -      submit_gauge ("apache_scoreboard", "sending"  , sending);
 -      submit_gauge ("apache_scoreboard", "keepalive", keepalive);
 -      submit_gauge ("apache_scoreboard", "dnslookup", dnslookup);
 -      submit_gauge ("apache_scoreboard", "closing"  , closing);
 -      submit_gauge ("apache_scoreboard", "logging"  , logging);
 -      submit_gauge ("apache_scoreboard", "finishing", finishing);
 -      submit_gauge ("apache_scoreboard", "idle_cleanup", idle_cleanup);
 +      if (st->server_type == APACHE)
 +      {
 +              submit_gauge ("apache_scoreboard", "open"     , open, st);
 +              submit_gauge ("apache_scoreboard", "waiting"  , waiting, st);
 +              submit_gauge ("apache_scoreboard", "starting" , starting, st);
 +              submit_gauge ("apache_scoreboard", "reading"  , reading, st);
 +              submit_gauge ("apache_scoreboard", "sending"  , sending, st);
 +              submit_gauge ("apache_scoreboard", "keepalive", keepalive, st);
 +              submit_gauge ("apache_scoreboard", "dnslookup", dnslookup, st);
 +              submit_gauge ("apache_scoreboard", "closing"  , closing, st);
 +              submit_gauge ("apache_scoreboard", "logging"  , logging, st);
 +              submit_gauge ("apache_scoreboard", "finishing", finishing, st);
 +              submit_gauge ("apache_scoreboard", "idle_cleanup", idle_cleanup, st);
 +      }
 +      else
 +      {
 +              submit_gauge ("apache_scoreboard", "connect"       , open, st);
 +              submit_gauge ("apache_scoreboard", "close"         , closing, st);
 +              submit_gauge ("apache_scoreboard", "hard_error"    , hard_error, st);
 +              submit_gauge ("apache_scoreboard", "read"          , lighttpd_read, st);
 +              submit_gauge ("apache_scoreboard", "read_post"     , reading, st);
 +              submit_gauge ("apache_scoreboard", "write"         , sending, st);
 +              submit_gauge ("apache_scoreboard", "handle_request", handle_request, st);
 +              submit_gauge ("apache_scoreboard", "request_start" , request_start, st);
 +              submit_gauge ("apache_scoreboard", "request_end"   , request_end, st);
 +              submit_gauge ("apache_scoreboard", "response_start", response_start, st);
 +              submit_gauge ("apache_scoreboard", "response_end"  , response_end, st);
 +      }
  }
  
 -static int apache_read (void)
 +static int apache_read_host (user_data_t *user_data) /* {{{ */
  {
        int i;
  
        char *fields[4];
        int   fields_num;
  
 -      if (curl == NULL)
 -              return (-1);
 -      if (url == NULL)
 -              return (-1);
 +      apache_t *st;
 +
 +      st = user_data->data;
 +
 +      assert (st->url != NULL);
 +      /* (Assured by `config_add') */
 +
 +      if (st->curl == NULL)
 +      {
 +              int status;
 +
 +              status = init_host (st);
 +              if (status != 0)
 +                      return (-1);
 +      }
 +      assert (st->curl != NULL);
  
 -      apache_buffer_fill = 0;
 -      if (curl_easy_perform (curl) != 0)
 +      st->apache_buffer_fill = 0;
 +      if (curl_easy_perform (st->curl) != 0)
        {
                ERROR ("apache: curl_easy_perform failed: %s",
 -                              apache_curl_error);
 +                              st->apache_curl_error);
                return (-1);
        }
  
 -      ptr = apache_buffer;
 +      /* fallback - server_type to apache if not set at this time */
 +      if (st->server_type == -1)
 +      {
 +              WARNING ("apache plugin: Unable to determine server software "
 +                              "automatically. Will assume Apache.");
 +              st->server_type = APACHE;
 +      }
 +
 +      ptr = st->apache_buffer;
        saveptr = NULL;
        while ((lines[lines_num] = strtok_r (ptr, "\n\r", &saveptr)) != NULL)
        {
                        if ((strcmp (fields[0], "Total") == 0)
                                        && (strcmp (fields[1], "Accesses:") == 0))
                                submit_counter ("apache_requests", "",
 -                                              atoll (fields[2]));
 +                                              atoll (fields[2]), st);
                        else if ((strcmp (fields[0], "Total") == 0)
                                        && (strcmp (fields[1], "kBytes:") == 0))
                                submit_counter ("apache_bytes", "",
 -                                              1024LL * atoll (fields[2]));
 +                                              1024LL * atoll (fields[2]), st);
                }
                else if (fields_num == 2)
                {
                        if (strcmp (fields[0], "Scoreboard:") == 0)
 -                              submit_scoreboard (fields[1]);
 +                              submit_scoreboard (fields[1], st);
                        else if (strcmp (fields[0], "BusyServers:") == 0)
 -                              submit_gauge ("apache_connections", NULL, atol (fields[1]));
 +                              submit_gauge ("apache_connections", NULL, atol (fields[1]), st);
                }
        }
  
 -      apache_buffer_fill = 0;
 +      st->apache_buffer_fill = 0;
  
        return (0);
 -} /* int apache_read */
 +} /* }}} int apache_read_host */
  
  void module_register (void)
  {
 -      plugin_register_config ("apache", config,
 -                      config_keys, config_keys_num);
 -      plugin_register_init ("apache", init);
 -      plugin_register_read ("apache", apache_read);
 +      plugin_register_complex_config ("apache", config);
  } /* void module_register */
 +
 +/* vim: set sw=8 noet fdm=marker : */
diff --combined src/bind.c
@@@ -227,6 -227,19 +227,6 @@@ static int memsummary_translation_table
    STATIC_ARRAY_SIZE (memsummary_translation_table);
  /* }}} */
  
 -static void remove_special (char *buffer, size_t buffer_size) /* {{{ */
 -{
 -  size_t i;
 -
 -  for (i = 0; i < buffer_size; i++)
 -  {
 -    if (buffer[i] == 0)
 -      return;
 -    if ((!isalnum ((int) buffer[i])) && (buffer[i] != '-'))
 -      buffer[i] = '_';
 -  }
 -} /* }}} void remove_special */
 -
  static void submit (time_t ts, const char *plugin_instance, /* {{{ */
      const char *type, const char *type_instance, value_t value)
  {
    if (plugin_instance) {
      sstrncpy(vl.plugin_instance, plugin_instance,
          sizeof(vl.plugin_instance));
 -    remove_special (vl.plugin_instance, sizeof (vl.plugin_instance));
 +    replace_special (vl.plugin_instance, sizeof (vl.plugin_instance));
    }
    sstrncpy(vl.type, type, sizeof(vl.type));
    if (type_instance) {
      sstrncpy(vl.type_instance, type_instance,
          sizeof(vl.type_instance));
 -    remove_special (vl.plugin_instance, sizeof (vl.plugin_instance));
 +    replace_special (vl.plugin_instance, sizeof (vl.plugin_instance));
    }
    plugin_dispatch_values(&vl);
  } /* }}} void submit */
@@@ -1382,6 -1395,7 +1382,7 @@@ static int bind_init (void) /* {{{ *
    curl_easy_setopt (curl, CURLOPT_USERAGENT, PACKAGE_NAME"/"PACKAGE_VERSION);
    curl_easy_setopt (curl, CURLOPT_ERRORBUFFER, bind_curl_error);
    curl_easy_setopt (curl, CURLOPT_URL, (url != NULL) ? url : BIND_DEFAULT_URL);
+   curl_easy_setopt (curl, CURLOPT_FOLLOWLOCATION, 1);
  
    return (0);
  } /* }}} int bind_init */
diff --combined src/collectd.conf.in
@@@ -4,12 -4,6 +4,12 @@@
  # http://collectd.org/
  #
  
 +##############################################################################
 +# Global                                                                     #
 +#----------------------------------------------------------------------------#
 +# Global settings for the daemon.                                            #
 +##############################################################################
 +
  #Hostname    "localhost"
  FQDNLookup   true
  #BaseDir     "@prefix@/var/lib/@PACKAGE_NAME@"
  #Interval     10
  #ReadThreads  5
  
 -@BUILD_PLUGIN_LOGFILE_TRUE@LoadPlugin logfile
 -@BUILD_PLUGIN_SYSLOG_TRUE@LoadPlugin syslog
 +##############################################################################
 +# Logging                                                                    #
 +#----------------------------------------------------------------------------#
 +# Plugins which provide logging functions should be loaded first, so log     #
 +# messages generated when loading or configuring other plugins can be        #
 +# accessed.                                                                  #
 +##############################################################################
 +
 +@LOAD_PLUGIN_SYSLOG@LoadPlugin syslog
 +@LOAD_PLUGIN_LOGFILE@LoadPlugin logfile
  
  #<Plugin logfile>
 -#     LogLevel info
 +#     LogLevel @DEFAULT_LOG_LEVEL@
  #     File STDOUT
  #     Timestamp true
  #</Plugin>
  
  #<Plugin syslog>
 -#     LogLevel info
 -#</Plugin>
 -
 -@BUILD_PLUGIN_APACHE_TRUE@LoadPlugin apache
 -@BUILD_PLUGIN_APCUPS_TRUE@LoadPlugin apcups
 -@BUILD_PLUGIN_APPLE_SENSORS_TRUE@LoadPlugin apple_sensors
 -@BUILD_PLUGIN_ASCENT_TRUE@LoadPlugin ascent
 -@BUILD_PLUGIN_BATTERY_TRUE@LoadPlugin battery
 -@BUILD_PLUGIN_BIND_TRUE@LoadPlugin bind
 -@BUILD_PLUGIN_CPU_TRUE@LoadPlugin cpu
 -@BUILD_PLUGIN_CPUFREQ_TRUE@LoadPlugin cpufreq
 -@BUILD_PLUGIN_CSV_TRUE@LoadPlugin csv
 -@BUILD_PLUGIN_CURL_TRUE@LoadPlugin curl
 -@BUILD_PLUGIN_DBI_TRUE@LoadPlugin dbi
 -@BUILD_PLUGIN_DF_TRUE@LoadPlugin df
 -@BUILD_PLUGIN_DISK_TRUE@LoadPlugin disk
 -@BUILD_PLUGIN_DNS_TRUE@LoadPlugin dns
 -@BUILD_PLUGIN_EMAIL_TRUE@LoadPlugin email
 -@BUILD_PLUGIN_ENTROPY_TRUE@LoadPlugin entropy
 -@BUILD_PLUGIN_EXEC_TRUE@LoadPlugin exec
 -@BUILD_PLUGIN_FILECOUNT_TRUE@LoadPlugin filecount
 -@BUILD_PLUGIN_HDDTEMP_TRUE@LoadPlugin hddtemp
 -@BUILD_PLUGIN_INTERFACE_TRUE@LoadPlugin interface
 -@BUILD_PLUGIN_IPTABLES_TRUE@LoadPlugin iptables
 -@BUILD_PLUGIN_IPMI_TRUE@LoadPlugin ipmi
 -@BUILD_PLUGIN_IPVS_TRUE@LoadPlugin ipvs
 -@BUILD_PLUGIN_IRQ_TRUE@LoadPlugin irq
 -@BUILD_PLUGIN_LIBVIRT_TRUE@LoadPlugin libvirt
 -@BUILD_PLUGIN_LOAD_TRUE@LoadPlugin load
 -@BUILD_PLUGIN_MBMON_TRUE@LoadPlugin mbmon
 -@BUILD_PLUGIN_MEMCACHED_TRUE@LoadPlugin memcached
 -@BUILD_PLUGIN_MEMORY_TRUE@LoadPlugin memory
 -@BUILD_PLUGIN_MULTIMETER_TRUE@LoadPlugin multimeter
 -@BUILD_PLUGIN_MYSQL_TRUE@LoadPlugin mysql
 -@BUILD_PLUGIN_NETLINK_TRUE@LoadPlugin netlink
 -@BUILD_PLUGIN_NETWORK_TRUE@LoadPlugin network
 -@BUILD_PLUGIN_NFS_TRUE@LoadPlugin nfs
 -@BUILD_PLUGIN_NGINX_TRUE@LoadPlugin nginx
 -@BUILD_PLUGIN_NOTIFY_DESKTOP_TRUE@LoadPlugin notify_desktop
 -@BUILD_PLUGIN_NOTIFY_EMAIL_TRUE@LoadPlugin notify_email
 -@BUILD_PLUGIN_NTPD_TRUE@LoadPlugin ntpd
 -@BUILD_PLUGIN_NUT_TRUE@LoadPlugin nut
 -@BUILD_PLUGIN_ONEWIRE_TRUE@LoadPlugin onewire
 -@BUILD_PLUGIN_OPENVPN_TRUE@LoadPlugin openvpn
 -@BUILD_PLUGIN_ORACLE_TRUE@LoadPlugin oracle
 -@BUILD_PLUGIN_PERL_TRUE@LoadPlugin perl
 -@BUILD_PLUGIN_PING_TRUE@LoadPlugin ping
 -@BUILD_PLUGIN_POSTGRESQL_TRUE@LoadPlugin postgresql
 -@BUILD_PLUGIN_POWERDNS_TRUE@LoadPlugin powerdns
 -@BUILD_PLUGIN_PROCESSES_TRUE@LoadPlugin processes
 -@BUILD_PLUGIN_RRDCACHED_TRUE@LoadPlugin rrdcached
 -@BUILD_PLUGIN_RRDTOOL_TRUE@LoadPlugin rrdtool
 -@BUILD_PLUGIN_SENSORS_TRUE@LoadPlugin sensors
 -@BUILD_PLUGIN_SERIAL_TRUE@LoadPlugin serial
 -@BUILD_PLUGIN_SNMP_TRUE@LoadPlugin snmp
 -@BUILD_PLUGIN_SWAP_TRUE@LoadPlugin swap
 -@BUILD_PLUGIN_TAIL_TRUE@LoadPlugin tail
 -@BUILD_PLUGIN_TAPE_TRUE@LoadPlugin tape
 -@BUILD_PLUGIN_TCPCONNS_TRUE@LoadPlugin tcpconns
 -@BUILD_PLUGIN_TEAMSPEAK2_TRUE@LoadPlugin teamspeak2
 -@BUILD_PLUGIN_THERMAL_TRUE@LoadPlugin thermal
 -@BUILD_PLUGIN_UNIXSOCK_TRUE@LoadPlugin unixsock
 -@BUILD_PLUGIN_USERS_TRUE@LoadPlugin users
 -#LoadPlugin uuid
 -@BUILD_PLUGIN_VMEM_TRUE@LoadPlugin vmem
 -@BUILD_PLUGIN_VSERVER_TRUE@LoadPlugin vserver
 -@BUILD_PLUGIN_WIRELESS_TRUE@LoadPlugin wireless
 -@BUILD_PLUGIN_XMMS_TRUE@LoadPlugin xmms
 +#     LogLevel @DEFAULT_LOG_LEVEL@
 +#</Plugin>
 +
 +##############################################################################
 +# LoadPlugin section                                                         #
 +#----------------------------------------------------------------------------#
 +# Lines beginning with a single `#' belong to plugins which have been built  #
 +# but are disabled by default.                                               #
 +#                                                                            #
 +# Lines begnning with `##' belong to plugins which have not been built due   #
 +# to missing dependencies or because they have been deactivated explicitly.  #
 +##############################################################################
 +
 +#@BUILD_PLUGIN_APACHE_TRUE@LoadPlugin apache
 +#@BUILD_PLUGIN_APCUPS_TRUE@LoadPlugin apcups
 +#@BUILD_PLUGIN_APPLE_SENSORS_TRUE@LoadPlugin apple_sensors
 +#@BUILD_PLUGIN_ASCENT_TRUE@LoadPlugin ascent
 +#@BUILD_PLUGIN_BATTERY_TRUE@LoadPlugin battery
 +#@BUILD_PLUGIN_BIND_TRUE@LoadPlugin bind
 +#@BUILD_PLUGIN_CONNTRACK_TRUE@LoadPlugin conntrack
 +@BUILD_PLUGIN_CPU_TRUE@@BUILD_PLUGIN_CPU_TRUE@LoadPlugin cpu
 +#@BUILD_PLUGIN_CPUFREQ_TRUE@LoadPlugin cpufreq
 +@LOAD_PLUGIN_CSV@LoadPlugin csv
 +#@BUILD_PLUGIN_CURL_TRUE@LoadPlugin curl
 +#@BUILD_PLUGIN_DBI_TRUE@LoadPlugin dbi
 +#@BUILD_PLUGIN_DF_TRUE@LoadPlugin df
 +#@BUILD_PLUGIN_DISK_TRUE@LoadPlugin disk
 +#@BUILD_PLUGIN_DNS_TRUE@LoadPlugin dns
 +#@BUILD_PLUGIN_EMAIL_TRUE@LoadPlugin email
 +#@BUILD_PLUGIN_ENTROPY_TRUE@LoadPlugin entropy
 +#@BUILD_PLUGIN_EXEC_TRUE@LoadPlugin exec
 +#@BUILD_PLUGIN_FILECOUNT_TRUE@LoadPlugin filecount
 +#@BUILD_PLUGIN_FSCACHE_TRUE@LoadPlugin fscache
 +#@BUILD_PLUGIN_GMOND_TRUE@LoadPlugin gmond
 +#@BUILD_PLUGIN_HDDTEMP_TRUE@LoadPlugin hddtemp
 +@BUILD_PLUGIN_INTERFACE_TRUE@@BUILD_PLUGIN_INTERFACE_TRUE@LoadPlugin interface
 +#@BUILD_PLUGIN_IPTABLES_TRUE@LoadPlugin iptables
 +#@BUILD_PLUGIN_IPMI_TRUE@LoadPlugin ipmi
 +#@BUILD_PLUGIN_IPVS_TRUE@LoadPlugin ipvs
 +#@BUILD_PLUGIN_IRQ_TRUE@LoadPlugin irq
 +#@BUILD_PLUGIN_JAVA_TRUE@LoadPlugin java
 +#@BUILD_PLUGIN_LIBVIRT_TRUE@LoadPlugin libvirt
 +@BUILD_PLUGIN_LOAD_TRUE@@BUILD_PLUGIN_LOAD_TRUE@LoadPlugin load
 +#@BUILD_PLUGIN_MBMON_TRUE@LoadPlugin mbmon
 +#@BUILD_PLUGIN_MEMCACHEC_TRUE@LoadPlugin memcachec
 +#@BUILD_PLUGIN_MEMCACHED_TRUE@LoadPlugin memcached
 +@BUILD_PLUGIN_MEMORY_TRUE@@BUILD_PLUGIN_MEMORY_TRUE@LoadPlugin memory
 +#@BUILD_PLUGIN_MULTIMETER_TRUE@LoadPlugin multimeter
 +#@BUILD_PLUGIN_MYSQL_TRUE@LoadPlugin mysql
 +#@BUILD_PLUGIN_NETLINK_TRUE@LoadPlugin netlink
 +@LOAD_PLUGIN_NETWORK@LoadPlugin network
 +#@BUILD_PLUGIN_NFS_TRUE@LoadPlugin nfs
 +#@BUILD_PLUGIN_NGINX_TRUE@LoadPlugin nginx
 +#@BUILD_PLUGIN_NOTIFY_DESKTOP_TRUE@LoadPlugin notify_desktop
 +#@BUILD_PLUGIN_NOTIFY_EMAIL_TRUE@LoadPlugin notify_email
 +#@BUILD_PLUGIN_NTPD_TRUE@LoadPlugin ntpd
 +#@BUILD_PLUGIN_NUT_TRUE@LoadPlugin nut
 +#@BUILD_PLUGIN_ONEWIRE_TRUE@LoadPlugin onewire
 +#@BUILD_PLUGIN_OPENVPN_TRUE@LoadPlugin openvpn
 +#@BUILD_PLUGIN_ORACLE_TRUE@LoadPlugin oracle
 +#@BUILD_PLUGIN_PERL_TRUE@LoadPlugin perl
 +#@BUILD_PLUGIN_PING_TRUE@LoadPlugin ping
 +#@BUILD_PLUGIN_POSTGRESQL_TRUE@LoadPlugin postgresql
 +#@BUILD_PLUGIN_POWERDNS_TRUE@LoadPlugin powerdns
 +#@BUILD_PLUGIN_PROCESSES_TRUE@LoadPlugin processes
 +#@BUILD_PLUGIN_PROTOCOLS_TRUE@LoadPlugin protocols
 +#@BUILD_PLUGIN_RRDCACHED_TRUE@LoadPlugin rrdcached
 +@LOAD_PLUGIN_RRDTOOL@LoadPlugin rrdtool
 +#@BUILD_PLUGIN_SENSORS_TRUE@LoadPlugin sensors
 +#@BUILD_PLUGIN_SERIAL_TRUE@LoadPlugin serial
 +#@BUILD_PLUGIN_SNMP_TRUE@LoadPlugin snmp
 +#@BUILD_PLUGIN_SWAP_TRUE@LoadPlugin swap
 +#@BUILD_PLUGIN_TABLE_TRUE@LoadPlugin table
 +#@BUILD_PLUGIN_TAIL_TRUE@LoadPlugin tail
 +#@BUILD_PLUGIN_TAPE_TRUE@LoadPlugin tape
 +#@BUILD_PLUGIN_TCPCONNS_TRUE@LoadPlugin tcpconns
 +#@BUILD_PLUGIN_TEAMSPEAK2_TRUE@LoadPlugin teamspeak2
 +#@BUILD_PLUGIN_TED_TRUE@LoadPlugin ted
 +#@BUILD_PLUGIN_THERMAL_TRUE@LoadPlugin thermal
 +#@BUILD_PLUGIN_UNIXSOCK_TRUE@LoadPlugin unixsock
 +#@BUILD_PLUGIN_UPTIME_TRUE@LoadPlugin uptime
 +#@BUILD_PLUGIN_USERS_TRUE@LoadPlugin users
 +#@BUILD_PLUGIN_UUID_TRUE@LoadPlugin uuid
 +#@BUILD_PLUGIN_VMEM_TRUE@LoadPlugin vmem
 +#@BUILD_PLUGIN_VSERVER_TRUE@LoadPlugin vserver
 +#@BUILD_PLUGIN_WIRELESS_TRUE@LoadPlugin wireless
 +#@BUILD_PLUGIN_XMMS_TRUE@LoadPlugin xmms
 +
 +##############################################################################
 +# Plugin configuration                                                       #
 +#----------------------------------------------------------------------------#
 +# In this section configuration stubs for each plugin are provided. A desc-  #
 +# ription of those options is available in the collectd.conf(5) manual page. #
 +##############################################################################
  
  #<Plugin apache>
  #     URL "http://localhost/status?auto"
  #     </Directory>
  #</Plugin>
  
 -@BUILD_PLUGIN_HDDTEMP_TRUE@<Plugin hddtemp>
 -#     Host "127.0.0.1"
 -#     Port "7634"
 -@BUILD_PLUGIN_HDDTEMP_TRUE@   TranslateDevicename false
 -@BUILD_PLUGIN_HDDTEMP_TRUE@</Plugin>
 +#<Plugin "gmond">
 +#  MCReceiveFrom "239.2.11.71" "8649"
 +#  <Metric "swap_total">
 +#    Type "swap"
 +#    TypeInstance "total"
 +#    DataSource "value"
 +#  </Metric>
 +#  <Metric "swap_free">
 +#    Type "swap"
 +#    TypeInstance "free"
 +#    DataSource "value"
 +#  </Metric>
 +#</Plugin>
 +
 +#<Plugin hddtemp>
 +#  Host "127.0.0.1"
 +#  Port "7634"
 +#
 +#  #----------------------------------------------------------------#
 +#  # `TranslateDevicename' enables backwards compatibility behavior #
 +#  # and is enabled by default. Setting this option to `false' is   #
 +#  # highly recommended.                                            #
 +#  #----------------------------------------------------------------#
 +#  TranslateDevicename false
 +#</Plugin>
  
  #<Plugin interface>
  #     Interface "eth0"
  #     IgnoreSelected true
  #</Plugin>
  
 +#<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>
 +
  #<Plugin libvirt>
  #     Connection "xen:///"
  #     RefreshInterval 60
  #     Port "411"
  #</Plugin>
  
 +#<Plugin memcachec>
 +#     <Page "plugin_instance">
 +#             Server "localhost"
 +#             Key "page_key"
 +#             <Match>
 +#                     Regex "(\\d+) bytes sent"
 +#                     DSType CounterAdd
 +#                     Type "ipt_octets"
 +#                     Instance "type_instance"
 +#             </Match>
 +#     </Page>
 +#</Plugin>
 +
  #<Plugin memcached>
  #     Host "127.0.0.1"
  #     Port "11211"
  #</Plugin>
  
  #<Plugin mysql>
 -#     Host "database.serv.er"
 -#     User "db_user"
 -#     Password "secret"
 -#     Database "db_name"
 +#     <Database db_name>
 +#             Host "database.serv.er"
 +#             User "db_user"
 +#             Password "secret"
 +#             Database "db_name"
 +#             MasterStats true
 +#     </Database>
 +#
 +#     <Database db_name2>
 +#             Host "localhost"
 +#             Socket "/var/run/mysql/mysqld.sock"
 +#             SlaveStats true
 +#             SlaveNotifications true
 +#     </Database>
  #</Plugin>
  
  #<Plugin netlink>
  #     IgnoreSelected false
  #</Plugin>
  
 -#<Plugin network>
 -#     Server "ff18::efc0:4a42" "25826"
 -#     Server "239.192.74.66" "25826"
 +@LOAD_PLUGIN_NETWORK@<Plugin network>
 +@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"
  #     TimeToLive "128"
  #     Forward false
  #     CacheFlush 1800
 -#</Plugin>
 +@LOAD_PLUGIN_NETWORK@</Plugin>
  
  #<Plugin nginx>
  #     URL "http://localhost/status?auto"
  #     Process "name"
  #</Plugin>
  
 +#<Plugin protocols>
 +#     Value "/^Tcp:/"
 +#     IgnoreSelected false
 +#</Plugin>
 +
  #<Plugin rrdcached>
  #     DaemonAddress "unix:/tmp/rrdcached.sock"
  #     DataDir "@prefix@/var/lib/@PACKAGE_NAME@/rrd"
  #       Instance "IF-MIB::ifDescr"
  #       Values "IF-MIB::ifInOctets" "IF-MIB::ifOutOctets"
  #   </Data>
 -#   
 +#
  #   <Host "some.switch.mydomain.org">
  #       Address "192.168.0.2"
  #       Version 1
  #   </Host>
  #</Plugin>
  
 +#<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>
 +
  #<Plugin "tail">
  #  <File "/var/log/exim4/mainlog">
  #    Instance "exim"
  #     Server "8767"
  #</Plugin>
  
 +#<Plugin ted>
 +#     Device "/dev/ttyUSB0"
 +#     Retries 0
 +#</Plugin>
 +
  #<Plugin thermal>
  #     ForceUseProcfs false
  #     Device "THRM"
  #     Verbose false
  #</Plugin>
  
 -# * * * * * * * * * * * * *
 -# * FILTER CONFIGURATION  *
 -# * * * * * * * * * * * * *
 -
 -# The following configures collectd's filtering mechanism. Before changing
 -# anything in this section, please read the `FILTER CONFIGURATION' section in
 -# the collectd.conf(5) manual page.
 +##############################################################################
 +# Filter configuration                                                       #
 +#----------------------------------------------------------------------------#
 +# The following configures collectd's filtering mechanism. Before changing   #
 +# anything in this section, please read the `FILTER CONFIGURATION' section   #
 +# in the collectd.conf(5) manual page.                                       #
 +##############################################################################
  
  # Load required matches:
  #@BUILD_PLUGIN_MATCH_REGEX_TRUE@LoadPlugin match_regex
  #@BUILD_PLUGIN_TARGET_NOTIFICATION_TRUE@LoadPlugin target_notification
  #@BUILD_PLUGIN_TARGET_REPLACE_TRUE@LoadPlugin target_replace
  #@BUILD_PLUGIN_TARGET_SET_TRUE@LoadPlugin target_set
 - 
 -# The following block demonstrates the default behavior if no filtering is
 -# configured at all: All values will be sent to all available write plugins.
 +
 +#----------------------------------------------------------------------------#
 +# The following block demonstrates the default behavior if no filtering is   #
 +# configured at all: All values will be sent to all available write plugins. #
 +#----------------------------------------------------------------------------#
  
- #<Chain "Main">
+ #<Chain "PostCache">
  #  Target "write"
  #</Chain>