summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: add25ce)
raw | patch | inline | side by side (parent: add25ce)
author | Nicolas JOURDEN <nicolas.jourden@laposte.net> | |
Tue, 10 Nov 2015 14:59:08 +0000 (15:59 +0100) | ||
committer | Nicolas JOURDEN <nicolas.jourden@laposte.net> | |
Tue, 10 Nov 2015 14:59:08 +0000 (15:59 +0100) |
configure.ac | patch | blob | history | |
src/Makefile.am | patch | blob | history | |
src/gps.c | [new file with mode: 0644] | patch | blob |
src/gps.pod | [new file with mode: 0644] | patch | blob |
src/types.db | patch | blob | history |
diff --git a/configure.ac b/configure.ac
index 7b2296d0f56bf8ba5111f23f9145afe4c4db243c..7a8114568147dfd003bc7395d94e1087596918b9 100644 (file)
--- a/configure.ac
+++ b/configure.ac
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-libiptc {{{
AC_ARG_WITH(libiptc, [AS_HELP_STRING([--with-libiptc@<:@=PREFIX@:>@], [Path to libiptc.])],
[
plugin_ethstat="no"
plugin_fhcount="no"
plugin_fscache="no"
+plugin_gps="no"
plugin_interface="no"
plugin_ipmi="no"
plugin_ipvs="no"
plugin_interface="yes"
fi
+if test "x$with_libgps" = "xyes" && test "x$with_libpthread" = "xyes"
+then
+ plugin_gps="yes"
+fi
+
if test "x$have_getloadavg" = "xyes"
then
plugin_load="yes"
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([hddtemp], [yes], [Query hddtempd])
AC_PLUGIN([interface], [$plugin_interface], [Interface traffic statistics])
AC_PLUGIN([ipc], [$plugin_ipc], [IPC statistics])
libesmtp . . . . . . $with_libesmtp
libganglia . . . . . $with_libganglia
libgcrypt . . . . . . $with_libgcrypt
+ libgps . . . . . . . $with_libgps
libhal . . . . . . . $with_libhal
libhiredis . . . . . $with_libhiredis
libi2c-dev . . . . . $with_libi2c
filecount . . . . . . $enable_filecount
fscache . . . . . . . $enable_fscache
gmond . . . . . . . . $enable_gmond
+ gps . . . . . . . . . $enable_gps
hddtemp . . . . . . . $enable_hddtemp
interface . . . . . . $enable_interface
ipc . . . . . . . . . $enable_ipc
diff --git a/src/Makefile.am b/src/Makefile.am
index 07ffdda9ce58ec20107893a4513bef2d144c2ce1..2848ebdb583828720c16124d2a396073988517aa 100644 (file)
--- a/src/Makefile.am
+++ b/src/Makefile.am
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 = -module -avoid-version $(BUILD_WITH_LIBGPS_LDFLAGS)
+gps_la_LIBADD = -lpthread $(BUILD_WITH_LIBGPS_LIBS)
+endif
+
if BUILD_PLUGIN_HDDTEMP
pkglib_LTLIBRARIES += hddtemp.la
hddtemp_la_SOURCES = hddtemp.c
collectd-threshold.pod \
collectd-unixsock.pod \
postgresql_default.conf \
+ gps.pod \
types.db.pod
.pod.1:
diff --git a/src/gps.c b/src/gps.c
--- /dev/null
+++ b/src/gps.c
@@ -0,0 +1,223 @@
+/**
+ * This plug-in helps to monitor the GPS connected to a system.
+ * It reads the data comming from GPSd.
+ It look for the following parameters.
+ */
+
+#include "collectd.h"
+#include "common.h"
+#include "plugin.h"
+
+#if HAVE_GPS_H
+#include <gps.h>
+#endif
+
+#if HAVE_LIBPTHREAD
+#include <pthread.h>
+#endif
+
+typedef struct
+{
+ char *host;
+ char *port;
+ int timeout;
+} gps_definition_t;
+static gps_definition_t gps_data_config;
+
+typedef struct {
+ int satellites;
+ double vdop;
+ double hdop;
+} gpsDATA_t;
+static gpsDATA_t gps_data_read;
+
+
+static const char *config_keys[] =
+{
+ "Host",
+ "Port",
+ "Timeout"
+};
+static int config_keys_num = STATIC_ARRAY_SIZE (config_keys);
+
+
+// Thread items:
+static pthread_t connector = (pthread_t) 0;
+static pthread_mutex_t data_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+
+/**
+ * Thread reading from GPSd.
+ */
+static void * gps_collectd_thread (void * pData)
+{
+ struct gps_data_t gps_data;
+
+ while (1)
+ {
+ if (gps_open(gps_data_config.host, gps_data_config.port, &gps_data) < 0)
+ {
+ printf ("cannot connect to: %s:%s", gps_data_config.host, gps_data_config.port);
+ sleep(60);
+ continue;
+ }
+
+ gps_stream(&gps_data, WATCH_ENABLE | WATCH_JSON, NULL);
+
+ while (1)
+ {
+ if (gps_waiting (&gps_data, gps_data_config.timeout))
+ {
+ if (gps_read (&gps_data) == -1)
+ {
+ WARNING ("incorrect data.\n");
+ }
+ else {
+ pthread_mutex_lock (&data_mutex);
+
+ // Dop data:
+ if (isnan(gps_data.dop.vdop) == 0)
+ {
+ gps_data_read.vdop = gps_data.dop.vdop;
+ }
+ if (isnan(gps_data.dop.hdop) == 0)
+ {
+ gps_data_read.hdop = gps_data.dop.hdop;
+ }
+
+ // Sat in view:
+ if ((gps_data.set & LATLON_SET))
+ {
+ gps_data_read.satellites = gps_data.satellites_used;
+ }
+
+ pthread_mutex_unlock (&data_mutex);
+ }
+ }
+ }
+ }
+
+ gps_stream(&gps_data, WATCH_DISABLE, NULL);
+ gps_close(&gps_data);
+
+ pthread_exit ((void *)0);
+}
+
+
+/**
+ * Submit the data.
+ */
+static void gps_collectd_submit (const char *type, gauge_t value)
+{
+ 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, "gps", sizeof (vl.type_instance));
+
+ plugin_dispatch_values (&vl);
+}
+
+
+/**
+ * Read the data and submit.
+ */
+static int gps_collectd_read ()
+{
+ pthread_mutex_lock (&data_mutex);
+ gps_collectd_submit("gps_hdop", (gauge_t) gps_data_read.hdop);
+ gps_collectd_submit("gps_vdop", (gauge_t) gps_data_read.vdop);
+ gps_collectd_submit("gps_sat", (gauge_t) gps_data_read.satellites);
+ printf ("gps: hdop=%1.3f, vdop=%1.3f, sat=%02d.\n",
+ gps_data_read.hdop,
+ gps_data_read.vdop,
+ gps_data_read.satellites
+ );
+ pthread_mutex_unlock (&data_mutex);
+ return (0);
+}
+
+
+/**
+ * Read configuration.
+ */
+static int gps_collectd_config (const char *key, const char *value)
+{
+ if (strcasecmp (key, "Host") == 0) {
+ if (gps_data_config.host != NULL) free (gps_data_config.host);
+ gps_data_config.host = sstrdup (value);
+ }
+ if (strcasecmp (key, "Port") == 0) {
+ if (gps_data_config.port != NULL) free (gps_data_config.port);
+ gps_data_config.port = sstrdup (value);
+ }
+ if (strcasecmp (key, "Timeout") == 0) {
+ gps_data_config.timeout = (int) strtol (value, NULL, 1000);
+ }
+ return (0);
+}
+
+
+/**
+ * Init.
+ */
+static int gps_collectd_init (void)
+{
+ int err = 0;
+
+ printf ("gps: will use %s:%s with timeout %d.\n", gps_data_config.host, gps_data_config.port, gps_data_config.timeout);
+
+ err = plugin_thread_create (&connector, NULL, gps_collectd_thread, NULL);
+
+ if (err != 0) {
+ WARNING ("pthread_create() failed.");
+ return (-1);
+ }
+
+ return (0);
+}
+
+
+/**
+ * Shutdown.
+ */
+static int gps_collectd_shutdown (void)
+{
+ if (connector != ((pthread_t) 0)) {
+ pthread_kill (connector, SIGTERM);
+ connector = (pthread_t) 0;
+ }
+
+ sfree (gps_data_config.port);
+ sfree (gps_data_config.host);
+
+ return (0);
+}
+
+/**
+ * Register the module.
+ */
+void module_register (void)
+{
+ gps_data_config.host = sstrdup ("localhost");
+ gps_data_config.port = sstrdup ("2947");
+ gps_data_read.hdop = 0;
+ gps_data_read.vdop = 0;
+ gps_data_read.satellites = 0;
+
+ // Read the config params:
+ plugin_register_config ("gps", gps_collectd_config, config_keys, config_keys_num);
+ // Create the thread:
+ plugin_register_init ("gps", gps_collectd_init);
+ // Kill the thread and stop.
+ plugin_register_shutdown ("gps", gps_collectd_shutdown);
+ // Read plugin:
+ plugin_register_read ("gps", gps_collectd_read);
+}
+
diff --git a/src/gps.pod b/src/gps.pod
--- /dev/null
+++ b/src/gps.pod
@@ -0,0 +1,71 @@
+=encoding UTF-8
+
+=head1 NAME
+
+gps - Documentation of collectd's C<gps plugin>
+
+=head1 SYNOPSIS
+
+ # See collectd.conf(5)
+ LoadPlugin gps
+ <Plugin "gps">
+ Host "localhost"
+ Port "2947"
+ Timeout 1000
+ </Plugin>
+
+=head1 DESCRIPTION
+
+The C<gps plugin> connects to gpsd on the host machine.
+The port and the timeout are configurable.
+
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<Host>
+
+The host on which gpsd runs.
+
+=item B<Port>
+
+Port to connect to gpsd on the host machine.
+
+=item B<Timeout>
+
+Timeout in ms.
+
+=back
+
+=head1 NOTIFICATION DATA FORMAT
+
+=over 4
+
+=item B<gps_sat>
+
+Number of satelites in view.
+0 means no GPS are visible.
+
+=item B<gps_hdop>
+
+Horizontal dilution.
+It should be between 0 and 3.
+Look at the documentaiton of your GPS.
+
+=item B<gps_vdop>
+
+Vertical dilution.
+Same as above.
+
+=head1 SEE ALSO
+
+L<collectd(1)>,
+L<collectd.conf(5)>,
+gpsd
+
+=head1 AUTHOR
+
+Nicolas Jourden E<lt>nicolas.jourden@laposte.netE<gt>
+
+=cut
diff --git a/src/types.db b/src/types.db
index 38fb546c867170f43eada049718786e46e6a1060..bfe660e0e8d372518b11e80c68e9e4014d5da988 100644 (file)
--- a/src/types.db
+++ b/src/types.db
frequency value:GAUGE:0:U
fscache_stat value:DERIVE:0:U
gauge value:GAUGE:U:U
+gps_sat value:GAUGE:0:25
+gps_hdop value:GAUGE:0:100
+gps_vdop value:GAUGE:0:100
hash_collisions value:DERIVE:0:U
http_request_methods value:DERIVE:0:U
http_requests value:DERIVE:0:U