summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: e24bfed)
raw | patch | inline | side by side (parent: e24bfed)
author | anthony <anthony> | |
Fri, 19 May 2006 13:46:16 +0000 (13:46 +0000) | ||
committer | anthony <anthony> | |
Fri, 19 May 2006 13:46:16 +0000 (13:46 +0000) |
'apcaccess status'. The code I used calls 'exit()' if it cannot connect
to the apcupsd daemon. A reasonable action for a standalone program.
Not good for a monitoring daemon. This was completely an oversight on my part.
2. (minor) Some dead code is now defined out if APCMAIN is not defined.
3. (minor) My units in collection.cgi where incorrect.
4. (minor) if the apcups plugin cannot connect to the apcupsd it will
simply not call the submit routines allowing the rrd files to fill with NAN
as expected, rather than submitting zeros.
to the apcupsd daemon. A reasonable action for a standalone program.
Not good for a monitoring daemon. This was completely an oversight on my part.
2. (minor) Some dead code is now defined out if APCMAIN is not defined.
3. (minor) My units in collection.cgi where incorrect.
4. (minor) if the apcups plugin cannot connect to the apcupsd it will
simply not call the submit routines allowing the rrd files to fill with NAN
as expected, rather than submitting zeros.
contrib/collection.cgi | patch | blob | history | |
src/apcups.c | patch | blob | history |
diff --git a/contrib/collection.cgi b/contrib/collection.cgi
index a39828618c7fc1e1b13c76c234b11bacaba66ec5..0d65a767c05ee2d23d9325ced8166d5ba2718bdb 100755 (executable)
--- a/contrib/collection.cgi
+++ b/contrib/collection.cgi
'GPRINT:max:MAX:%5.1lf%sV Max,',
'GPRINT:avg:LAST:%5.1lf%sV Last\l'
],
+ apcups_volt => [
+ 'DEF:line_avg={file}:linev:AVERAGE',
+ 'DEF:line_min={file}:linev:MIN',
+ 'DEF:line_max={file}:linev:MAX',
+ 'DEF:out_avg={file}:outputv:AVERAGE',
+ 'DEF:out_min={file}:outputv:MIN',
+ 'DEF:out_max={file}:outputv:MAX',
+ #"AREA:line_max#$HalfBlue",
+ #"AREA:line_min#$Canvas",
+ #"AREA:out_avg#$HalfGreen",
+ "LINE1:line_avg#$FullBlue:Line Volt",
+ 'GPRINT:line_min:MIN:%5.1lf%sV Min,',
+ 'GPRINT:line_avg:AVERAGE:%5.1lf%sV Avg,',
+ 'GPRINT:line_max:MAX:%5.1lf%sV Max,',
+ 'GPRINT:line_avg:LAST:%5.1lf%sV Last\l',
+ "LINE2:out_avg#$FullGreen:Out Volt",
+ 'GPRINT:out_min:MIN:%5.1lf%sV Min,',
+ 'GPRINT:out_avg:AVERAGE:%5.1lf%sV Avg,',
+ 'GPRINT:out_max:MAX:%5.1lf%sV Max,',
+ 'GPRINT:out_avg:LAST:%5.1lf%sV Last\l'
+ ],
+ apcups_bvolt => [
+ 'DEF:bvolt_avg={file}:battv:AVERAGE',
+ 'DEF:bvolt_min={file}:battv:MIN',
+ 'DEF:bvolt_max={file}:battv:MAX',
+ "AREA:bvolt_max#$HalfBlue",
+ "LINE1:bvolt_avg#$FullBlue:Batt Volt",
+ 'GPRINT:bvolt_min:MIN:%5.1lf%sV Min,',
+ 'GPRINT:bvolt_avg:AVERAGE:%5.1lf%sV Avg,',
+ 'GPRINT:bvolt_max:MAX:%5.1lf%sV Max,',
+ 'GPRINT:bvolt_avg:LAST:%5.1lf%sV Last\l',
+ ],
+ apcups_load => [
+ 'DEF:load_avg={file}:loadpct:AVERAGE',
+ 'DEF:load_min={file}:loadpct:MIN',
+ 'DEF:load_max={file}:loadpct:MAX',
+ "AREA:load_max#$HalfBlue",
+ "LINE1:load_avg#$FullBlue:Batt load",
+ 'GPRINT:load_min:MIN:%5.1lf%s%% Min,',
+ 'GPRINT:load_avg:AVERAGE:%5.1lf%s%% Avg,',
+ 'GPRINT:load_max:MAX:%5.1lf%s%% Max,',
+ 'GPRINT:load_avg:LAST:%5.1lf%s%% Last\l',
+ ],
+ apcups_charge => [
+ 'DEF:charge_avg={file}:bcharge:AVERAGE',
+ 'DEF:charge_min={file}:bcharge:MIN',
+ 'DEF:charge_max={file}:bcharge:MAX',
+ "AREA:charge_max#$HalfBlue",
+ "LINE1:charge_avg#$FullBlue:Batt Charge",
+ 'GPRINT:charge_min:MIN:%5.1lf%s%% Min,',
+ 'GPRINT:charge_avg:AVERAGE:%5.1lf%s%% Avg,',
+ 'GPRINT:charge_max:MAX:%5.1lf%s%% Max,',
+ 'GPRINT:charge_avg:LAST:%5.1lf%s%% Last\l',
+ ],
+ apcups_time => [
+ 'DEF:time_avg={file}:timeleft:AVERAGE',
+ 'DEF:time_min={file}:timeleft:MIN',
+ 'DEF:time_max={file}:timeleft:MAX',
+ "AREA:time_max#$HalfBlue",
+ "LINE1:time_avg#$FullBlue:Time Avail",
+ 'GPRINT:time_min:MIN:%5.1lf%smin Min,',
+ 'GPRINT:time_avg:AVERAGE:%5.1lf%smin Avg,',
+ 'GPRINT:time_max:MAX:%5.1lf%smin Max,',
+ 'GPRINT:time_avg:LAST:%5.1lf%smin Last\l',
+ ],
+ apcups_temp => [
+ 'DEF:temp_avg={file}:itemp:AVERAGE',
+ 'DEF:temp_min={file}:itemp:MIN',
+ 'DEF:temp_max={file}:itemp:MAX',
+ "AREA:temp_max#$HalfBlue",
+ "LINE1:temp_avg#$FullBlue:Temp Avail",
+ 'GPRINT:temp_min:MIN:%5.1lf%s° Min,',
+ 'GPRINT:temp_avg:AVERAGE:%5.1lf%s° Avg,',
+ 'GPRINT:temp_max:MAX:%5.1lf%s° Max,',
+ 'GPRINT:temp_avg:LAST:%5.1lf%s° Last\l',
+ ],
+ apcups_freq => [
+ 'DEF:freq_avg={file}:linefreq:AVERAGE',
+ 'DEF:freq_min={file}:linefreq:MIN',
+ 'DEF:freq_max={file}:linefreq:MAX',
+ "AREA:freq_max#$HalfBlue",
+ "LINE1:freq_avg#$FullBlue:Line Freq",
+ 'GPRINT:freq_min:MIN:%5.1lf%sHz Min,',
+ 'GPRINT:freq_avg:AVERAGE:%5.1lf%sHz Avg,',
+ 'GPRINT:freq_max:MAX:%5.1lf%sHz Max,',
+ 'GPRINT:freq_avg:LAST:%5.1lf%sHz Last\l',
+ ],
vs_threads => [
"DEF:total_avg={file}:total:AVERAGE",
"DEF:total_min={file}:total:MIN",
traffic => ['-t', '{host} {inst} traffic', '-v', 'Bit/s'],
users => ['-t', '{host} users', '-v', 'Users'],
voltage => ['-t', '{host} voltage', '-v', 'Volts'],
+ apcups_volt => ['-t', '{host} APC voltage {inst}', '-v', 'Volts AC'],
+ apcups_bvolt => ['-t', '{host} APC Batt voltage {inst}', '-v', 'Volts DC'],
+ apcups_load => ['-t', '{host} APC Load {inst}', '-v', 'Percent'],
+ apcups_charge => ['-t', '{host} APC Batt Charge {inst}', '-v', 'Percent'],
+ apcups_time => ['-t', '{host} APC Time Left {inst}', '-v', 'Minutes'],
+ apcups_temp => ['-t', '{host} APC Internal Temp {inst}', '-v', '°Celsius'],
+ apcups_freq => ['-t', '{host} APC Line Freq {inst}', '-v', 'Hz'],
vs_threads => ['-t', '{host} threads', '-v', 'Threads'],
vs_memory => ['-t', '{host} memory usage', '-v', 'Bytes'],
vs_processes => ['-t', '{host} processes', '-v', 'Processes'],
cpu => \&output_graph_cpu,
cpufreq => 1,
disk => 1,
+ apcups_volt => 1,
+ apcups_bvolt => 1,
+ apcups_load => 1,
+ apcups_charge => 1,
+ apcups_time => 1,
+ apcups_temp => 1,
+ apcups_freq => 1,
load => 0,
mails => 0,
memory => 0,
diff --git a/src/apcups.c b/src/apcups.c
index 049383da6fe3bc9c80efc68c807d07526fb18796..fb2583e63a50b332bf4ef1eb19892b1b6e87a926 100644 (file)
--- a/src/apcups.c
+++ b/src/apcups.c
#define _(String) (String)
#define N_(String) (String)
#define MAXSTRING 256
+<<<<<<< .mine
+=======
+#define Error_abort0(fmd) generic_error_out(__FILE__, __LINE__, fmd)
+>>>>>>> .r733
#define MODULE_NAME "apcups"
/* Prototypes */
+<<<<<<< .mine
+=======
static void generic_error_out(const char *, int , const char *, ...);
+>>>>>>> .r733
/* Default values for contacting daemon */
static char *host = "localhost";
static int port = NISPORT;
static struct sockaddr_in tcp_serv_addr; /* socket information */
+static int net_errno = 0; /* error number -- not yet implemented */
static char *net_errmsg = NULL; /* pointer to error message */
static char net_errbuf[256]; /* error message buffer for messages */
+<<<<<<< .mine
+struct sockaddr_in tcp_serv_addr; /* socket information */
+int net_errno = 0; /* error number -- not yet implemented */
+char *net_errmsg = NULL; /* pointer to error message */
+char net_errbuf[256]; /* error message buffer for messages */
+
+void (*error_cleanup) (void) = NULL;
+
+=======
+>>>>>>> .r733
/*
* The following are only if not compiled to test the module with its own main.
*/
#endif /* ifndef APCMAIN */
+<<<<<<< .mine
+struct apc_detail_s {
+ int connected;
+ float linev;
+ float loadpct;
+ float bcharge;
+ float timeleft;
+ float outputv;
+ float itemp;
+ float battv;
+ float linefreq;
+=======
struct apc_detail_s
{
float linev;
float itemp;
float battv;
float linefreq;
+>>>>>>> .r733
};
#define BIG_BUF 4096
+<<<<<<< .mine
+
+#define BIG_BUF 5000
+
+/* Implement snprintf */
+int asnprintf(char *str, size_t size, const char *fmt, ...)
+{
+#ifdef HAVE_VSNPRINTF
+ va_list arg_ptr;
+ int len;
+
+ va_start(arg_ptr, fmt);
+ len = vsnprintf(str, size, fmt, arg_ptr);
+ va_end(arg_ptr);
+
+ str[size - 1] = 0;
+ return len;
+
+#else
+
+ va_list arg_ptr;
+ int len;
+ char *buf;
+
+ buf = (char *)malloc(BIG_BUF);
+
+ va_start(arg_ptr, fmt);
+ len = vsprintf(buf, fmt, arg_ptr);
+ va_end(arg_ptr);
+
+ if (len >= BIG_BUF){
+ syslog(LOG_ERR, "apcups: asnprintf(): Buffer overflow");
+ return(0);
+ }
+
+ memcpy(str, buf, size);
+ str[size - 1] = 0;
+
+ free(buf);
+ return len;
+#endif
+}
+
+/* Implement vsnprintf() */
+int avsnprintf(char *str, size_t size, const char *format, va_list ap)
+{
+#ifdef HAVE_VSNPRINTF
+ int len;
+
+ len = vsnprintf(str, size, format, ap);
+ str[size - 1] = 0;
+
+ return len;
+
+#else
+
+ int len;
+ char *buf;
+
+ buf = (char *)malloc(BIG_BUF);
+
+ len = vsprintf(buf, format, ap);
+ if (len >= BIG_BUF){
+ syslog(LOG_ERR, "apcups: avsnprintf(): Buffer overflow");
+ return(0);
+ }
+
+ memcpy(str, buf, size);
+ str[size - 1] = 0;
+
+ free(buf);
+ return len;
+#endif
+}
+
+=======
+>>>>>>> .r733
/*
+<<<<<<< .mine
+=======
* Subroutine normally called by macro error_abort() to print
* FATAL ERROR message and supplied error message
*/
}
/*
+>>>>>>> .r733
* Read nbytes from the network.
* It is possible that the total bytes require in several
* read requests
} while (nread == -1 && (errno == EINTR || errno == EAGAIN));
if (nread <= 0) {
+ net_errno = errno;
return (nread); /* error, or EOF */
}
* Write nbytes to the network.
* It may require several writes.
*/
-static int write_nbytes(int fd, void *buf, int buflen)
+static int write_nbytes(int fd, char *ptr, int nbytes)
{
- int nleft;
- int nwritten;
- char *ptr;
-
- ptr = (char *) buf;
+ int nleft, nwritten;
- nleft = buflen;
- while (nleft > 0)
- {
+ nleft = nbytes;
+ while (nleft > 0) {
nwritten = write(fd, ptr, nleft);
- if (nwritten <= 0)
- {
- syslog (LOG_ERR, "Writing to socket failed: %s", strerror (errno));
- return (nwritten);
+ if (nwritten <= 0) {
+ net_errno = errno;
+ return (nwritten); /* error */
}
nleft -= nwritten;
ptr += nwritten;
}
- /* If we get here, (nleft <= 0) is true */
- return (buflen);
+ return (nbytes - nleft);
}
/* Close the network connection */
short pktsiz = 0;
/* send EOF sentinel */
- write_nbytes (sockfd, &pktsiz, sizeof(short));
+ write_nbytes(sockfd, (char *) &pktsiz, sizeof(short));
close (sockfd);
}
* Send a message over the network. The send consists of
* two network packets. The first is sends a short containing
* the length of the data packet which follows.
- * Returns zero on success
- * Returns non-zero on error
+ * Returns number of bytes sent
+ * Returns -1 on error
*/
static int net_send(int sockfd, char *buff, int len)
{
int rc;
- short packet_size;
+ short pktsiz;
/* send short containing size of data packet */
- packet_size = htons ((short) len);
-
- rc = write_nbytes(sockfd, &packet_size, sizeof (packet_size));
- if (rc != sizeof(packet_size))
- return (-1);
+ pktsiz = htons((short)len);
+ rc = write_nbytes(sockfd, (char *)&pktsiz, sizeof(short));
+ if (rc != sizeof(short)) {
+ net_errmsg = "net_send: write_nbytes error of length prefix\n";
+ return -1;
+ }
/* send data packet */
- rc = write_nbytes (sockfd, buff, len);
- if (rc != len)
- return (-1);
+ rc = write_nbytes(sockfd, buff, len);
+ if (rc != len) {
+ net_errmsg = "net_send: write_nbytes error\n";
+ return -1;
+ }
- return (0);
+ return rc;
}
+
/* Get and print status from apcupsd NIS server */
static int do_pthreads_status(char *host, int port, struct apc_detail_s *apcups_detail)
{
+<<<<<<< .mine
+ int sockfd, n;
+ char recvline[MAXSTRING + 1];
+ char *tokptr;
+
+ if ((sockfd = net_open(host, NULL, port)) < 0){
+ syslog(LOG_ERR, "apcups: Cannot open connection: %s",
+ net_errmsg);
+ net_errmsg = NULL;
+ return;
+ }
+
+ net_send(sockfd, "status", 6);
+
+ while ((n = net_recv(sockfd, recvline, sizeof(recvline))) > 0) {
+ recvline[n] = 0;
+#ifdef APCMAIN
+ fputs(recvline, stdout);
+#endif /* ifdef APCMAIN */
+=======
int sockfd;
int n;
char recvline[MAXSTRING + 1];
@@ -389,14 +518,93 @@ static int do_pthreads_status(char *host, int port, struct apc_detail_s *apcups_
#else
# define PRINT_VALUE(name, val) /**/
#endif
+>>>>>>> .r733
+<<<<<<< .mine
+ tokptr = strtok(recvline,":");
+ while(tokptr != NULL) {
+ /* Look for Limit_Add */
+ if(strncmp("LINEV",tokptr,5) == 0) {
+#ifdef APCMAIN
+ fprintf(stdout," Found LINEV.\n");
+#endif /* ifdef APCMAIN */
+ tokptr = strtok(NULL," \t");
+ if(tokptr == NULL) continue;
+ apcups_detail->linev = atof (tokptr);
+ }else if(strncmp("BATTV",tokptr,5) == 0) {
+#ifdef APCMAIN
+ fprintf(stdout," Found BATTV.\n");
+#endif /* ifdef APCMAIN */
+ tokptr = strtok(NULL," \t");
+ if(tokptr == NULL) continue;
+ apcups_detail->battv = atof (tokptr);
+ }else if(strncmp("ITEMP",tokptr,5) == 0) {
+#ifdef APCMAIN
+ fprintf(stdout," Found ITEMP.\n");
+#endif /* ifdef APCMAIN */
+ tokptr = strtok(NULL," \t");
+ if(tokptr == NULL) continue;
+ apcups_detail->itemp = atof (tokptr);
+ }else if(strncmp("LOADPCT",tokptr,7) == 0) {
+#ifdef APCMAIN
+ fprintf(stdout," Found LOADPCT.\n");
+#endif /* ifdef APCMAIN */
+ tokptr = strtok(NULL," \t");
+ if(tokptr == NULL) continue;
+ apcups_detail->loadpct = atof (tokptr);
+ }else if(strncmp("BCHARGE",tokptr,7) == 0) {
+#ifdef APCMAIN
+ fprintf(stdout," Found BCHARGE.\n");
+#endif /* ifdef APCMAIN */
+ tokptr = strtok(NULL," \t");
+ if(tokptr == NULL) continue;
+ apcups_detail->bcharge = atof (tokptr);
+ }else if(strncmp("OUTPUTV",tokptr,7) == 0) {
+#ifdef APCMAIN
+ fprintf(stdout," Found OUTPUTV.\n");
+#endif /* ifdef APCMAIN */
+ tokptr = strtok(NULL," \t");
+ if(tokptr == NULL) continue;
+ apcups_detail->outputv = atof (tokptr);
+ }else if(strncmp("LINEFREQ",tokptr,8) == 0) {
+#ifdef APCMAIN
+ fprintf(stdout," Found LINEFREQ.\n");
+#endif /* ifdef APCMAIN */
+ tokptr = strtok(NULL," \t");
+ if(tokptr == NULL) continue;
+ apcups_detail->linefreq = atof (tokptr);
+ }else if(strncmp("TIMELEFT",tokptr,8) == 0) {
+#ifdef APCMAIN
+ fprintf(stdout," Found TIMELEFT.\n");
+#endif /* ifdef APCMAIN */
+ tokptr = strtok(NULL," \t");
+ if(tokptr == NULL) continue;
+ apcups_detail->timeleft = atof (tokptr);
+ } /* */
+ tokptr = strtok(NULL,":");
+ }
+ }
+=======
/* TODO: Keep the socket open, if possible */
if ((sockfd = net_open (host, NULL, port)) < 0)
{
syslog (LOG_ERR, "apcups plugin: Connecting to the apcupsd failed.");
return (-1);
}
+>>>>>>> .r733
+<<<<<<< .mine
+ if (n < 0) {
+ syslog(LOG_ERR, "apcups: Error recieving data: %s",
+ net_errmsg);
+ net_errmsg = NULL;
+ return;
+ }
+ /* signal that we did in fact connect. */
+ apcups_detail->connected = 1;
+
+ net_close(sockfd);
+=======
net_send (sockfd, "status", 6);
while ((n = net_recv (sockfd, recvline, sizeof (recvline))) > 0)
@@ -441,15 +649,13 @@ static int do_pthreads_status(char *host, int port, struct apc_detail_s *apcups_
} /* while (tokptr != NULL) */
}
- net_close (sockfd);
-
if (n < 0)
- {
- syslog (LOG_WARNING, "apcups plugin: Error reading from socket");
- return (-1);
- }
+ Error_abort0(net_errmsg);
+
+ net_close(sockfd);
return (0);
+>>>>>>> .r733
}
#ifdef APCMAIN
/* we are not really going to use this */
struct apc_detail_s apcups_detail;
+<<<<<<< .mine
+ openlog("apcups",LOG_PID | LOG_NDELAY | LOG_LOCAL1);
+
+ if (!*host || strcmp(host, "0.0.0.0") == 0)
+ host = "localhost";
+
+ do_pthreads_status(host, port, &apcups_detail);
+
+ return 0;
+=======
if (!*host || strcmp(host, "0.0.0.0") == 0)
host = "localhost";
do_pthreads_status(host, port, &apcups_detail);
return 0;
+>>>>>>> .r733
}
#else
static void apcups_init (void)
apcups_detail.itemp = 0.0;
apcups_detail.battv = 0.0;
apcups_detail.linefreq = 0.0;
+ apcups_detail.connected = 0;
if (!*host || strcmp(host, "0.0.0.0") == 0)
do_pthreads_status(host, port, &apcups_detail);
+ /*
+ * if we did not connect then do not bother submitting
+ * zeros. We want rrd files to have NAN.
+ */
+ if(!apcups_detail.connected) return;
+
apcups_submit (host, &apcups_detail);
apc_bvolt_submit (host, &apcups_detail);
apc_load_submit (host, &apcups_detail);