From 374d5b33a80a31a9e25bc4b1e9404091a4017761 Mon Sep 17 00:00:00 2001 From: Nicolas JOURDEN Date: Thu, 19 Nov 2015 10:22:33 +0100 Subject: [PATCH] Applied comments from Florian FOSTER, added more documentation, pause, fixed some typos. --- src/gps.c | 138 ++++++++++++++++++++++++++++++++++++++------------- src/gps.pod | 50 +++++++++++-------- src/types.db | 5 +- 3 files changed, 135 insertions(+), 58 deletions(-) diff --git a/src/gps.c b/src/gps.c index 1136f50b..86bd2d1c 100644 --- a/src/gps.c +++ b/src/gps.c @@ -1,13 +1,42 @@ /** - * 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. - */ + * 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 + **/ + + #include "collectd.h" #include "common.h" #include "plugin.h" + +#define GPS_DEFAULT_HOST "localhost" +#define GPS_DEFAULT_PORT "2947" +#define GPS_DEFAULT_TIMEOUT 15 +#define GPS_DEFAULT_PAUSE 1 + + #if HAVE_GPS_H #include #endif @@ -16,27 +45,31 @@ #include #endif + typedef struct { char *host; char *port; int timeout; + int pause; } 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; +} gpsdata_t; +static gpsdata_t gps_data_read; static const char *config_keys[] = { "Host", "Port", - "Timeout" + "Timeout", + "Pause" }; static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); @@ -47,7 +80,7 @@ static pthread_mutex_t data_mutex = PTHREAD_MUTEX_INITIALIZER; /** - * Thread reading from GPSd. + * Thread reading from gpsd. */ static void * gps_collectd_thread (void * pData) { @@ -57,41 +90,57 @@ static void * gps_collectd_thread (void * pData) { 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); + WARNING ("gps: 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); + gps_stream(&gps_data, WATCH_ENABLE | WATCH_JSON | WATCH_NEWSTYLE, NULL); + gps_send(&gps_data, "?WATCH={\"enable\":true,\"json\":true,\"nmea\":false}\r\n"); while (1) { - if (gps_waiting (&gps_data, gps_data_config.timeout)) + if (gps_waiting (&gps_data, gps_data_config.timeout ) ) { + DEBUG ("gps: reading\n"); + if (gps_read (&gps_data) == -1) { - WARNING ("incorrect data.\n"); + WARNING ("gps: incorrect data !\n"); } else { pthread_mutex_lock (&data_mutex); + DEBUG ("gps: parsing\n"); // Dop data: if (isnan(gps_data.dop.vdop) == 0) { + DEBUG ("gps: isnan(gps_data.dop.vdop) == 0 [OK]\n"); gps_data_read.vdop = gps_data.dop.vdop; } if (isnan(gps_data.dop.hdop) == 0) { + DEBUG ("gps: isnan(gps_data.dop.hdop) == 0 [OK]\n"); gps_data_read.hdop = gps_data.dop.hdop; } // Sat in view: if ((gps_data.set & LATLON_SET)) { + DEBUG ("gps: gps_data.set & LATLON_SET [OK] ... \n"); gps_data_read.satellites = gps_data.satellites_used; } + + DEBUG ("gps: raw is hdop=%1.3f, vdop=%1.3f, sat-used=%02d, lat=%02.05f, lon=%03.05f\n", + gps_data.dop.hdop, + gps_data.dop.vdop, + gps_data.satellites_used, + gps_data.fix.latitude, + gps_data.fix.longitude + ); pthread_mutex_unlock (&data_mutex); + sleep(gps_data_config.pause); } } } @@ -105,9 +154,9 @@ static void * gps_collectd_thread (void * pData) /** - * Submit the data. + * Submit a piece of the data. */ -static void gps_collectd_submit (const char *type, gauge_t value) +static void gps_collectd_submit (const char *type, gauge_t value, const char *type_instance) { value_t values[1]; value_list_t vl = VALUE_LIST_INIT; @@ -119,22 +168,22 @@ static void gps_collectd_submit (const char *type, gauge_t value) 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)); + sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); plugin_dispatch_values (&vl); } /** - * Read the data and submit. + * Read the data and submit by piece. */ 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_collectd_submit("dilution_of_precision", (gauge_t) gps_data_read.hdop, "horizontal"); + gps_collectd_submit("dilution_of_precision", (gauge_t) gps_data_read.vdop, "vertical"); + gps_collectd_submit("satellites", (gauge_t) gps_data_read.satellites, "gps"); + DEBUG ("gps: hdop=%1.3f, vdop=%1.3f, sat=%02d.\n", gps_data_read.hdop, gps_data_read.vdop, gps_data_read.satellites @@ -149,16 +198,33 @@ static int gps_collectd_read () */ 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); + char *endptr = NULL; + + 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, "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) ( strtod(value, &endptr) * 1000 ); + DEBUG ("gps: will use pause %s - %d.\n", value, gps_data_config.timeout); } - if (strcasecmp (key, "Timeout") == 0) { - gps_data_config.timeout = (int) strtol (value, NULL, 1000); + if (strcasecmp (key, "Pause") == 0) + { + gps_data_config.pause = (int) (strtod (value, &endptr)); + DEBUG ("gps: will use pause %s - %d.\n", value, gps_data_config.pause); } return (0); } @@ -171,12 +237,13 @@ 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); + DEBUG ("gps: will use %s:%s, timeout %d ms, pause %d sec.\n", gps_data_config.host, gps_data_config.port, gps_data_config.timeout, gps_data_config.pause); err = plugin_thread_create (&connector, NULL, gps_collectd_thread, NULL); - if (err != 0) { - WARNING ("pthread_create() failed."); + if (err != 0) + { + ERROR ("gps: pthread_create() failed."); return (-1); } @@ -189,7 +256,8 @@ static int gps_collectd_init (void) */ static int gps_collectd_shutdown (void) { - if (connector != ((pthread_t) 0)) { + if (connector != ((pthread_t) 0)) + { pthread_kill (connector, SIGTERM); connector = (pthread_t) 0; } @@ -205,8 +273,10 @@ static int gps_collectd_shutdown (void) */ void module_register (void) { - gps_data_config.host = sstrdup ("localhost"); - gps_data_config.port = sstrdup ("2947"); + gps_data_config.host = sstrdup (GPS_DEFAULT_HOST); + gps_data_config.port = sstrdup (GPS_DEFAULT_PORT); + gps_data_config.timeout = GPS_DEFAULT_TIMEOUT; + gps_data_config.pause = GPS_DEFAULT_PAUSE; gps_data_read.hdop = 0; gps_data_read.vdop = 0; gps_data_read.satellites = 0; diff --git a/src/gps.pod b/src/gps.pod index e9d50146..540a1627 100644 --- a/src/gps.pod +++ b/src/gps.pod @@ -6,18 +6,26 @@ gps - Documentation of collectd's C =head1 SYNOPSIS - # See collectd.conf(5) - LoadPlugin gps - - Host "localhost" - Port "2947" - Timeout 1000 - +LoadPlugin gps + + # Connect to localhost on gpsd regular port: + Host "127.0.0.1" + Port "2947" + # 15 seconds timeout + Timeout 15 + # Pause of 1 second between readings: + Pause 1 + + =head1 DESCRIPTION The C connects to gpsd on the host machine. -The port and the timeout are configurable. +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 ! =head1 OPTIONS @@ -26,15 +34,19 @@ The port and the timeout are configurable. =item B -The host on which gpsd runs. +The host on which gpsd runs (default localhost). =item B -Port to connect to gpsd on the host machine. +Port to connect to gpsd on the host machine (with quotes), (default 2947). =item B -Timeout in ms. +Timeout in seconds (default 15 sec). + +=item B + +Pause to apply between readings in seconds (default 1 sec). =back @@ -42,21 +54,17 @@ Timeout in ms. =over 4 -=item B +=item B -Number of satelites in view. +Number of satellites in view. 0 means no GPS are visible. -=item B +=item B -Horizontal dilution. +Vertical or horizontal dilution. It should be between 0 and 3. -Look at the documentaiton of your GPS. - -=item B +Look at the documentaiton of your GPS to know more. -Vertical dilution. -Same as above. =head1 SEE ALSO @@ -66,6 +74,6 @@ gpsd =head1 AUTHOR -Nicolas Jourden Enicolas.jourden@laposte.netE +Nicolas JOURDEN Enicolas.jourden at laposte.netE =cut diff --git a/src/types.db b/src/types.db index bfe660e0..03be695d 100644 --- a/src/types.db +++ b/src/types.db @@ -77,9 +77,8 @@ frequency_offset value:GAUGE:-1000000:1000000 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 +satellites value:GAUGE:0:U +dilution_of_precision value:GAUGE:0:U hash_collisions value:DERIVE:0:U http_request_methods value:DERIVE:0:U http_requests value:DERIVE:0:U -- 2.30.2