Commit eb304da034b7ed33ccf614265714e4b796dd8eea
1 parent
0e09ef33
Added check_sensors
Showing
5 changed files
with
332 additions
and
0 deletions
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 | ... | ... |