X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fapcups.c;h=50c45e7bdb051b8bca91f920b18aa1ebd1c2e4b7;hb=0a8741b9061f8df4a78a448c021612db06e17425;hp=b4bc0997e6c3e7d309d13e23225edef31ca7f465;hpb=0d80072344ea5322c34f716ed77a5319a62bfc96;p=collectd.git diff --git a/src/apcups.c b/src/apcups.c index b4bc0997..50c45e7b 100644 --- a/src/apcups.c +++ b/src/apcups.c @@ -25,9 +25,9 @@ **/ #include "collectd.h" + #include "common.h" /* rrd_update_file */ #include "plugin.h" /* plugin_register, plugin_submit */ -#include "configfile.h" /* cf_register */ #if HAVE_SYS_TYPES_H # include @@ -40,6 +40,10 @@ # include #endif +#ifndef APCUPS_SERVER_TIMEOUT +# define APCUPS_SERVER_TIMEOUT 15.0 +#endif + #ifndef APCUPS_DEFAULT_NODE # define APCUPS_DEFAULT_NODE "localhost" #endif @@ -51,17 +55,17 @@ /* * Private data types */ -struct apc_detail_s +typedef struct { - double linev; - double loadpct; - double bcharge; - double timeleft; - double outputv; - double itemp; - double battv; - double linefreq; -}; + gauge_t linev; + gauge_t loadpct; + gauge_t bcharge; + gauge_t timeleft; + gauge_t outputv; + gauge_t itemp; + gauge_t battv; + gauge_t linefreq; +} apc_detail_t; /* * Private variables @@ -85,7 +89,7 @@ static int net_shutdown (int *fd) if ((fd == NULL) || (*fd < 0)) return (EINVAL); - swrite (*fd, (void *) &packet_size, sizeof (packet_size)); + (void)swrite (*fd, (void *) &packet_size, sizeof (packet_size)); close (*fd); *fd = -1; @@ -111,15 +115,14 @@ static int net_open (char const *node, char const *service) { int sd; int status; - struct addrinfo ai_hints; struct addrinfo *ai_return; struct addrinfo *ai_list; - /* Resolve name */ - memset (&ai_hints, 0, sizeof (ai_hints)); /* TODO: Change this to `AF_UNSPEC' if apcupsd can handle IPv6 */ - ai_hints.ai_family = AF_INET; - ai_hints.ai_socktype = SOCK_STREAM; + struct addrinfo ai_hints = { + .ai_family = AF_INET, + .ai_socktype = SOCK_STREAM + }; status = getaddrinfo (node, service, &ai_hints, &ai_return); if (status != 0) @@ -250,14 +253,12 @@ static int net_send (int *sockfd, const char *buff, int len) /* Get and print status from apcupsd NIS server */ static int apc_query_server (char const *node, char const *service, - struct apc_detail_s *apcups_detail) + apc_detail_t *apcups_detail) { int n; char recvline[1024]; char *tokptr; char *toksaveptr; - char *key; - double value; _Bool retry = 1; int status; @@ -322,17 +323,17 @@ static int apc_query_server (char const *node, char const *service, printf ("net_recv = `%s';\n", recvline); #endif /* if APCMAIN */ - if (strncmp ("END APC", recvline, strlen ("END APC")) == 0) - break; - toksaveptr = NULL; tokptr = strtok_r (recvline, " :\t", &toksaveptr); while (tokptr != NULL) { - key = tokptr; + char *key = tokptr; if ((tokptr = strtok_r (NULL, " :\t", &toksaveptr)) == NULL) continue; - value = atof (tokptr); + + gauge_t value; + if (strtogauge (tokptr, &value) != 0) + continue; PRINT_VALUE (key, value); @@ -380,9 +381,9 @@ static int apc_query_server (char const *node, char const *service, static int apcups_config (oconfig_item_t *ci) { - int i; + _Bool persistent_conn_set = 0; - for (i = 0; i < ci->children_num; i++) + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; @@ -392,34 +393,44 @@ static int apcups_config (oconfig_item_t *ci) cf_util_get_service (child, &conf_service); else if (strcasecmp (child->key, "ReportSeconds") == 0) cf_util_get_boolean (child, &conf_report_seconds); - else if (strcasecmp (child->key, "PersistentConnection") == 0) + else if (strcasecmp (child->key, "PersistentConnection") == 0) { cf_util_get_boolean (child, &conf_persistent_conn); + persistent_conn_set = 1; + } else ERROR ("apcups plugin: Unknown config option \"%s\".", child->key); } + if (!persistent_conn_set) { + double interval = CDTIME_T_TO_DOUBLE(plugin_get_interval()); + if (interval > APCUPS_SERVER_TIMEOUT) { + NOTICE ("apcups plugin: Plugin poll interval set to %.3f seconds. " + "Apcupsd NIS socket timeout is %.3f seconds, " + "PersistentConnection disabled by default.", + interval, APCUPS_SERVER_TIMEOUT); + conf_persistent_conn = 0; + } + } + return (0); } /* int apcups_config */ -static void apc_submit_generic (const char *type, const char *type_inst, double value) +static void apc_submit_generic (const char *type, const char *type_inst, gauge_t value) { - value_t values[1]; - value_list_t vl = VALUE_LIST_INIT; - - values[0].gauge = value; + if (isnan (value)) + return; - vl.values = values; + value_list_t vl = VALUE_LIST_INIT; + vl.values = &(value_t) { .gauge = value }; vl.values_len = 1; - sstrncpy (vl.host, hostname_g, sizeof (vl.host)); sstrncpy (vl.plugin, "apcups", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, "", sizeof (vl.plugin_instance)); sstrncpy (vl.type, type, sizeof (vl.type)); sstrncpy (vl.type_instance, type_inst, sizeof (vl.type_instance)); plugin_dispatch_values (&vl); } -static void apc_submit (struct apc_detail_s *apcups_detail) +static void apc_submit (apc_detail_t const *apcups_detail) { apc_submit_generic ("voltage", "input", apcups_detail->linev); apc_submit_generic ("voltage", "output", apcups_detail->outputv); @@ -433,33 +444,27 @@ static void apc_submit (struct apc_detail_s *apcups_detail) static int apcups_read (void) { - struct apc_detail_s apcups_detail; - int status; - - apcups_detail.linev = -1.0; - apcups_detail.outputv = -1.0; - apcups_detail.battv = -1.0; - apcups_detail.loadpct = -1.0; - apcups_detail.bcharge = -1.0; - apcups_detail.timeleft = NAN; - apcups_detail.itemp = -300.0; - apcups_detail.linefreq = -1.0; - - status = apc_query_server ((conf_node == NULL) ? APCUPS_DEFAULT_NODE : conf_node, - (conf_service == NULL) ? APCUPS_DEFAULT_SERVICE : conf_service, - &apcups_detail); - - /* - * if we did not connect then do not bother submitting - * zeros. We want rrd files to have NAN. - */ + apc_detail_t apcups_detail = { + .linev = NAN, + .outputv = NAN, + .battv = NAN, + .loadpct = NAN, + .bcharge = NAN, + .timeleft = NAN, + .itemp = NAN, + .linefreq = NAN, + }; + + int status = apc_query_server (conf_node == NULL + ? APCUPS_DEFAULT_NODE + : conf_node, + conf_service, &apcups_detail); if (status != 0) { - DEBUG ("apcups plugin: apc_query_server (%s, %s) = %i", - (conf_node == NULL) ? APCUPS_DEFAULT_NODE : conf_node, - (conf_service == NULL) ? APCUPS_DEFAULT_SERVICE : conf_service, - status); - return (-1); + DEBUG ("apcups plugin: apc_query_server (\"%s\", \"%s\") = %d", + conf_node == NULL ? APCUPS_DEFAULT_NODE : conf_node, + conf_service, status); + return (status); } apc_submit (&apcups_detail);