From eb304da034b7ed33ccf614265714e4b796dd8eea Mon Sep 17 00:00:00 2001 From: Imanol-Mikel Barba Sabariego Date: Sat, 10 Oct 2020 01:27:27 +0100 Subject: [PATCH] Added check_sensors --- CMakeLists.txt | 6 ++++++ check_sensors/auxiliar.cpp | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ check_sensors/auxiliar.h | 37 +++++++++++++++++++++++++++++++++++++ check_sensors/check_sensors.cpp | 185 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ check_sensors/check_sensors.h | 31 +++++++++++++++++++++++++++++++ 5 files changed, 332 insertions(+), 0 deletions(-) create mode 100644 check_sensors/auxiliar.cpp create mode 100644 check_sensors/auxiliar.h create mode 100644 check_sensors/check_sensors.cpp create mode 100644 check_sensors/check_sensors.h diff --git a/CMakeLists.txt b/CMakeLists.txt index e6f01c3..7d2decd 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,6 +18,12 @@ add_executable(check_memfree_freebsd ${SOURCE_FILES_MEMFREE_FREEBSD}) set(SOURCE_FILES_SMART check_smart/check_smart.cpp check_smart/auxiliar.cpp) add_executable(check_smart ${SOURCE_FILES_SMART}) +find_library(libsensors libsensors.so) +set(SOURCE_FILES_SENSORS check_sensors/check_sensors.cpp check_sensors/auxiliar.cpp) +add_executable(check_sensors ${SOURCE_FILES_SENSORS}) +target_link_libraries(check_sensors ${libsensors}) + + set(SOURCE_FILES_TFTP check_tftp/check_tftp.cpp check_tftp/udp.cpp check_tftp/auxiliar.cpp) add_executable(check_tftp ${SOURCE_FILES_TFTP}) diff --git a/check_sensors/auxiliar.cpp b/check_sensors/auxiliar.cpp new file mode 100644 index 0000000..4a4569c --- /dev/null +++ b/check_sensors/auxiliar.cpp @@ -0,0 +1,73 @@ +// +// Created by Imanol on 28-may-16. +// + +#include "auxiliar.h" + +void timer_handler(int signum) { + if(signum == SIGVTALRM) { + std::cout << servicename << " CRITICAL - timeout occurred" << std::endl; + exit(2); + } +} + +int str2int(const std::string& str) { + int num; + std::stringstream sstream; + sstream << str; + if(!(sstream >> num)) { + throw ConversionException("Integer conversion error"); + } + return num; +} + +std::string int2str(const int x) { + std::string str; + std::stringstream sstream; + sstream << x; + sstream >> str; + return str; +} + +std::string double2str(const double x) { + std::string str; + std::stringstream sstream; + sstream << x; + sstream >> str; + return str; +} + +double str2double(const std::string& str) { + double num; + std::stringstream sstream; + sstream << str; + if(!(sstream >> num)) { + throw ConversionException("Double conversion error"); + } + return num; +} + +bool starts_with(const std::string& value, const std::string& begin) { + return value.rfind(begin,0) == 0; +} + +bool ends_with(const std::string& value, const std::string& ending) { + if(ending.size() > value.size()) return false; + return std::equal(ending.rbegin(), ending.rend(), value.rbegin()); +} + +int exec(const std::string& cmd, std::string& output) { + output = ""; + FILE* pipe = popen(cmd.c_str(), "r"); + if(!pipe) { + std::cout << "Error opening child process" << std::endl; + exit(3); + } + char buffer[128]; + while(!feof(pipe)) { + if(fgets(buffer, 128, pipe) != NULL) { + output += buffer; + } + } + return pclose(pipe)/256; +} diff --git a/check_sensors/auxiliar.h b/check_sensors/auxiliar.h new file mode 100644 index 0000000..de5c193 --- /dev/null +++ b/check_sensors/auxiliar.h @@ -0,0 +1,37 @@ +// +// Created by Imanol on 28-may-16. +// + +#ifndef NAGIOS_PLUGINS_AUXILIAR_H +#define NAGIOS_PLUGINS_AUXILIAR_H + +#include +#include +#include + +#include +#include +#include + +extern const char *servicename; + +int str2int(const std::string& str); +std::string int2str(const int x); +double str2double(const std::string& str); +std::string double2str(const double x); +bool starts_with(const std::string& value, const std::string& begin); +bool ends_with(const std::string& value, const std::string& ending); +int exec(const std::string& cmd, std::string& output); +void timer_handler(int signum); + +class ConversionException : public std::exception +{ +private: + std::string s; +public: + ConversionException(std::string ss) : s(ss) {} + ~ConversionException() throw () {} + const char* what() const throw() { return s.c_str(); } +}; + +#endif //NAGIOS_PLUGINS_AUXILIAR_H diff --git a/check_sensors/check_sensors.cpp b/check_sensors/check_sensors.cpp new file mode 100644 index 0000000..5759a75 --- /dev/null +++ b/check_sensors/check_sensors.cpp @@ -0,0 +1,185 @@ +#include "check_sensors.h" + +const char *servicename = (const char*)"SENSORS"; + +int getTemps(const std::string& sensorName, std::map& temps) { + sensors_chip_name const * cn; + int c = 0; + while((cn = sensors_get_detected_chips(0, &c)) != 0) { + if(!strcmp(sensorName.c_str(), cn->prefix)) { + sensors_feature const *feat; + int f = 0; + while((feat = sensors_get_features(cn, &f)) != 0) { + std::string feature = feat->name; + if(starts_with(feature,"temp")) { + sensors_subfeature const *subf; + int s = 0; + while((subf = sensors_get_all_subfeatures(cn, feat, &s)) != 0) { + std::string subfeature = subf->name; + if(ends_with(subfeature,"_input")) { + double value; + if (subf->flags & SENSORS_MODE_R) { + int rc = sensors_get_value(cn, subf->number, &value); + if (rc < 0) { + return rc; + } else { + temps[feature] = value; + } + } + } + } + } + } + } + } + return 0; +} + +int evalStatus(const std::string& sensorName, double warn, double crit, std::string& status) { + int ret = OK; + int rc; + std::map temps; + status = sensorName; + + if((rc = getTemps(sensorName, temps))) { + status = "Error retrieving temps from libsensors: " + int2str(rc); + return UNKN; + } + + for(const std::pair& entry : temps) { + std::string feature = entry.first; + double value = entry.second; + if(value > crit && ret != CRIT) { + ret = CRIT; + } else if(value > warn && ret == OK) { + ret = WARN; + } + status += " " + feature + ": " + double2str(value); + } + return ret; +} + +void printVersion() { + std::cout << "check_sensors v" << VERSION << std::endl << std::endl; +} + +void printHelp(bool longVersion) { + if(longVersion) { + printVersion(); + 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; + printHelp(false); + std::cout << "Options:" << std::endl; + std::cout << " -h" << std::endl; + std::cout << " Print detailed help screen" << std::endl; + std::cout << " -V" << std::endl; + std::cout << " Print version information" << std::endl; + std::cout << " -w DOUBLE" << std::endl; + std::cout << " Warning temperature level" << std::endl; + std::cout << " -c DOUBLE" << std::endl; + std::cout << " Critical temperature level" << std::endl; + std::cout << " SENSORS" << std::endl; + std::cout << " sensor names to retrieve temperature data" << std::endl << std::endl; + return; + } + std::cout << "Usage: " << std::endl << "check_sensors [-hV] -w -c SENSORS..." << std::endl << std::endl; +} + +void set_timeout(unsigned int sec) { + struct itimerval timer; + timer.it_value.tv_sec = sec; + timer.it_value.tv_usec = 0; + timer.it_interval.tv_sec = 0; + timer.it_interval.tv_usec = 0; + setitimer (ITIMER_VIRTUAL, &timer, 0); + + struct sigaction sa; + memset (&sa, 0, sizeof (sa)); + sa.sa_handler = &timer_handler; + sigaction (SIGVTALRM, &sa, 0); +} + +int main(int argc, char **argv) { + set_timeout(10); + int c; + char *warningFlag = NULL; + char *criticalFlag = NULL; + + while((c = getopt (argc, argv, "Vhw:c:")) != -1) { + switch(c) { + case 'h': + printHelp(true); + return OK; + case 'V': + printVersion(); + return OK; + case 'w': + warningFlag = optarg; + break; + case 'c': + criticalFlag = optarg; + break; + case '?': + printHelp(false); + return UNKN; + } + } + + if(warningFlag == NULL) { + std::cout << "Warning flag not specified" << std::endl; + return UNKN; + } + if(criticalFlag == NULL) { + std::cout << "Critical flag not specified" << std::endl; + return UNKN; + } + if(optind >= argc) { + std::cout << "No sensors to check" << std::endl; + return UNKN; + } + + double warn = 0; + double crit = 0; + + try { + warn = str2double(warningFlag); + crit = str2double(criticalFlag); + } catch(ConversionException e) { + std::cout << e.what() << std::endl; + return UNKN; + } + + std::vector results; + int returnCode = OK; + + sensors_init(NULL); + for(int i = optind; i < argc; i++) { + std::string result; + switch(evalStatus(argv[i], warn, crit, result)) { + case OK: + break; + case WARN: + if(returnCode == OK) {returnCode = WARN;} + break; + case CRIT: + returnCode = CRIT; + break; + case UNKN: + returnCode = UNKN; + break; + } + results.push_back(result); + } + sensors_cleanup(); + + std::cout << servicename; + if(returnCode == OK) {std::cout << " OK - sensors: ";} + else if(returnCode == WARN) {std::cout << " WARNING - sensors: ";} + else if(returnCode == CRIT) {std::cout << " CRITICAL - sensors: ";} + else if(returnCode == UNKN) {std::cout << " UNKNOWN - sensors: ";} + for(int i = 0; i < (argc-1); i++) { + std::cout << results[i]; + if(i != (argc-2)) {std::cout << ", ";} + } + std::cout << std::endl; + return returnCode; +} diff --git a/check_sensors/check_sensors.h b/check_sensors/check_sensors.h new file mode 100644 index 0000000..26f9516 --- /dev/null +++ b/check_sensors/check_sensors.h @@ -0,0 +1,31 @@ +#ifndef CHECK_SENSORS_H +#define CHECK_SENSORS_H + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "auxiliar.h" + +#include + +#define OK 0 +#define WARN 1 +#define CRIT 2 +#define UNKN 3 + +#define VERSION "1.0" + +int getTemps(const std::string& sensorName, std::map& temps); +int evalStatus(const std::string& sensorName, double warn, double crit, std::string& status); +void printVersion(); +void printHelp(bool longVersion); +void set_timeout(unsigned int sec); + +#endif -- libgit2 0.22.2