summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLorenz Kästle <12514511+RincewindsHat@users.noreply.github.com>2026-06-08 07:35:45 +0200
committerGitHub <noreply@github.com>2026-06-08 07:35:45 +0200
commit992a4555ac975285f959dd2d3228b1d71ab23123 (patch)
tree7d2566e1051a5d8f61b7f2ec839b086c5898ba0b
parent44e1913da4d227aaabb7b5ccfae65d879082a5e4 (diff)
downloadmonitoring-plugins-992a4555ac975285f959dd2d3228b1d71ab23123.tar.gz
check_ups: implement modern output (#2272)
Co-authored-by: Lorenz Kästle <lorenz.kaestle@netways.de>
-rw-r--r--plugins/check_ups.c367
-rw-r--r--plugins/check_ups.d/config.h79
2 files changed, 250 insertions, 196 deletions
diff --git a/plugins/check_ups.c b/plugins/check_ups.c
index 54decce3..ac6bf574 100644
--- a/plugins/check_ups.c
+++ b/plugins/check_ups.c
@@ -36,6 +36,9 @@ const char *progname = "check_ups";
36const char *copyright = "2000-2024"; 36const char *copyright = "2000-2024";
37const char *email = "devel@monitoring-plugins.org"; 37const char *email = "devel@monitoring-plugins.org";
38 38
39#include "output.h"
40#include "perfdata.h"
41#include "thresholds.h"
39#include "common.h" 42#include "common.h"
40#include "netutils.h" 43#include "netutils.h"
41#include "utils.h" 44#include "utils.h"
@@ -86,264 +89,273 @@ int main(int argc, char **argv) {
86 /* set socket timeout */ 89 /* set socket timeout */
87 alarm(socket_timeout); 90 alarm(socket_timeout);
88 91
92 mp_check overall = mp_check_init();
93
94 mp_subcheck sc_retrieve_status = mp_subcheck_init();
95
89 /* get the ups status if possible */ 96 /* get the ups status if possible */
90 determine_status_result query_result = determine_status(config); 97 determine_status_result query_result = determine_status(config);
91 if (query_result.errorcode != OK) { 98 if (query_result.errorcode != OK) {
92 return STATE_CRITICAL; 99 xasprintf(&sc_retrieve_status.output, "%s", "Failed to retrieve status from UPS tools");
100 mp_add_subcheck_to_check(&overall, sc_retrieve_status);
101 mp_exit(overall);
93 } 102 }
94 103
104 xasprintf(&sc_retrieve_status.output, "%s", "Retrieved status from UPS tools");
105 mp_add_subcheck_to_check(&overall, sc_retrieve_status);
106
95 int ups_status_flags = query_result.ups_status; 107 int ups_status_flags = query_result.ups_status;
96 int supported_options = query_result.supported_options; 108 int supported_options = query_result.supported_options;
97 109
98 // Exit result 110 // Exit result
99 mp_state_enum result = STATE_UNKNOWN; 111 mp_subcheck sc_ups_status = mp_subcheck_init();
100 char *message = NULL;
101 112
102 if (supported_options & UPS_STATUS) { 113 if (supported_options & UPS_STATUS) {
103 char *ups_status = strdup(""); 114 mp_state_enum ups_state_result = STATE_OK;
104 result = STATE_OK;
105 115
106 if (ups_status_flags & UPSSTATUS_OFF) { 116 if (ups_status_flags & UPSSTATUS_OFF) {
107 xasprintf(&ups_status, "Off"); 117 xasprintf(&sc_ups_status.output, "Off");
108 result = STATE_CRITICAL; 118 ups_state_result = STATE_CRITICAL;
109 } else if ((ups_status_flags & (UPSSTATUS_OB | UPSSTATUS_LB)) == 119 } else if ((ups_status_flags & (UPSSTATUS_OB | UPSSTATUS_LB)) ==
110 (UPSSTATUS_OB | UPSSTATUS_LB)) { 120 (UPSSTATUS_OB | UPSSTATUS_LB)) {
111 xasprintf(&ups_status, _("On Battery, Low Battery")); 121 xasprintf(&sc_ups_status.output, _("On Battery, Low Battery"));
112 result = STATE_CRITICAL; 122 ups_state_result = STATE_CRITICAL;
113 } else { 123 } else {
114 if (ups_status_flags & UPSSTATUS_OL) { 124 if (ups_status_flags & UPSSTATUS_OL) {
115 xasprintf(&ups_status, "%s%s", ups_status, _("Online")); 125 xasprintf(&sc_ups_status.output, "%s%s", sc_ups_status.output, _("Online"));
116 } 126 }
117 if (ups_status_flags & UPSSTATUS_OB) { 127 if (ups_status_flags & UPSSTATUS_OB) {
118 xasprintf(&ups_status, "%s%s", ups_status, _("On Battery")); 128 xasprintf(&sc_ups_status.output, "%s%s", sc_ups_status.output, _("On Battery"));
119 result = max_state(result, STATE_WARNING); 129 ups_state_result = max_state(ups_state_result, STATE_WARNING);
120 } 130 }
121 if (ups_status_flags & UPSSTATUS_LB) { 131 if (ups_status_flags & UPSSTATUS_LB) {
122 xasprintf(&ups_status, "%s%s", ups_status, _(", Low Battery")); 132 xasprintf(&sc_ups_status.output, "%s%s", sc_ups_status.output, _(", Low Battery"));
123 result = max_state(result, STATE_WARNING); 133 ups_state_result = max_state(ups_state_result, STATE_WARNING);
124 } 134 }
125 if (ups_status_flags & UPSSTATUS_CAL) { 135 if (ups_status_flags & UPSSTATUS_CAL) {
126 xasprintf(&ups_status, "%s%s", ups_status, _(", Calibrating")); 136 xasprintf(&sc_ups_status.output, "%s%s", sc_ups_status.output, _(", Calibrating"));
127 } 137 }
128 if (ups_status_flags & UPSSTATUS_RB) { 138 if (ups_status_flags & UPSSTATUS_RB) {
129 xasprintf(&ups_status, "%s%s", ups_status, _(", Replace Battery")); 139 xasprintf(&sc_ups_status.output, "%s%s", sc_ups_status.output,
130 result = max_state(result, STATE_WARNING); 140 _(", Replace Battery"));
141 ups_state_result = max_state(ups_state_result, STATE_WARNING);
131 } 142 }
132 if (ups_status_flags & UPSSTATUS_BYPASS) { 143 if (ups_status_flags & UPSSTATUS_BYPASS) {
133 xasprintf(&ups_status, "%s%s", ups_status, _(", On Bypass")); 144 xasprintf(&sc_ups_status.output, "%s%s", sc_ups_status.output, _(", On Bypass"));
134 // Bypassing the battery is likely a bad thing 145 // Bypassing the battery is likely a bad thing
135 result = STATE_CRITICAL; 146 ups_state_result = STATE_CRITICAL;
136 } 147 }
137 if (ups_status_flags & UPSSTATUS_OVER) { 148 if (ups_status_flags & UPSSTATUS_OVER) {
138 xasprintf(&ups_status, "%s%s", ups_status, _(", Overload")); 149 xasprintf(&sc_ups_status.output, "%s%s", sc_ups_status.output, _(", Overload"));
139 result = max_state(result, STATE_WARNING); 150 ups_state_result = max_state(ups_state_result, STATE_WARNING);
140 } 151 }
141 if (ups_status_flags & UPSSTATUS_TRIM) { 152 if (ups_status_flags & UPSSTATUS_TRIM) {
142 xasprintf(&ups_status, "%s%s", ups_status, _(", Trimming")); 153 xasprintf(&sc_ups_status.output, "%s%s", sc_ups_status.output, _(", Trimming"));
143 } 154 }
144 if (ups_status_flags & UPSSTATUS_BOOST) { 155 if (ups_status_flags & UPSSTATUS_BOOST) {
145 xasprintf(&ups_status, "%s%s", ups_status, _(", Boosting")); 156 xasprintf(&sc_ups_status.output, "%s%s", sc_ups_status.output, _(", Boosting"));
146 } 157 }
147 if (ups_status_flags & UPSSTATUS_CHRG) { 158 if (ups_status_flags & UPSSTATUS_CHRG) {
148 xasprintf(&ups_status, "%s%s", ups_status, _(", Charging")); 159 xasprintf(&sc_ups_status.output, "%s%s", sc_ups_status.output, _(", Charging"));
149 } 160 }
150 if (ups_status_flags & UPSSTATUS_DISCHRG) { 161 if (ups_status_flags & UPSSTATUS_DISCHRG) {
151 xasprintf(&ups_status, "%s%s", ups_status, _(", Discharging")); 162 xasprintf(&sc_ups_status.output, "%s%s", sc_ups_status.output, _(", Discharging"));
152 result = max_state(result, STATE_WARNING); 163 ups_state_result = max_state(ups_state_result, STATE_WARNING);
153 } 164 }
154 if (ups_status_flags & UPSSTATUS_ALARM) { 165 if (ups_status_flags & UPSSTATUS_ALARM) {
155 xasprintf(&ups_status, "%s%s", ups_status, _(", ALARM")); 166 xasprintf(&sc_ups_status.output, "%s%s", sc_ups_status.output, _(", ALARM"));
156 result = STATE_CRITICAL; 167 ups_state_result = STATE_CRITICAL;
157 } 168 }
158 if (ups_status_flags & UPSSTATUS_UNKNOWN) { 169 if (ups_status_flags & UPSSTATUS_UNKNOWN) {
159 xasprintf(&ups_status, "%s%s", ups_status, _(", Unknown")); 170 xasprintf(&sc_ups_status.output, "%s%s", sc_ups_status.output, _(", Unknown"));
160 } 171 }
161 } 172 }
162 xasprintf(&message, "%sStatus=%s ", message, ups_status); 173 xasprintf(&sc_ups_status.output, "Status: %s", sc_ups_status.output);
174 sc_ups_status = mp_set_subcheck_state(sc_ups_status, ups_state_result);
163 } 175 }
164 176
165 int res; 177 int res;
166 char temp_buffer[MAX_INPUT_BUFFER]; 178 char temp_buffer[MAX_INPUT_BUFFER];
167 char *performance_data = strdup("");
168 /* get the ups utility voltage if possible */ 179 /* get the ups utility voltage if possible */
180 mp_subcheck sc_voltage = mp_subcheck_init();
181 sc_voltage = mp_set_subcheck_default_state(sc_voltage, STATE_OK);
169 res = get_ups_variable("input.voltage", temp_buffer, config); 182 res = get_ups_variable("input.voltage", temp_buffer, config);
170 if (res == NOSUCHVAR) { 183 if (res == NOSUCHVAR) {
171 supported_options &= ~UPS_UTILITY; 184 supported_options &= ~UPS_UTILITY;
172 } else if (res != OK) { 185 } else if (res != OK) {
173 return STATE_CRITICAL; 186 sc_voltage = mp_set_subcheck_state(sc_voltage, STATE_CRITICAL);
187 xasprintf(&sc_voltage.output, "%s", "Failed to detect voltage");
188 mp_add_subcheck_to_check(&overall, sc_voltage);
189 mp_exit(overall);
174 } else { 190 } else {
175 supported_options |= UPS_UTILITY; 191 supported_options |= UPS_UTILITY;
176 192
177 double ups_utility_voltage = 0.0; 193 double ups_utility_voltage = 0.0;
178 ups_utility_voltage = atof(temp_buffer); 194 ups_utility_voltage = atof(temp_buffer);
179 xasprintf(&message, "%sUtility=%3.1fV ", message, ups_utility_voltage); 195 xasprintf(&sc_voltage.output, "Utility: %3.1fV", ups_utility_voltage);
180 196
181 double ups_utility_deviation = 0.0; 197 double ups_utility_deviation = 0.0;
182
183 if (ups_utility_voltage > 120.0) { 198 if (ups_utility_voltage > 120.0) {
184 ups_utility_deviation = 120.0 - ups_utility_voltage; 199 ups_utility_deviation = 120.0 - ups_utility_voltage;
185 } else { 200 } else {
186 ups_utility_deviation = ups_utility_voltage - 120.0; 201 ups_utility_deviation = ups_utility_voltage - 120.0;
187 } 202 }
188 203 mp_perfdata pd_voltage_deviation = perfdata_init();
189 if (config.check_variable == UPS_UTILITY) { 204 pd_voltage_deviation.label = "voltage_deviation";
190 if (config.check_crit && ups_utility_deviation >= config.critical_value) { 205 pd_voltage_deviation.uom = "V";
191 result = STATE_CRITICAL; 206 pd_voltage_deviation.value = mp_create_pd_value(ups_utility_deviation);
192 } else if (config.check_warn && ups_utility_deviation >= config.warning_value) { 207
193 result = max_state(result, STATE_WARNING); 208 pd_voltage_deviation =
194 } 209 mp_pd_set_thresholds(pd_voltage_deviation, config.utility_thresholds);
195 xasprintf(&performance_data, "%s", 210 sc_voltage = mp_set_subcheck_state(sc_voltage, mp_get_pd_status(pd_voltage_deviation));
196 perfdata("voltage", (long)(1000 * ups_utility_voltage), "mV", 211 mp_add_perfdata_to_subcheck(&sc_voltage, pd_voltage_deviation);
197 config.check_warn, (long)(1000 * config.warning_value), 212
198 config.check_crit, (long)(1000 * config.critical_value), true, 0, 213 mp_perfdata pd_voltage = perfdata_init();
199 false, 0)); 214 pd_voltage.label = "voltage";
200 } else { 215 pd_voltage.uom = "V";
201 xasprintf(&performance_data, "%s", 216 pd_voltage.value = mp_create_pd_value(ups_utility_voltage);
202 perfdata("voltage", (long)(1000 * ups_utility_voltage), "mV", false, 0, false, 217 mp_add_perfdata_to_subcheck(&sc_voltage, pd_voltage);
203 0, true, 0, false, 0)); 218
204 } 219 mp_add_subcheck_to_check(&overall, sc_voltage);
205 } 220 }
206 221
207 /* get the ups battery percent if possible */ 222 /* get the ups battery percent if possible */
223 mp_subcheck sc_battery_charge = mp_subcheck_init();
224 sc_battery_charge = mp_set_subcheck_default_state(sc_battery_charge, STATE_OK);
208 res = get_ups_variable("battery.charge", temp_buffer, config); 225 res = get_ups_variable("battery.charge", temp_buffer, config);
209 if (res == NOSUCHVAR) { 226 if (res == NOSUCHVAR) {
210 supported_options &= ~UPS_BATTPCT; 227 supported_options &= ~UPS_BATTPCT;
211 } else if (res != OK) { 228 } else if (res != OK) {
212 return STATE_CRITICAL; 229 sc_battery_charge = mp_set_subcheck_state(sc_battery_charge, STATE_CRITICAL);
230 xasprintf(&sc_battery_charge.output, "%s", "Failed to detect battery charge");
231 mp_add_subcheck_to_check(&overall, sc_battery_charge);
232 mp_exit(overall);
213 } else { 233 } else {
214 supported_options |= UPS_BATTPCT; 234 supported_options |= UPS_BATTPCT;
215 235
216 double ups_battery_percent = 0.0; 236 double ups_battery_percent = atof(temp_buffer);
217 ups_battery_percent = atof(temp_buffer); 237 xasprintf(&sc_battery_charge.output, "Battery charge: %3.1f%%", ups_battery_percent);
218 xasprintf(&message, "%sBatt=%3.1f%% ", message, ups_battery_percent);
219 238
220 if (config.check_variable == UPS_BATTPCT) { 239 mp_perfdata pd_battery_charge = perfdata_init();
221 if (config.check_crit && ups_battery_percent <= config.critical_value) { 240 pd_battery_charge = mp_set_pd_value(pd_battery_charge, ups_battery_percent);
222 result = STATE_CRITICAL; 241 pd_battery_charge.label = "battery";
223 } else if (config.check_warn && ups_battery_percent <= config.warning_value) { 242 pd_battery_charge.uom = "%";
224 result = max_state(result, STATE_WARNING); 243 pd_battery_charge = mp_pd_set_thresholds(pd_battery_charge, config.battery_thresholds);
225 } 244 mp_add_perfdata_to_subcheck(&sc_battery_charge, pd_battery_charge);
226 xasprintf(&performance_data, "%s %s", performance_data, 245
227 perfdata("battery", (long)ups_battery_percent, "%", config.check_warn, 246 sc_battery_charge =
228 (long)(config.warning_value), config.check_crit, 247 mp_set_subcheck_state(sc_battery_charge, mp_get_pd_status(pd_battery_charge));
229 (long)(config.critical_value), true, 0, true, 100)); 248
230 } else { 249 // if (config.check_crit && ups_battery_percent <= config.critical_value) {
231 xasprintf(&performance_data, "%s %s", performance_data, 250 // } else if (config.check_warn && ups_battery_percent <= config.warning_value) {
232 perfdata("battery", (long)ups_battery_percent, "%", false, 0, false, 0, true, 251 mp_add_subcheck_to_check(&overall, sc_battery_charge);
233 0, true, 100));
234 }
235 } 252 }
236 253
237 /* get the ups load percent if possible */ 254 /* get the ups load percent if possible */
238 res = get_ups_variable("ups.load", temp_buffer, config); 255 res = get_ups_variable("ups.load", temp_buffer, config);
256 mp_subcheck sc_load_percent = mp_subcheck_init();
257 mp_set_subcheck_default_state(sc_load_percent, STATE_OK);
239 if (res == NOSUCHVAR) { 258 if (res == NOSUCHVAR) {
240 supported_options &= ~UPS_LOADPCT; 259 supported_options &= ~UPS_LOADPCT;
241 } else if (res != OK) { 260 } else if (res != OK) {
242 return STATE_CRITICAL; 261 sc_load_percent = mp_set_subcheck_state(sc_load_percent, STATE_CRITICAL);
262 xasprintf(&sc_load_percent.output, "%s", "Failed to detect load");
263 mp_add_subcheck_to_check(&overall, sc_load_percent);
264 mp_exit(overall);
243 } else { 265 } else {
244 supported_options |= UPS_LOADPCT; 266 supported_options |= UPS_LOADPCT;
245 267
246 double ups_load_percent = 0.0; 268 double ups_load_percent = atof(temp_buffer);
247 ups_load_percent = atof(temp_buffer); 269 xasprintf(&sc_load_percent.output, "Load :%3.1f%% ", ups_load_percent);
248 xasprintf(&message, "%sLoad=%3.1f%% ", message, ups_load_percent);
249 270
250 if (config.check_variable == UPS_LOADPCT) { 271 mp_perfdata pd_load_percent = perfdata_init();
251 if (config.check_crit && ups_load_percent >= config.critical_value) { 272 pd_load_percent.label = "load";
252 result = STATE_CRITICAL; 273 pd_load_percent.uom = "%";
253 } else if (config.check_warn && ups_load_percent >= config.warning_value) { 274 pd_load_percent.value = mp_create_pd_value(ups_load_percent);
254 result = max_state(result, STATE_WARNING); 275 pd_load_percent = mp_pd_set_thresholds(pd_load_percent, config.load_thresholds);
255 } 276
256 xasprintf(&performance_data, "%s %s", performance_data, 277 sc_load_percent = mp_set_subcheck_state(sc_load_percent, mp_get_pd_status(pd_load_percent));
257 perfdata("load", (long)ups_load_percent, "%", config.check_warn, 278
258 (long)(config.warning_value), config.check_crit, 279 // if (config.check_crit && ups_load_percent >= config.critical_value) {
259 (long)(config.critical_value), true, 0, true, 100)); 280 // } else if (config.check_warn && ups_load_percent >= config.warning_value) {
260 } else {
261 xasprintf(&performance_data, "%s %s", performance_data,
262 perfdata("load", (long)ups_load_percent, "%", false, 0, false, 0, true, 0,
263 true, 100));
264 }
265 } 281 }
266 282
267 /* get the ups temperature if possible */ 283 /* get the ups temperature if possible */
268 res = get_ups_variable("ups.temperature", temp_buffer, config); 284 res = get_ups_variable("ups.temperature", temp_buffer, config);
285 mp_subcheck sc_temperature = mp_subcheck_init();
286 sc_temperature = mp_set_subcheck_default_state(sc_temperature, STATE_OK);
269 if (res == NOSUCHVAR) { 287 if (res == NOSUCHVAR) {
270 supported_options &= ~UPS_TEMP; 288 supported_options &= ~UPS_TEMP;
271 } else if (res != OK) { 289 } else if (res != OK) {
272 return STATE_CRITICAL; 290 sc_temperature = mp_set_subcheck_state(sc_temperature, STATE_CRITICAL);
291 xasprintf(&sc_temperature.output, "%s", "Failed to detect temperature");
292 mp_add_subcheck_to_check(&overall, sc_temperature);
293 mp_exit(overall);
273 } else { 294 } else {
274 supported_options |= UPS_TEMP; 295 supported_options |= UPS_TEMP;
275 296
276 double ups_temperature = 0.0; 297 double ups_temperature = atof(temp_buffer);
277 char *tunits; 298 mp_perfdata pd_temperature = perfdata_init();
299 pd_temperature.label = "temp";
278 300
279 if (config.temp_output_c) { 301 if (config.temp_output_c) {
280 tunits = "degC"; 302 xasprintf(&sc_temperature.output, "Temperature: %3.1fC", ups_temperature);
281 ups_temperature = atof(temp_buffer); 303 pd_temperature.uom = "C";
282 xasprintf(&message, "%sTemp=%3.1fC", message, ups_temperature);
283 } else { 304 } else {
284 tunits = "degF"; 305 ups_temperature = (ups_temperature * 1.8) + 32;
285 ups_temperature = (atof(temp_buffer) * 1.8) + 32; 306 xasprintf(&sc_temperature.output, "Temperature: %3.1fF", ups_temperature);
286 xasprintf(&message, "%sTemp=%3.1fF", message, ups_temperature); 307 pd_temperature.uom = "F";
287 } 308 }
288 309
289 if (config.check_variable == UPS_TEMP) { 310 pd_temperature = mp_set_pd_value(pd_temperature, ups_temperature);
290 if (config.check_crit && ups_temperature >= config.critical_value) { 311 pd_temperature = mp_pd_set_thresholds(pd_temperature, config.temperature_thresholds);
291 result = STATE_CRITICAL; 312
292 } else if (config.check_warn && ups_temperature >= config.warning_value) { 313 sc_temperature = mp_set_subcheck_state(sc_temperature, mp_get_pd_status(pd_temperature));
293 result = max_state(result, STATE_WARNING); 314
294 } 315 // if (config.check_crit && ups_temperature >= config.critical_value) {
295 xasprintf(&performance_data, "%s %s", performance_data, 316 // } else if (config.check_warn && ups_temperature >= config.warning_value) {
296 perfdata("temp", (long)ups_temperature, tunits, config.check_warn,
297 (long)(config.warning_value), config.check_crit,
298 (long)(config.critical_value), true, 0, false, 0));
299 } else {
300 xasprintf(&performance_data, "%s %s", performance_data,
301 perfdata("temp", (long)ups_temperature, tunits, false, 0, false, 0, true, 0,
302 false, 0));
303 }
304 } 317 }
305 318
306 /* get the ups real power if possible */ 319 /* get the ups real power if possible */
307 res = get_ups_variable("ups.realpower", temp_buffer, config); 320 res = get_ups_variable("ups.realpower", temp_buffer, config);
321 mp_subcheck sc_real_power = mp_subcheck_init();
322 sc_real_power = mp_set_subcheck_default_state(sc_real_power, STATE_OK);
308 if (res == NOSUCHVAR) { 323 if (res == NOSUCHVAR) {
309 supported_options &= ~UPS_REALPOWER; 324 supported_options &= ~UPS_REALPOWER;
310 } else if (res != OK) { 325 } else if (res != OK) {
311 return STATE_CRITICAL; 326 sc_real_power = mp_set_subcheck_state(sc_real_power, STATE_CRITICAL);
327 xasprintf(&sc_real_power.output, "%s", "Failed to detect real power");
328 mp_add_subcheck_to_check(&overall, sc_real_power);
329 mp_exit(overall);
312 } else { 330 } else {
313 supported_options |= UPS_REALPOWER; 331 supported_options |= UPS_REALPOWER;
314 double ups_realpower = 0.0; 332
315 ups_realpower = atof(temp_buffer); 333 double ups_realpower = atof(temp_buffer);
316 xasprintf(&message, "%sReal power=%3.1fW ", message, ups_realpower); 334 xasprintf(&sc_temperature.output, "Real power: %3.1fW ", ups_realpower);
317 335
318 if (config.check_variable == UPS_REALPOWER) { 336 mp_perfdata pd_real_power = perfdata_init();
319 if (config.check_crit && ups_realpower >= config.critical_value) { 337 pd_real_power.label = "realpower";
320 result = STATE_CRITICAL; 338 pd_real_power = mp_set_pd_value(pd_real_power, ups_realpower);
321 } else if (config.check_warn && ups_realpower >= config.warning_value) { 339 pd_real_power.uom = "W";
322 result = max_state(result, STATE_WARNING); 340 pd_real_power = mp_pd_set_thresholds(pd_real_power, config.real_power_thresholds);
323 } 341
324 xasprintf(&performance_data, "%s %s", performance_data, 342 // if (config.check_crit && ups_realpower >= config.critical_value) {
325 perfdata("realpower", (long)ups_realpower, "W", config.check_warn, 343 // } else if (config.check_warn && ups_realpower >= config.warning_value) {
326 (long)(config.warning_value), config.check_crit,
327 (long)(config.critical_value), true, 0, false, 0));
328 } else {
329 xasprintf(&performance_data, "%s %s", performance_data,
330 perfdata("realpower", (long)ups_realpower, "W", false, 0, false, 0, true, 0,
331 false, 0));
332 }
333 } 344 }
334 345
335 /* if the UPS does not support any options we are looking for, report an 346 /* if the UPS does not support any options we are looking for, report an
336 * error */ 347 * error */
337 if (supported_options == UPS_NONE) { 348 if (supported_options == UPS_NONE) {
338 result = STATE_CRITICAL; 349 mp_subcheck sc_any_option = mp_subcheck_init();
339 xasprintf(&message, _("UPS does not support any available options\n")); 350 sc_any_option = mp_set_subcheck_state(sc_any_option, STATE_CRITICAL);
351 xasprintf(&sc_any_option.output, _("UPS does not support any available options\n"));
352 mp_add_subcheck_to_check(&overall, sc_any_option);
340 } 353 }
341 354
342 /* reset timeout */ 355 /* reset timeout */
343 alarm(0); 356 alarm(0);
344 357
345 printf("UPS %s - %s|%s\n", state_text(result), message, performance_data); 358 mp_exit(overall);
346 exit(result);
347} 359}
348 360
349/* determines what options are supported by the UPS */ 361/* determines what options are supported by the UPS */
@@ -502,26 +514,27 @@ check_ups_config_wrapper process_arguments(int argc, char **argv) {
502 return result; 514 return result;
503 } 515 }
504 516
505 int c; 517 for (int i = 1; i < argc; i++) {
506 for (c = 1; c < argc; c++) { 518 if (strcmp("-to", argv[i]) == 0) {
507 if (strcmp("-to", argv[c]) == 0) { 519 strcpy(argv[i], "-t");
508 strcpy(argv[c], "-t"); 520 } else if (strcmp("-wt", argv[i]) == 0) {
509 } else if (strcmp("-wt", argv[c]) == 0) { 521 strcpy(argv[i], "-w");
510 strcpy(argv[c], "-w"); 522 } else if (strcmp("-ct", argv[i]) == 0) {
511 } else if (strcmp("-ct", argv[c]) == 0) { 523 strcpy(argv[i], "-c");
512 strcpy(argv[c], "-c");
513 } 524 }
514 } 525 }
515 526
516 int option = 0; 527 int option = 0;
517 while (1) { 528 ups_test_type test_selection = UPS_NONE;
518 c = getopt_long(argc, argv, "hVTH:u:p:v:c:w:t:", longopts, &option); 529 mp_thresholds tmp_thr = mp_thresholds_init();
530 while (true) {
531 int counter = getopt_long(argc, argv, "hVTH:u:p:v:c:w:t:", longopts, &option);
519 532
520 if (c == -1 || c == EOF) { 533 if (counter == -1 || counter == EOF) {
521 break; 534 break;
522 } 535 }
523 536
524 switch (c) { 537 switch (counter) {
525 case '?': /* help */ 538 case '?': /* help */
526 usage5(); 539 usage5();
527 case 'H': /* hostname */ 540 case 'H': /* hostname */
@@ -545,33 +558,41 @@ check_ups_config_wrapper process_arguments(int argc, char **argv) {
545 usage2(_("Port must be a positive integer"), optarg); 558 usage2(_("Port must be a positive integer"), optarg);
546 } 559 }
547 break; 560 break;
548 case 'c': /* critical time threshold */ 561 case 'c': /* critical voltage threshold */
549 if (is_intnonneg(optarg)) { 562 if (is_intnonneg(optarg)) {
550 result.config.critical_value = atoi(optarg); 563 mp_range_parsed tmp = mp_parse_range_string(optarg);
551 result.config.check_crit = true; 564 if (tmp.error != MP_PARSING_SUCCESS) {
565 usage2(_("Critical voltage must be a valid range expression"), optarg);
566 } else {
567 tmp_thr = mp_thresholds_set_crit(tmp_thr, tmp.range);
568 }
552 } else { 569 } else {
553 usage2(_("Critical time must be a positive integer"), optarg); 570 usage2(_("Critical voltage must be a positive integer"), optarg);
554 } 571 }
555 break; 572 break;
556 case 'w': /* warning time threshold */ 573 case 'w': /* warning voltage threshold */
557 if (is_intnonneg(optarg)) { 574 if (is_intnonneg(optarg)) {
558 result.config.warning_value = atoi(optarg); 575 mp_range_parsed tmp = mp_parse_range_string(optarg);
559 result.config.check_warn = true; 576 if (tmp.error != MP_PARSING_SUCCESS) {
577 usage2(_("Warning voltage must be a valid range expression"), optarg);
578 } else {
579 tmp_thr = mp_thresholds_set_warn(tmp_thr, tmp.range);
580 }
560 } else { 581 } else {
561 usage2(_("Warning time must be a positive integer"), optarg); 582 usage2(_("Warning voltage must be a positive integer"), optarg);
562 } 583 }
563 break; 584 break;
564 case 'v': /* variable */ 585 case 'v': /* variable */
565 if (!strcmp(optarg, "LINE")) { 586 if (!strcmp(optarg, "LINE")) {
566 result.config.check_variable = UPS_UTILITY; 587 test_selection = UPS_UTILITY;
567 } else if (!strcmp(optarg, "TEMP")) { 588 } else if (!strcmp(optarg, "TEMP")) {
568 result.config.check_variable = UPS_TEMP; 589 test_selection = UPS_TEMP;
569 } else if (!strcmp(optarg, "BATTPCT")) { 590 } else if (!strcmp(optarg, "BATTPCT")) {
570 result.config.check_variable = UPS_BATTPCT; 591 test_selection = UPS_BATTPCT;
571 } else if (!strcmp(optarg, "LOADPCT")) { 592 } else if (!strcmp(optarg, "LOADPCT")) {
572 result.config.check_variable = UPS_LOADPCT; 593 test_selection = UPS_LOADPCT;
573 } else if (!strcmp(optarg, "REALPOWER")) { 594 } else if (!strcmp(optarg, "REALPOWER")) {
574 result.config.check_variable = UPS_REALPOWER; 595 test_selection = UPS_REALPOWER;
575 } else { 596 } else {
576 usage2(_("Unrecognized UPS variable"), optarg); 597 usage2(_("Unrecognized UPS variable"), optarg);
577 } 598 }
@@ -604,6 +625,23 @@ check_ups_config_wrapper process_arguments(int argc, char **argv) {
604 result.config.server_address = strdup("127.0.0.1"); 625 result.config.server_address = strdup("127.0.0.1");
605 } 626 }
606 627
628 switch (test_selection) {
629 case UPS_UTILITY:
630 result.config.utility_thresholds = tmp_thr;
631 case UPS_BATTPCT:
632 result.config.battery_thresholds = tmp_thr;
633 case UPS_LOADPCT:
634 result.config.load_thresholds = tmp_thr;
635 case UPS_REALPOWER:
636 result.config.real_power_thresholds = tmp_thr;
637 case UPS_TEMP:
638 result.config.temperature_thresholds = tmp_thr;
639 case UPS_NONE:
640 case UPS_STATUS:
641 default: {
642 }
643 }
644
607 return validate_arguments(result); 645 return validate_arguments(result);
608} 646}
609 647
@@ -647,7 +685,10 @@ void print_help(void) {
647 printf(" %s %s\n", _("Valid values for STRING are"), 685 printf(" %s %s\n", _("Valid values for STRING are"),
648 "LINE, TEMP, BATTPCT, LOADPCT or REALPOWER"); 686 "LINE, TEMP, BATTPCT, LOADPCT or REALPOWER");
649 687
650 printf(UT_WARN_CRIT); 688 printf(" %s\n", "-w, --warning");
689 printf(" %s\n", _("Set warning threshold on metric selected via --variable"));
690 printf(" %s\n", "-c, --critical");
691 printf(" %s\n", _("Set critical threshold on metric selected via --variable"));
651 692
652 printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); 693 printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
653 694
diff --git a/plugins/check_ups.d/config.h b/plugins/check_ups.d/config.h
index e05edceb..900363fd 100644
--- a/plugins/check_ups.d/config.h
+++ b/plugins/check_ups.d/config.h
@@ -1,31 +1,36 @@
1#pragma once 1#pragma once
2 2
3#include "../../config.h" 3#include "../../config.h"
4#include "thresholds.h"
4#include <stddef.h> 5#include <stddef.h>
5 6
6#define UPS_NONE 0 /* no supported options */ 7typedef enum {
7#define UPS_UTILITY 1 /* supports utility line */ 8 UPS_NONE = 0, /* no supported options */
8#define UPS_BATTPCT 2 /* supports percent battery remaining */ 9 UPS_UTILITY = 1, /* supports utility line */
9#define UPS_STATUS 4 /* supports UPS status */ 10 UPS_BATTPCT = 2, /* supports percent battery remaining */
10#define UPS_TEMP 8 /* supports UPS temperature */ 11 UPS_STATUS = 4, /* supports UPS status */
11#define UPS_LOADPCT 16 /* supports load percent */ 12 UPS_TEMP = 8, /* supports UPS temperature */
12#define UPS_REALPOWER 32 /* supports real power */ 13 UPS_LOADPCT = 16, /* supports load percent */
13 14 UPS_REALPOWER = 32, /* supports real power */
14#define UPSSTATUS_NONE 0 15} ups_test_type;
15#define UPSSTATUS_OFF 1 16
16#define UPSSTATUS_OL 2 17typedef enum {
17#define UPSSTATUS_OB 4 18 UPSSTATUS_NONE = 0,
18#define UPSSTATUS_LB 8 19 UPSSTATUS_OFF = 1,
19#define UPSSTATUS_CAL 16 20 UPSSTATUS_OL = 2,
20#define UPSSTATUS_RB 32 /*Replace Battery */ 21 UPSSTATUS_OB = 4,
21#define UPSSTATUS_BYPASS 64 22 UPSSTATUS_LB = 8,
22#define UPSSTATUS_OVER 128 23 UPSSTATUS_CAL = 16,
23#define UPSSTATUS_TRIM 256 24 UPSSTATUS_RB = 32, /*Replace Battery */
24#define UPSSTATUS_BOOST 512 25 UPSSTATUS_BYPASS = 64,
25#define UPSSTATUS_CHRG 1024 26 UPSSTATUS_OVER = 128,
26#define UPSSTATUS_DISCHRG 2048 27 UPSSTATUS_TRIM = 256,
27#define UPSSTATUS_UNKNOWN 4096 28 UPSSTATUS_BOOST = 512,
28#define UPSSTATUS_ALARM 8192 29 UPSSTATUS_CHRG = 1024,
30 UPSSTATUS_DISCHRG = 2048,
31 UPSSTATUS_UNKNOWN = 4096,
32 UPSSTATUS_ALARM = 8192,
33} ups_status_type;
29 34
30enum { 35enum {
31 PORT = 3493 36 PORT = 3493
@@ -35,20 +40,28 @@ typedef struct ups_config {
35 unsigned int server_port; 40 unsigned int server_port;
36 char *server_address; 41 char *server_address;
37 char *ups_name; 42 char *ups_name;
38 double warning_value; 43
39 double critical_value; 44 mp_thresholds utility_thresholds;
40 bool check_warn; 45 mp_thresholds battery_thresholds;
41 bool check_crit; 46 mp_thresholds load_thresholds;
42 int check_variable; 47 mp_thresholds real_power_thresholds;
48 mp_thresholds temperature_thresholds;
49
43 bool temp_output_c; 50 bool temp_output_c;
44} check_ups_config; 51} check_ups_config;
45 52
46check_ups_config check_ups_config_init(void) { 53check_ups_config check_ups_config_init(void) {
47 check_ups_config tmp = {0}; 54 check_ups_config tmp = {
48 tmp.server_port = PORT; 55 .server_port = PORT,
49 tmp.server_address = NULL; 56 .server_address = NULL,
50 tmp.ups_name = NULL; 57 .ups_name = NULL,
51 tmp.check_variable = UPS_NONE; 58
59 .utility_thresholds = mp_thresholds_init(),
60 .battery_thresholds = mp_thresholds_init(),
61 .load_thresholds = mp_thresholds_init(),
62 .real_power_thresholds = mp_thresholds_init(),
63 .temperature_thresholds = mp_thresholds_init(),
64 };
52 65
53 return tmp; 66 return tmp;
54} 67}