#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; } if(!temps.size()) { status = "Sensor " + sensorName + " not found"; 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 < results.size(); ++i) { std::cout << results[i]; if(i != (results.size()-1)) {std::cout << ", ";} } std::cout << std::endl; return returnCode; }