Commit eb304da034b7ed33ccf614265714e4b796dd8eea

Authored by Imanol-Mikel Barba Sabariego
1 parent 0e09ef33

Added check_sensors

CMakeLists.txt
... ... @@ -18,6 +18,12 @@ add_executable(check_memfree_freebsd ${SOURCE_FILES_MEMFREE_FREEBSD})
18 18 set(SOURCE_FILES_SMART check_smart/check_smart.cpp check_smart/auxiliar.cpp)
19 19 add_executable(check_smart ${SOURCE_FILES_SMART})
20 20  
  21 +find_library(libsensors libsensors.so)
  22 +set(SOURCE_FILES_SENSORS check_sensors/check_sensors.cpp check_sensors/auxiliar.cpp)
  23 +add_executable(check_sensors ${SOURCE_FILES_SENSORS})
  24 +target_link_libraries(check_sensors ${libsensors})
  25 +
  26 +
21 27 set(SOURCE_FILES_TFTP check_tftp/check_tftp.cpp check_tftp/udp.cpp check_tftp/auxiliar.cpp)
22 28 add_executable(check_tftp ${SOURCE_FILES_TFTP})
23 29  
... ...
check_sensors/auxiliar.cpp 0 → 100644
  1 +//
  2 +// Created by Imanol on 28-may-16.
  3 +//
  4 +
  5 +#include "auxiliar.h"
  6 +
  7 +void timer_handler(int signum) {
  8 + if(signum == SIGVTALRM) {
  9 + std::cout << servicename << " CRITICAL - timeout occurred" << std::endl;
  10 + exit(2);
  11 + }
  12 +}
  13 +
  14 +int str2int(const std::string& str) {
  15 + int num;
  16 + std::stringstream sstream;
  17 + sstream << str;
  18 + if(!(sstream >> num)) {
  19 + throw ConversionException("Integer conversion error");
  20 + }
  21 + return num;
  22 +}
  23 +
  24 +std::string int2str(const int x) {
  25 + std::string str;
  26 + std::stringstream sstream;
  27 + sstream << x;
  28 + sstream >> str;
  29 + return str;
  30 +}
  31 +
  32 +std::string double2str(const double x) {
  33 + std::string str;
  34 + std::stringstream sstream;
  35 + sstream << x;
  36 + sstream >> str;
  37 + return str;
  38 +}
  39 +
  40 +double str2double(const std::string& str) {
  41 + double num;
  42 + std::stringstream sstream;
  43 + sstream << str;
  44 + if(!(sstream >> num)) {
  45 + throw ConversionException("Double conversion error");
  46 + }
  47 + return num;
  48 +}
  49 +
  50 +bool starts_with(const std::string& value, const std::string& begin) {
  51 + return value.rfind(begin,0) == 0;
  52 +}
  53 +
  54 +bool ends_with(const std::string& value, const std::string& ending) {
  55 + if(ending.size() > value.size()) return false;
  56 + return std::equal(ending.rbegin(), ending.rend(), value.rbegin());
  57 +}
  58 +
  59 +int exec(const std::string& cmd, std::string& output) {
  60 + output = "";
  61 + FILE* pipe = popen(cmd.c_str(), "r");
  62 + if(!pipe) {
  63 + std::cout << "Error opening child process" << std::endl;
  64 + exit(3);
  65 + }
  66 + char buffer[128];
  67 + while(!feof(pipe)) {
  68 + if(fgets(buffer, 128, pipe) != NULL) {
  69 + output += buffer;
  70 + }
  71 + }
  72 + return pclose(pipe)/256;
  73 +}
... ...
check_sensors/auxiliar.h 0 → 100644
  1 +//
  2 +// Created by Imanol on 28-may-16.
  3 +//
  4 +
  5 +#ifndef NAGIOS_PLUGINS_AUXILIAR_H
  6 +#define NAGIOS_PLUGINS_AUXILIAR_H
  7 +
  8 +#include <sstream>
  9 +#include <iostream>
  10 +#include <exception>
  11 +
  12 +#include <stdlib.h>
  13 +#include <stdio.h>
  14 +#include <signal.h>
  15 +
  16 +extern const char *servicename;
  17 +
  18 +int str2int(const std::string& str);
  19 +std::string int2str(const int x);
  20 +double str2double(const std::string& str);
  21 +std::string double2str(const double x);
  22 +bool starts_with(const std::string& value, const std::string& begin);
  23 +bool ends_with(const std::string& value, const std::string& ending);
  24 +int exec(const std::string& cmd, std::string& output);
  25 +void timer_handler(int signum);
  26 +
  27 +class ConversionException : public std::exception
  28 +{
  29 +private:
  30 + std::string s;
  31 +public:
  32 + ConversionException(std::string ss) : s(ss) {}
  33 + ~ConversionException() throw () {}
  34 + const char* what() const throw() { return s.c_str(); }
  35 +};
  36 +
  37 +#endif //NAGIOS_PLUGINS_AUXILIAR_H
... ...
check_sensors/check_sensors.cpp 0 → 100644
  1 +#include "check_sensors.h"
  2 +
  3 +const char *servicename = (const char*)"SENSORS";
  4 +
  5 +int getTemps(const std::string& sensorName, std::map<std::string, double>& temps) {
  6 + sensors_chip_name const * cn;
  7 + int c = 0;
  8 + while((cn = sensors_get_detected_chips(0, &c)) != 0) {
  9 + if(!strcmp(sensorName.c_str(), cn->prefix)) {
  10 + sensors_feature const *feat;
  11 + int f = 0;
  12 + while((feat = sensors_get_features(cn, &f)) != 0) {
  13 + std::string feature = feat->name;
  14 + if(starts_with(feature,"temp")) {
  15 + sensors_subfeature const *subf;
  16 + int s = 0;
  17 + while((subf = sensors_get_all_subfeatures(cn, feat, &s)) != 0) {
  18 + std::string subfeature = subf->name;
  19 + if(ends_with(subfeature,"_input")) {
  20 + double value;
  21 + if (subf->flags & SENSORS_MODE_R) {
  22 + int rc = sensors_get_value(cn, subf->number, &value);
  23 + if (rc < 0) {
  24 + return rc;
  25 + } else {
  26 + temps[feature] = value;
  27 + }
  28 + }
  29 + }
  30 + }
  31 + }
  32 + }
  33 + }
  34 + }
  35 + return 0;
  36 +}
  37 +
  38 +int evalStatus(const std::string& sensorName, double warn, double crit, std::string& status) {
  39 + int ret = OK;
  40 + int rc;
  41 + std::map<std::string, double> temps;
  42 + status = sensorName;
  43 +
  44 + if((rc = getTemps(sensorName, temps))) {
  45 + status = "Error retrieving temps from libsensors: " + int2str(rc);
  46 + return UNKN;
  47 + }
  48 +
  49 + for(const std::pair<std::string, double>& entry : temps) {
  50 + std::string feature = entry.first;
  51 + double value = entry.second;
  52 + if(value > crit && ret != CRIT) {
  53 + ret = CRIT;
  54 + } else if(value > warn && ret == OK) {
  55 + ret = WARN;
  56 + }
  57 + status += " " + feature + ": " + double2str(value);
  58 + }
  59 + return ret;
  60 +}
  61 +
  62 +void printVersion() {
  63 + std::cout << "check_sensors v" << VERSION << std::endl << std::endl;
  64 +}
  65 +
  66 +void printHelp(bool longVersion) {
  67 + if(longVersion) {
  68 + printVersion();
  69 + std::cout << "Checks for pending, reallocated or uncorrectable sectors in disks using SMART" << std::endl << "WARNING: Requires the setuid bit to be set to run as root" << std::endl << std::endl;
  70 + printHelp(false);
  71 + std::cout << "Options:" << std::endl;
  72 + std::cout << " -h" << std::endl;
  73 + std::cout << " Print detailed help screen" << std::endl;
  74 + std::cout << " -V" << std::endl;
  75 + std::cout << " Print version information" << std::endl;
  76 + std::cout << " -w DOUBLE" << std::endl;
  77 + std::cout << " Warning temperature level" << std::endl;
  78 + std::cout << " -c DOUBLE" << std::endl;
  79 + std::cout << " Critical temperature level" << std::endl;
  80 + std::cout << " SENSORS" << std::endl;
  81 + std::cout << " sensor names to retrieve temperature data" << std::endl << std::endl;
  82 + return;
  83 + }
  84 + std::cout << "Usage: " << std::endl << "check_sensors [-hV] -w <temp> -c <temp> SENSORS..." << std::endl << std::endl;
  85 +}
  86 +
  87 +void set_timeout(unsigned int sec) {
  88 + struct itimerval timer;
  89 + timer.it_value.tv_sec = sec;
  90 + timer.it_value.tv_usec = 0;
  91 + timer.it_interval.tv_sec = 0;
  92 + timer.it_interval.tv_usec = 0;
  93 + setitimer (ITIMER_VIRTUAL, &timer, 0);
  94 +
  95 + struct sigaction sa;
  96 + memset (&sa, 0, sizeof (sa));
  97 + sa.sa_handler = &timer_handler;
  98 + sigaction (SIGVTALRM, &sa, 0);
  99 +}
  100 +
  101 +int main(int argc, char **argv) {
  102 + set_timeout(10);
  103 + int c;
  104 + char *warningFlag = NULL;
  105 + char *criticalFlag = NULL;
  106 +
  107 + while((c = getopt (argc, argv, "Vhw:c:")) != -1) {
  108 + switch(c) {
  109 + case 'h':
  110 + printHelp(true);
  111 + return OK;
  112 + case 'V':
  113 + printVersion();
  114 + return OK;
  115 + case 'w':
  116 + warningFlag = optarg;
  117 + break;
  118 + case 'c':
  119 + criticalFlag = optarg;
  120 + break;
  121 + case '?':
  122 + printHelp(false);
  123 + return UNKN;
  124 + }
  125 + }
  126 +
  127 + if(warningFlag == NULL) {
  128 + std::cout << "Warning flag not specified" << std::endl;
  129 + return UNKN;
  130 + }
  131 + if(criticalFlag == NULL) {
  132 + std::cout << "Critical flag not specified" << std::endl;
  133 + return UNKN;
  134 + }
  135 + if(optind >= argc) {
  136 + std::cout << "No sensors to check" << std::endl;
  137 + return UNKN;
  138 + }
  139 +
  140 + double warn = 0;
  141 + double crit = 0;
  142 +
  143 + try {
  144 + warn = str2double(warningFlag);
  145 + crit = str2double(criticalFlag);
  146 + } catch(ConversionException e) {
  147 + std::cout << e.what() << std::endl;
  148 + return UNKN;
  149 + }
  150 +
  151 + std::vector<std::string> results;
  152 + int returnCode = OK;
  153 +
  154 + sensors_init(NULL);
  155 + for(int i = optind; i < argc; i++) {
  156 + std::string result;
  157 + switch(evalStatus(argv[i], warn, crit, result)) {
  158 + case OK:
  159 + break;
  160 + case WARN:
  161 + if(returnCode == OK) {returnCode = WARN;}
  162 + break;
  163 + case CRIT:
  164 + returnCode = CRIT;
  165 + break;
  166 + case UNKN:
  167 + returnCode = UNKN;
  168 + break;
  169 + }
  170 + results.push_back(result);
  171 + }
  172 + sensors_cleanup();
  173 +
  174 + std::cout << servicename;
  175 + if(returnCode == OK) {std::cout << " OK - sensors: ";}
  176 + else if(returnCode == WARN) {std::cout << " WARNING - sensors: ";}
  177 + else if(returnCode == CRIT) {std::cout << " CRITICAL - sensors: ";}
  178 + else if(returnCode == UNKN) {std::cout << " UNKNOWN - sensors: ";}
  179 + for(int i = 0; i < (argc-1); i++) {
  180 + std::cout << results[i];
  181 + if(i != (argc-2)) {std::cout << ", ";}
  182 + }
  183 + std::cout << std::endl;
  184 + return returnCode;
  185 +}
... ...
check_sensors/check_sensors.h 0 → 100644
  1 +#ifndef CHECK_SENSORS_H
  2 +#define CHECK_SENSORS_H
  3 +
  4 +#include <iostream>
  5 +#include <map>
  6 +#include <string>
  7 +#include <vector>
  8 +
  9 +#include <stdlib.h>
  10 +#include <string.h>
  11 +#include <sys/time.h>
  12 +#include <unistd.h>
  13 +
  14 +#include "auxiliar.h"
  15 +
  16 +#include <sensors/sensors.h>
  17 +
  18 +#define OK 0
  19 +#define WARN 1
  20 +#define CRIT 2
  21 +#define UNKN 3
  22 +
  23 +#define VERSION "1.0"
  24 +
  25 +int getTemps(const std::string& sensorName, std::map<std::string, double>& temps);
  26 +int evalStatus(const std::string& sensorName, double warn, double crit, std::string& status);
  27 +void printVersion();
  28 +void printHelp(bool longVersion);
  29 +void set_timeout(unsigned int sec);
  30 +
  31 +#endif
... ...