[collectd] [PATCH 1/2] Add collectd-flush command line utility.

Hakon-Dugstad.Johnsen at telenor.com Hakon-Dugstad.Johnsen at telenor.com
Thu Aug 5 16:37:45 CEST 2010


collectd-flush is a small command-line utility which uses libcollectdclient 
to flush collectd through the unixsock plugin. As far as I know, there is 
no easy way to work with unix sockets from the shell, so if someone 
wanted to flush collectd without this program, they would need to do it 
through some other language (or restart the deamon).

I am no C wizard, so please bear with me if I have
done something a stupid way. :)
The code is based on/inspired by collectd-nagios.

If this message is not properly encoded as utf-8, something wrong must have 
happened with my mailer. If that's the case, I'm sorry.  The only non-ascii character
in the patch is the second character of my name, which is an å.

Signed-off-by: Håkon J Dugstad Johnsen <hakon-dugstad.johnsen at telenor.com>
---
 src/collectd-flush.c   |  175 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/collectd-flush.pod |   71 +++++++++++++++++++
 2 files changed, 246 insertions(+), 0 deletions(-)
 create mode 100644 src/collectd-flush.c
 create mode 100644 src/collectd-flush.pod

diff --git a/src/collectd-flush.c b/src/collectd-flush.c
new file mode 100644
index 0000000..c43ae09
--- /dev/null
+++ b/src/collectd-flush.c
@@ -0,0 +1,175 @@
+/**
+ * collectd-flush - src/collectd-flush.c
+ * Copyright (C) 2010 Håkon J Dugstad Johnsen 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; only version 2 of the License is applicable.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ * Authors:
+ *   Håkon J Dugstad Johnsen <hakon-dugstad.johnsen at telenor.com>
+ **/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <getopt.h>
+#include "libcollectdclient/client.h"
+
+extern char *optarg;
+
+static int flush (
+    const char *address, 
+    const char *plugin, 
+    const char *ident_str, 
+    int timeout) 
+{
+  lcc_connection_t *connection;
+  lcc_identifier_t ident;
+
+  // Pointer which is passed to lcc_flush.
+  //Either a null pointer or it points to ident
+  lcc_identifier_t *identp; 
+  int status;
+
+  connection = NULL;
+  status = lcc_connect(address, &connection);
+  if (status != 0)
+  {
+		fprintf (stderr, "ERROR: Connecting to daemon at %s failed: %s.\n",
+				address, strerror (errno));
+		return 1;
+	}
+
+  identp = NULL;
+  if (ident_str != NULL && *ident_str != '\0') {
+    identp = &ident;
+    status = lcc_string_to_identifier (connection, &ident, ident_str);
+    if (status != 0) {
+      fprintf (stderr, "ERROR: Creating and identifier failed: %s.\n",
+          lcc_strerror(connection));
+      LCC_DESTROY (connection);
+
+      return 1;
+    }
+  }
+
+  status = lcc_flush (connection, plugin, identp, timeout);
+  if (status != 0) {
+    fprintf (stderr, "ERROR: Flushing failed: %s.\n",
+        lcc_strerror (connection));
+    LCC_DESTROY (connection);
+
+    return 1;
+  }
+
+  LCC_DESTROY (connection);
+
+  return 0;
+}
+
+void usage (const char *name) {
+  fprintf (stderr, "Usage: %s [options]\n"
+      "\n"
+      "Valid options are:\n"
+      "  -h, --help               Display this help message.\n"
+      "  -s, --socket=<socket>    Path to collectd's UNIX socket. Default: /var/run/collectd-unixsock\n"
+      "  -p, --plugin=<plugin>    Plugin to flush _to_ (not from). Example: rrdtool\n"
+      "  -i, --identifier=<identifier>\n"
+      "                           Only flush data specified by <identifier>, which has the format: \n"
+      "\n"
+      "                             [<hostname>/]<plugin>[-<plugin_instance>]/<type>[-<type_instance>]\n"
+      "\n"
+      "                           Hostname defaults to the local hostname if omitted.\n"
+      "                           No error is returned if the specified identifier does not exist.\n"
+      "                           Examples: uptime/uptime\n"
+      "                                     somehost/cpu-0/cpu-wait\n"
+      "  -t, --timeout=<timeout>  Only flush values older than this timeout.\n", name);
+}
+
+/*
+ * Count how many occurences there are of a char in a string.
+ */
+int charoccurences (const char *str, char chr) {
+  int count = 0;
+  while (*str != '\0') {
+    if (*str == chr) {
+      count++;
+    }
+    str++;
+  }
+
+  return count;
+}
+
+int main (int argc, char **argv) {
+  char address[1024] = "unix:/var/run/collectd-unixsock";
+  char *plugin = NULL;
+  char ident_str[1024] = "";
+  int timeout = -1;
+  char hostname[1024];
+  char c;
+
+  static struct option long_options[] = 
+    {
+      {"help", no_argument, 0, 'h'},
+      {"socket", required_argument, 0, 's'},
+      {"plugin", required_argument, 0, 'p'},
+      {"identifier", required_argument, 0, 'i'},
+      {"timeout", required_argument, 0, 't'}
+    };
+  int option_index = 0;
+
+ 
+  while ((c = getopt_long (argc, argv, "s:p:i:ht:", long_options, &option_index)) != -1) {
+    switch (c) {
+      case 's':
+        snprintf (address, sizeof (address), "unix:%s", optarg); 
+      case 'p':
+        plugin = optarg;
+        break;
+      case 'i':
+        if(charoccurences(optarg, '/') == 1) {
+          // The user has omitted the hostname part of the identifier 
+          // (there is only one '/' in the identifier)
+          // Let's add the local hostname
+          if(gethostname(hostname, sizeof(hostname)) != 0) {
+            fprintf (stderr, "Could not get local hostname: %s", strerror(errno));
+            return 1;
+          }
+          // Make sure hostname is zero-terminated
+          hostname[sizeof(hostname)-1] = '\0'; 
+          snprintf (ident_str, sizeof (ident_str), "%s/%s", hostname, optarg);
+          // Make sure ident_str is zero terminated
+          ident_str[sizeof(ident_str)-1] = '\0'; 
+        } else {
+          strncpy(ident_str, optarg, sizeof (ident_str));
+          // Make sure identifier is zero terminated
+          ident_str[sizeof(ident_str)-1] = '\0'; 
+        }
+        break;
+      case 't':
+        timeout = atoi (optarg);
+        break;
+      case 'h':
+        usage (argv[0]);
+        return 0;
+      default:
+        usage (argv[0]);
+        return 1;
+    }
+  }
+
+  return flush(address, plugin, ident_str, timeout);
+}
diff --git a/src/collectd-flush.pod b/src/collectd-flush.pod
new file mode 100644
index 0000000..1911005
--- /dev/null
+++ b/src/collectd-flush.pod
@@ -0,0 +1,71 @@
+=head1 NAME
+
+collectd-flush - Small command line utility to flush collectd
+
+=head1 SYNOPSIS
+
+collectd-flush I<[options]>
+
+=head1 DESCRIPTION
+
+This small command line utitilty uses C<libcollectdclient> to flush collectd 
+through a socket from the L<unixsock plugin>. Useful if you want to be sure 
+you have the latest values in your RRD files before graphing them or copying 
+them somewhere else.
+
+=head1 ARGUMENTS AND OPTIONS
+
+The following arguments and options are understood by collectd-flush. The order
+of the arguments generally doesn't matter, as long as no argument is passed 
+more than once.
+
+=over 4
+
+=item B<-h>, B<--help>
+
+Display information about the options.
+
+=item B<-s>, B<--socket=>I<socket>
+
+Path to the UNIX socket opened by collectd's C<unixsock plugin>. 
+Default: /var/run/collectd-unixsock
+
+=item B<-p>, B<--plugin=>I<plugin>
+
+Plugin to flush I<to>. Example: B<rrdtool>.
+
+=item B<-i>, B<--identifier=>I<identifier>
+
+If this option is present, only the data specified by I<identifier> will be flushed.
+I<identifier> has the following format:
+
+[I<hostname>/]I<plugin>[-I<plugin_instance>]/I<type>[-I<type_instance>]
+
+Examples:
+ somehost/cpu-0/cpu-idle
+ uptime/uptime
+ otherhost/memory/memory-used
+
+Hostname defaults to the local hostname if omitted. No error is returned if the
+specified identifier does not exist (this is a limitation in the 
+C<libcollectdclient> library).You can only specify one identifier each time you
+run this program (even though L<collectd-unixsock(5)> supports multiple
+identifiers).
+
+=item B<-t>, B<--timeout=>I<timeout>
+
+Only flush values older than I<timeout>.
+
+=back
+
+=head1 SEE ALSO
+
+L<collectd(1)>
+L<collectd.conf(5)>
+L<collectd-unixsock(5)>
+
+=head1 AUTHOR
+
+Håkon J Dugstad Johnsen E<lt>hakon-dugstad.johnsenE<nbsp>atE<nbsp>telenor.comE<gt>
+
+=cut
-- 
1.7.0.4



More information about the collectd mailing list