Merge remote-tracking branch 'origin/pr/1346'
authorMarc Fournier <marc.fournier@camptocamp.com>
Tue, 9 Aug 2016 11:14:04 +0000 (13:14 +0200)
committerMarc Fournier <marc.fournier@camptocamp.com>
Tue, 9 Aug 2016 11:14:04 +0000 (13:14 +0200)
 Conflicts:
README
configure.ac
src/Makefile.am
src/collectd.conf.in
src/collectd.conf.pod
src/types.db

AUTHORS
README
configure.ac
src/Makefile.am
src/collectd.conf.in
src/collectd.conf.pod
src/gps.c [new file with mode: 0644]
src/types.db

diff --git a/AUTHORS b/AUTHORS
index 5c9119b..f5f6db0 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -219,6 +219,9 @@ Michał Mirosław <mirq-linux at rere.qmqm.pl>
 Mirko Buffoni <briareos at eswat.org>
  - Port/Socket selection in the MySQL plugin.
 
+Nicolas Jourden <nicolas.jourden at laposte.net>
+ - gps plugin.
+
 Niki W. Waibel <niki.waibel at newlogic.com>
  - Initial autotools fixes.
  - libltdl code.
diff --git a/README b/README
index e5d5c37..f2df12c 100644 (file)
--- a/README
+++ b/README
@@ -125,6 +125,9 @@ Features
     - gmond
       Receive multicast traffic from Ganglia instances.
 
+    - gps
+      Monitor gps related data through gpsd.
+
     - grpc
       Receive values over the network using the gRPC framework.
 
@@ -700,6 +703,10 @@ Prerequisites
     Used by the `network' plugin for encryption and authentication.
     <http://www.gnupg.org/>
 
+  * libgps (optional)
+    Used by the `gps' plugin.
+    <http://developer.berlios.de/projects/gpsd/>
+
   * libhal (optional)
     If present, the `uuid' plugin will check for UUID from HAL.
     <http://hal.freedesktop.org/>
index 1bc02bc..1bacddd 100644 (file)
@@ -2284,6 +2284,56 @@ AC_SUBST(GCRYPT_LIBS)
 AM_CONDITIONAL(BUILD_WITH_LIBGCRYPT, test "x$with_libgcrypt" = "xyes")
 # }}}
 
+# --with-libgps {{{
+with_libgps_cflags=""
+with_libgps_ldflags=""
+AC_ARG_WITH(libgps, [AS_HELP_STRING([--with-libgps@<:@=PREFIX@:>@], [Path to libgps.])],
+[
+       if test "x$withval" != "xno" && test "x$withval" != "xyes"
+       then
+               with_libgps_cflags="-I$withval/include"
+               with_libgps_ldflags="-L$withval/lib"
+               with_libgps="yes"
+       else
+               with_libgps="$withval"
+       fi
+],
+[
+       with_libgps="yes"
+])
+if test "x$with_libgps" = "xyes"
+then
+       SAVE_CFLAGS="$CFLAGS"
+       CFLAGS="$CFLAGS $with_libgps_cflags"
+
+       AC_CHECK_HEADERS(gps.h, [with_libgps="yes"], [with_libgps="no (gps.h not found)"])
+
+       CFLAGS="$SAVE_CFLAGS"
+fi
+if test "x$with_libgps" = "xyes"
+then
+       SAVE_CFLAGS="$CFLAGS"
+       SAVE_LDFLAGS="$LDFLAGS"
+       CFLAGS="$CFLAGS $with_libgps_cflags"
+       LDFLAGS="$LDFLAGS $with_libgps_ldflags"
+
+       AC_CHECK_LIB(gps, gps_open, [with_libgps="yes"], [with_libgps="no (symbol gps_open not found)"])
+
+       CFLAGS="$SAVE_CFLAGS"
+       LDFLAGS="$SAVE_LDFLAGS"
+fi
+if test "x$with_libgps" = "xyes"
+then
+       BUILD_WITH_LIBGPS_CFLAGS="$with_libgps_cflags"
+       BUILD_WITH_LIBGPS_LDFLAGS="$with_libgps_ldflags"
+       BUILD_WITH_LIBGPS_LIBS="-lgps"
+       AC_SUBST(BUILD_WITH_LIBGPS_CFLAGS)
+       AC_SUBST(BUILD_WITH_LIBGPS_LDFLAGS)
+       AC_SUBST(BUILD_WITH_LIBGPS_LIBS)
+fi
+AM_CONDITIONAL(BUILD_WITH_LIBGPS, test "x$with_libgps" = "xyes")
+# }}}
+
 # --with-libgrpc++ {{{
 with_libgrpcpp_cppflags=""
 with_libgrpcpp_ldflags=""
@@ -5575,6 +5625,7 @@ plugin_entropy="no"
 plugin_ethstat="no"
 plugin_fhcount="no"
 plugin_fscache="no"
+plugin_gps="no"
 plugin_grpc="no"
 plugin_interface="no"
 plugin_ipmi="no"
@@ -5868,6 +5919,11 @@ then
        plugin_interface="yes"
 fi
 
+if test "x$with_libgps" = "xyes"
+then
+       plugin_gps="yes"
+fi
+
 if test "x$have_getloadavg" = "xyes"
 then
        plugin_load="yes"
@@ -6022,6 +6078,7 @@ AC_PLUGIN([fhcount],             [$plugin_fhcount],         [File handles statis
 AC_PLUGIN([filecount],           [yes],                     [Count files in directories])
 AC_PLUGIN([fscache],             [$plugin_fscache],         [fscache statistics])
 AC_PLUGIN([gmond],               [$with_libganglia],        [Ganglia plugin])
+AC_PLUGIN([gps],                 [$plugin_gps],             [GPS plugin])
 AC_PLUGIN([grpc],                [$plugin_grpc],            [gRPC plugin])
 AC_PLUGIN([hddtemp],             [yes],                     [Query hddtempd])
 AC_PLUGIN([interface],           [$plugin_interface],       [Interface traffic statistics])
@@ -6341,6 +6398,7 @@ AC_MSG_RESULT([    libdbi  . . . . . . . $with_libdbi])
 AC_MSG_RESULT([    libesmtp  . . . . . . $with_libesmtp])
 AC_MSG_RESULT([    libganglia  . . . . . $with_libganglia])
 AC_MSG_RESULT([    libgcrypt . . . . . . $with_libgcrypt])
+AC_MSG_RESULT([    libgps  . . . . . . . $with_libgps])
 AC_MSG_RESULT([    libgrpc++ . . . . . . $with_libgrpcpp])
 AC_MSG_RESULT([    libhal  . . . . . . . $with_libhal])
 AC_MSG_RESULT([    libhiredis  . . . . . $with_libhiredis])
@@ -6436,6 +6494,7 @@ AC_MSG_RESULT([    fhcount . . . . . . . $enable_fhcount])
 AC_MSG_RESULT([    filecount . . . . . . $enable_filecount])
 AC_MSG_RESULT([    fscache . . . . . . . $enable_fscache])
 AC_MSG_RESULT([    gmond . . . . . . . . $enable_gmond])
+AC_MSG_RESULT([    gps . . . . . . . . . $enable_gps])
 AC_MSG_RESULT([    grpc  . . . . . . . . $enable_grpc])
 AC_MSG_RESULT([    hddtemp . . . . . . . $enable_hddtemp])
 AC_MSG_RESULT([    interface . . . . . . $enable_interface])
index b1fe3c5..12c7730 100644 (file)
@@ -442,6 +442,14 @@ gmond_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(GANGLIA_LDFLAGS)
 gmond_la_LIBADD = $(GANGLIA_LIBS)
 endif
 
+if BUILD_PLUGIN_GPS
+pkglib_LTLIBRARIES += gps.la
+gps_la_SOURCES = gps.c
+gps_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBGPS_CFLAGS)
+gps_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBGPS_LDFLAGS)
+gps_la_LIBADD = -lpthread $(BUILD_WITH_LIBGPS_LIBS)
+endif
+
 if BUILD_PLUGIN_GRPC
 pkglib_LTLIBRARIES += grpc.la
 grpc_la_SOURCES = grpc.cc
index c666692..e3f2aa3 100644 (file)
 #@BUILD_PLUGIN_FILECOUNT_TRUE@LoadPlugin filecount
 #@BUILD_PLUGIN_FSCACHE_TRUE@LoadPlugin fscache
 #@BUILD_PLUGIN_GMOND_TRUE@LoadPlugin gmond
+#@BUILD_PLUGIN_GPS_TRUE@LoadPlugin gps
 #@BUILD_PLUGIN_GRPC_TRUE@LoadPlugin grpc
 #@BUILD_PLUGIN_HDDTEMP_TRUE@LoadPlugin hddtemp
 @BUILD_PLUGIN_INTERFACE_TRUE@@BUILD_PLUGIN_INTERFACE_TRUE@LoadPlugin interface
 #  </Metric>
 #</Plugin>
 
+#<Plugin gps>
+#  Host "127.0.0.1"
+#  Port "2947"
+#  Timeout 0.015
+#  PauseConnect 5
+#</Plugin>
+
 #<Plugin grpc>
 #      WorkerThreads 5
 #      <Listen "0.0.0.0" "50051">
index 088ec5d..6ada5f1 100644 (file)
@@ -2641,6 +2641,78 @@ source, this is optional. Otherwise the option is required.
 
 =back
 
+=head2 Plugin C<gps>
+
+The C<gps plugin> connects to gpsd on the host machine.
+The host, port, timeout and pause are configurable.
+
+This is useful if you run an NTP server using a GPS for source and you want to
+monitor it.
+
+Mind your GPS must send $--GSA for having the data reported!
+
+The following elements are collected:
+
+=over 4
+
+=item B<satellites>
+
+Number of satellites used for fix (type instance "used") and in view (type
+instance "visible"). 0 means no GPS satellites are visible.
+
+=item B<dilution_of_precision>
+
+Vertical and horizontal dilution (type instance "horizontal" or "vertical").
+It should be between 0 and 3.
+Look at the documentation of your GPS to know more.
+
+=back
+
+Synopsis:
+
+ LoadPlugin gps
+ <Plugin "gps">
+   # Connect to localhost on gpsd regular port:
+   Host "127.0.0.1"
+   Port "2947"
+   # 15 ms timeout
+   Timeout 0.015
+   # PauseConnect of 5 sec. between connection attempts.
+   PauseConnect 5
+ </Plugin>
+
+Available configuration options:
+
+=over 4
+
+=item B<Host> I<Host>
+
+The host on which gpsd daemon runs. Defaults to B<localhost>.
+
+=item B<Port> I<Port>
+
+Port to connect to gpsd on the host machine. Defaults to B<2947>.
+
+=item B<Timeout> I<Seconds>
+
+Timeout in seconds (default 0.015 sec).
+
+The GPS data stream is fetch by the plugin form the daemon.
+It waits for data to be available, if none arrives it times out
+and loop for another reading.
+Mind to put a low value gpsd expects value in the micro-seconds area
+(recommended is 500 us) since the waiting function is blocking.
+Value must be between 500 us and 5 sec., if outside that range the
+default value is applied.
+
+This only applies from gpsd release-2.95.
+
+=item B<PauseConnect> I<Seconds>
+
+Pause to apply between attempts of connection to gpsd in seconds (default 5 sec).
+
+=back
+
 =head2 Plugin C<grpc>
 
 The I<grpc> plugin provides an RPC interface to submit values to or query
diff --git a/src/gps.c b/src/gps.c
new file mode 100644 (file)
index 0000000..04de5aa
--- /dev/null
+++ b/src/gps.c
@@ -0,0 +1,368 @@
+/**
+ * collectd - src/gps.c
+ * Copyright (C) 2015  Nicolas JOURDEN
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *   Nicolas JOURDEN <nicolas.jourden at laposte.net>
+ *   Florian octo Forster <octo at collectd.org>
+ *   Marc Fournier <marc.fournier at camptocamp.com>
+ **/
+
+#include "collectd.h"
+#include "common.h"
+#include "plugin.h"
+#include "utils_time.h"
+#include "configfile.h"
+
+#define CGPS_TRUE                  1
+#define CGPS_FALSE                 0
+#define CGPS_DEFAULT_HOST          "localhost"
+#define CGPS_DEFAULT_PORT          "2947" /* DEFAULT_GPSD_PORT */
+#define CGPS_DEFAULT_TIMEOUT       MS_TO_CDTIME_T (15)
+#define CGPS_DEFAULT_PAUSE_CONNECT TIME_T_TO_CDTIME_T (5)
+#define CGPS_MAX_ERROR             100
+#define CGPS_CONFIG                "?WATCH={\"enable\":true,\"json\":true,\"nmea\":false}\r\n"
+
+#include <gps.h>
+#include <pthread.h>
+
+typedef struct {
+  char *host;
+  char *port;
+  cdtime_t timeout;
+  cdtime_t pause_connect;
+} cgps_config_t;
+
+typedef struct {
+  gauge_t sats_used;
+  gauge_t sats_visible;
+  gauge_t hdop;
+  gauge_t vdop;
+} cgps_data_t;
+
+static cgps_config_t cgps_config_data;
+
+static cgps_data_t cgps_data = {NAN, NAN, NAN, NAN};
+
+static pthread_t cgps_thread_id;
+static pthread_mutex_t  cgps_data_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t  cgps_thread_lock = PTHREAD_MUTEX_INITIALIZER;
+static int cgps_thread_shutdown = CGPS_FALSE;
+static int cgps_thread_running = CGPS_FALSE;
+
+/**
+ * Non blocking pause for the thread.
+ */
+static int cgps_thread_pause(cdtime_t pTime)
+{
+  cdtime_t now;
+  now = cdtime ();
+  struct timespec pause_th;
+  CDTIME_T_TO_TIMESPEC (MS_TO_CDTIME_T(10), &pause_th);
+  while (CGPS_TRUE)
+  {
+    if ( (cdtime () - now) > pTime )
+    {
+      break;
+    }
+
+    pthread_mutex_lock (&cgps_thread_lock);
+    if (cgps_thread_shutdown == CGPS_TRUE)
+    {
+      return CGPS_FALSE;
+    }
+    pthread_mutex_unlock (&cgps_thread_lock);
+    nanosleep (&pause_th, NULL);
+ }
+
+ return CGPS_TRUE;
+}
+
+/**
+ * Thread reading from gpsd.
+ */
+static void * cgps_thread (void * pData)
+{
+  struct gps_data_t gpsd_conn;
+  unsigned int err_count;
+  cgps_thread_running = CGPS_TRUE;
+
+  while (CGPS_TRUE)
+  {
+    pthread_mutex_lock (&cgps_thread_lock);
+    if (cgps_thread_shutdown == CGPS_TRUE)
+    {
+      goto quit;
+    }
+    pthread_mutex_unlock (&cgps_thread_lock);
+
+    err_count = 0;
+
+#if GPSD_API_MAJOR_VERSION > 4
+    int status = gps_open (cgps_config_data.host, cgps_config_data.port, &gpsd_conn);
+#else
+    int status = gps_open_r (cgps_config_data.host, cgps_config_data.port, &gpsd_conn);
+#endif
+    if (status < 0)
+    {
+      WARNING ("gps plugin: connecting to %s:%s failed: %s",
+               cgps_config_data.host, cgps_config_data.port, gps_errstr (status));
+
+      // Here we make a pause until a new tentative to connect, we check also if
+      // the thread does not need to stop.
+      if (cgps_thread_pause(cgps_config_data.pause_connect) == CGPS_FALSE)
+      {
+        goto quit;
+      }
+
+      continue;
+    }
+
+    gps_stream (&gpsd_conn, WATCH_ENABLE | WATCH_JSON | WATCH_NEWSTYLE, NULL);
+    gps_send (&gpsd_conn, CGPS_CONFIG);
+
+    while (CGPS_TRUE)
+    {
+      pthread_mutex_lock (&cgps_thread_lock);
+      if (cgps_thread_shutdown == CGPS_TRUE)
+      {
+        goto stop;
+      }
+      pthread_mutex_unlock (&cgps_thread_lock);
+
+#if GPSD_API_MAJOR_VERSION > 4
+      long timeout_us = CDTIME_T_TO_US (cgps_config_data.timeout);
+      if (!gps_waiting (&gpsd_conn, (int) timeout_us ))
+#else
+      if (!gps_waiting (&gpsd_conn))
+#endif
+      {
+        continue;
+      }
+
+      if (gps_read (&gpsd_conn) == -1)
+      {
+        WARNING ("gps plugin: incorrect data! (err_count: %d)", err_count);
+        err_count++;
+
+        if (err_count > CGPS_MAX_ERROR)
+        {
+          // Server is not responding ...
+          if (gps_send (&gpsd_conn, CGPS_CONFIG) == -1)
+          {
+            WARNING ("gps plugin: gpsd seems to be down, reconnecting");
+            gps_close (&gpsd_conn);
+            break;
+          }
+          // Server is responding ...
+          else
+          {
+            err_count = 0;
+          }
+        }
+
+        continue;
+      }
+
+      pthread_mutex_lock (&cgps_data_lock);
+
+      // Number of sats in view:
+      cgps_data.sats_used = (gauge_t) gpsd_conn.satellites_used;
+      cgps_data.sats_visible = (gauge_t) gpsd_conn.satellites_visible;
+
+      // dilution of precision:
+      cgps_data.vdop = NAN;
+      cgps_data.hdop = NAN;
+      if (cgps_data.sats_used > 0)
+      {
+        cgps_data.hdop = gpsd_conn.dop.hdop;
+        cgps_data.vdop = gpsd_conn.dop.vdop;
+      }
+
+      DEBUG ("gps plugin: %.0f sats used (of %.0f visible), hdop = %.3f, vdop = %.3f",
+             cgps_data.sats_used, cgps_data.sats_visible, cgps_data.hdop, cgps_data.vdop);
+
+      pthread_mutex_unlock (&cgps_data_lock);
+    }
+  }
+
+stop:
+  DEBUG ("gps plugin: thread closing gpsd connection ... ");
+  gps_stream (&gpsd_conn, WATCH_DISABLE, NULL);
+  gps_close (&gpsd_conn);
+quit:
+  DEBUG ("gps plugin: thread shutting down ... ");
+  cgps_thread_running = CGPS_FALSE;
+  pthread_mutex_unlock (&cgps_thread_lock);
+  pthread_exit (NULL);
+}
+
+
+/**
+ * Submit a piece of the data.
+ */
+static void cgps_submit (const char *type, gauge_t value, const char *type_instance)
+{
+  value_t values[1];
+  value_list_t vl = VALUE_LIST_INIT;
+
+  values[0].gauge = value;
+
+  vl.values = values;
+  vl.values_len = 1;
+  sstrncpy (vl.host, hostname_g, sizeof (vl.host));
+  sstrncpy (vl.plugin, "gps", sizeof (vl.plugin));
+  sstrncpy (vl.type, type, sizeof (vl.type));
+  sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance));
+
+  plugin_dispatch_values (&vl);
+}
+
+/**
+ * Read the data and submit by piece.
+ */
+static int cgps_read ()
+{
+  cgps_data_t data_copy;
+
+  pthread_mutex_lock (&cgps_data_lock);
+  data_copy = cgps_data;
+  pthread_mutex_unlock (&cgps_data_lock);
+
+  cgps_submit ("dilution_of_precision", data_copy.hdop, "horizontal");
+  cgps_submit ("dilution_of_precision", data_copy.vdop, "vertical");
+  cgps_submit ("satellites", data_copy.sats_used, "used");
+  cgps_submit ("satellites", data_copy.sats_visible, "visible");
+
+  return (0);
+}
+
+/**
+ * Read configuration.
+ */
+static int cgps_config (oconfig_item_t *ci)
+{
+  int i;
+
+  for (i = 0; i < ci->children_num; i++)
+  {
+    oconfig_item_t *child = ci->children + i;
+
+    if (strcasecmp ("Host", child->key) == 0)
+      cf_util_get_string (child, &cgps_config_data.host);
+    else if (strcasecmp ("Port", child->key) == 0)
+      cf_util_get_service (child, &cgps_config_data.port);
+    else if (strcasecmp ("Timeout", child->key) == 0)
+      cf_util_get_cdtime (child, &cgps_config_data.timeout);
+    else if (strcasecmp ("PauseConnect", child->key) == 0)
+      cf_util_get_cdtime (child, &cgps_config_data.pause_connect);
+    else
+      WARNING ("gps plugin: Ignoring unknown config option \"%s\".", child->key);
+  }
+
+  // Controlling the value for timeout:
+  // If set too high it blocks the reading (> 5 s), too low it gets not reading (< 500 us).
+  // To avoid any issues we replace "out of range" value by the default value.
+  if (
+    cgps_config_data.timeout > TIME_T_TO_CDTIME_T(5)
+    ||
+    cgps_config_data.timeout < US_TO_CDTIME_T(500)
+  )
+  {
+    WARNING ("gps plugin: timeout set to %.6f sec. setting to default (%.6f).",
+      CDTIME_T_TO_DOUBLE(cgps_config_data.timeout),
+      CDTIME_T_TO_DOUBLE(CGPS_DEFAULT_TIMEOUT)
+    );
+    cgps_config_data.timeout = CGPS_DEFAULT_TIMEOUT;
+  }
+
+  return (0);
+}
+
+/**
+ * Init.
+ */
+static int cgps_init (void)
+{
+  int status;
+
+  if (cgps_thread_running == CGPS_TRUE)
+  {
+    DEBUG ("gps plugin: error gps thread already running ... ");
+    return 0;
+  }
+
+  DEBUG ("gps plugin: config{host: \"%s\", port: \"%s\", timeout: %.6f sec., pause connect: %.3f sec.}",
+         cgps_config_data.host, cgps_config_data.port,
+         CDTIME_T_TO_DOUBLE (cgps_config_data.timeout),
+         CDTIME_T_TO_DOUBLE (cgps_config_data.pause_connect));
+
+  status = plugin_thread_create (&cgps_thread_id, NULL, cgps_thread, NULL);
+  if (status != 0)
+  {
+    ERROR ("gps plugin: pthread_create() failed.");
+    return (-1);
+  }
+
+  return (0);
+}
+
+/**
+ * Shutdown.
+ */
+static int cgps_shutdown (void)
+{
+  void * res;
+
+  pthread_mutex_lock (&cgps_thread_lock);
+  cgps_thread_shutdown = CGPS_TRUE;
+  pthread_mutex_unlock (&cgps_thread_lock);
+
+  pthread_join(cgps_thread_id, &res);
+  free(res);
+
+  // Clean mutex:
+  pthread_mutex_unlock(&cgps_thread_lock);
+  pthread_mutex_destroy(&cgps_thread_lock);
+  pthread_mutex_unlock(&cgps_data_lock);
+  pthread_mutex_destroy(&cgps_data_lock);
+
+  sfree (cgps_config_data.port);
+  sfree (cgps_config_data.host);
+
+  return (0);
+}
+
+/**
+ * Register the module.
+ */
+void module_register (void)
+{
+  cgps_config_data.host = sstrdup (CGPS_DEFAULT_HOST);
+  cgps_config_data.port = sstrdup (CGPS_DEFAULT_PORT);
+  cgps_config_data.timeout = CGPS_DEFAULT_TIMEOUT;
+  cgps_config_data.pause_connect = CGPS_DEFAULT_PAUSE_CONNECT;
+
+  plugin_register_complex_config ("gps", cgps_config);
+  plugin_register_init ("gps", cgps_init);
+  plugin_register_read ("gps", cgps_read);
+  plugin_register_shutdown ("gps", cgps_shutdown);
+}
index 8c6a995..cc79af0 100644 (file)
@@ -45,6 +45,7 @@ derive                  value:DERIVE:0:U
 df                      used:GAUGE:0:1125899906842623, free:GAUGE:0:1125899906842623
 df_complex              value:GAUGE:0:U
 df_inodes               value:GAUGE:0:U
+dilution_of_precision   value:GAUGE:0:U
 disk_io_time            io_time:DERIVE:0:U, weighted_io_time:DERIVE:0:U
 disk_latency            read:GAUGE:0:U, write:GAUGE:0:U
 disk_merged             read:DERIVE:0:U, write:DERIVE:0:U
@@ -197,6 +198,7 @@ root_dispersion         value:GAUGE:U:U
 route_etx               value:GAUGE:0:U
 route_metric            value:GAUGE:0:U
 routes                  value:GAUGE:0:U
+satellites              value:GAUGE:0:U
 segments                value:GAUGE:0:65535
 serial_octets           rx:DERIVE:0:U, tx:DERIVE:0:U
 signal_noise            value:GAUGE:U:0