]> granicus.if.org Git - icinga2/blob - plugins/check_uptime.cpp
Remove http_vhosts config from Windows
[icinga2] / plugins / check_uptime.cpp
1 /******************************************************************************
2  * Icinga 2                                                                   *
3  * Copyright (C) 2012-2015 Icinga Development Team (http://www.icinga.org)    *
4  *                                                                            *
5  * This program is free software; you can redistribute it and/or              *
6  * modify it under the terms of the GNU General Public License                *
7  * as published by the Free Software Foundation; either version 2             *
8  * of the License, or (at your option) any later version.                     *
9  *                                                                            *
10  * This program is distributed in the hope that it will be useful,            *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
13  * GNU General Public License for more details.                               *
14  *                                                                            *
15  * You should have received a copy of the GNU General Public License          *
16  * along with this program; if not, write to the Free Software Foundation     *
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.             *
18  ******************************************************************************/
19 #include <Windows.h>
20 #include <Shlwapi.h>
21 #include <iostream>
22
23 #include "thresholds.h"
24
25 #include "boost/chrono.hpp"
26 #include "boost/program_options.hpp"
27
28 #define VERSION 1.0
29
30 namespace po = boost::program_options;
31
32 using std::cout; using std::endl;
33 using std::wcout; using std::wstring;
34
35 static BOOL debug;
36
37 struct printInfoStruct 
38 {
39         threshold warn, crit;
40         long long time;
41         Tunit unit;
42 };
43
44
45 static int parseArguments(int, wchar_t **, po::variables_map&, printInfoStruct&);
46 static int printOutput(printInfoStruct&);
47 static void getUptime(printInfoStruct&);
48
49 int wmain(int argc, wchar_t **argv)
50 {
51         po::variables_map vm;
52         printInfoStruct printInfo = { };
53         int ret = parseArguments(argc, argv, vm, printInfo);
54         
55         if (ret != -1)
56                 return ret;
57
58         getUptime(printInfo);
59
60         return printOutput(printInfo);
61 }
62
63 int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct& printInfo) 
64 {
65         wchar_t namePath[MAX_PATH];
66         GetModuleFileName(NULL, namePath, MAX_PATH);
67         wchar_t *progName = PathFindFileName(namePath);
68
69         po::options_description desc;
70         
71         desc.add_options()
72                 ("help,h", "print help message and exit")
73                 ("version,V", "print version and exit")
74                 ("warning,w", po::wvalue<wstring>(), "warning threshold (Uses -unit)")
75                 ("debug,d", "Verbose/Debug output")
76                 ("critical,c", po::wvalue<wstring>(), "critical threshold (Uses -unit)")
77                 ("unit,u", po::wvalue<wstring>(), "desired unit of output\nh\t- hours\nm\t- minutes\ns\t- seconds (default)\nms\t- milliseconds")
78                 ;
79
80         po::basic_command_line_parser<wchar_t> parser(ac, av);
81
82         try {
83                 po::store(
84                         parser
85                         .options(desc)
86                         .style(
87                         po::command_line_style::unix_style |
88                         po::command_line_style::allow_long_disguise)
89                         .run(),
90                         vm);
91                 vm.notify();
92         } catch (std::exception& e) {
93                 cout << e.what() << endl << desc << endl;
94                 return 3;
95         }
96
97         if (vm.count("help")) {
98                 wcout << progName << " Help\n\tVersion: " << VERSION << endl;
99                 wprintf(
100                         L"%s is a simple program to check a machines uptime.\n"
101                         L"You can use the following options to define its behaviour:\n\n", progName);
102                 cout << desc;
103                 wprintf(
104                         L"\nIt will then output a string looking something like this:\n\n"
105                         L"\tUPTIME WARNING 712h | uptime=712h;700;1800;0\n\n"
106                         L"\"UPTIME\" being the type of the check, \"WARNING\" the returned status\n"
107                         L"and \"712h\" is the returned value.\n"
108                         L"The performance data is found behind the \"|\", in order:\n"
109                         L"returned value, warning threshold, critical threshold, minimal value and,\n"
110                         L"if applicable, the maximal value. Performance data will only be displayed when\n"
111                         L"you set at least one threshold\n\n"
112                         L"Note that the returned time ins always rounded down,\n"
113                         L"4 hours and 44 minutes will show as 4h.\n\n"
114                         L"%s' exit codes denote the following:\n"
115                         L" 0\tOK,\n\tNo Thresholds were broken or the programs check part was not executed\n"
116                         L" 1\tWARNING,\n\tThe warning, but not the critical threshold was broken\n"
117                         L" 2\tCRITICAL,\n\tThe critical threshold was broken\n"
118                         L" 3\tUNKNOWN, \n\tThe program experienced an internal or input error\n\n"
119                         L"Threshold syntax:\n\n"
120                         L"-w THRESHOLD\n"
121                         L"warn if threshold is broken, which means VALUE > THRESHOLD\n"
122                         L"(unless stated differently)\n\n"
123                         L"-w !THRESHOLD\n"
124                         L"inverts threshold check, VALUE < THRESHOLD (analogous to above)\n\n"
125                         L"-w [THR1-THR2]\n"
126                         L"warn is VALUE is inside the range spanned by THR1 and THR2\n\n"
127                         L"-w ![THR1-THR2]\n"
128                         L"warn if VALUE is outside the range spanned by THR1 and THR2\n\n"
129                         L"-w THRESHOLD%%\n"
130                         L"if the plugin accepts percentage based thresholds those will be used.\n"
131                         L"Does nothing if the plugin does not accept percentages, or only uses\n"
132                         L"percentage thresholds. Ranges can be used with \"%%\", but both range values need\n"
133                         L"to end with a percentage sign.\n\n"
134                         L"All of these options work with the critical threshold \"-c\" too.\n"
135                         , progName);
136                         cout << endl;
137                 return 0;
138         }
139
140         if (vm.count("version")) {
141                 cout << VERSION << endl;
142                 return 0;
143         }
144
145         if (vm.count("warning")) {
146                 try {
147                         printInfo.warn = threshold(vm["warning"].as<wstring>());
148                 } catch (std::invalid_argument& e) {
149                         cout << e.what() << endl;
150                         return 3;
151                 }
152         }
153         if (vm.count("critical")) {
154                 try {
155                         printInfo.crit = threshold(vm["critical"].as<wstring>());
156                 } catch (std::invalid_argument& e) {
157                         cout << e.what() << endl;
158                         return 3;
159                 }
160         }
161
162         if (vm.count("unit")) {
163                 try{
164                         printInfo.unit = parseTUnit(vm["unit"].as<wstring>());
165                 } catch (std::invalid_argument) {
166                         wcout << L"Unknown unit type " << vm["unit"].as<wstring>() << endl;
167                         return 3;
168                 } 
169         } else
170                 printInfo.unit = TunitS;
171
172         if (vm.count("debug"))
173                 debug = TRUE;
174
175         return -1;
176 }
177
178 static int printOutput(printInfoStruct& printInfo) 
179 {
180         if (debug)
181                 wcout << L"Constructing output string" << endl;
182
183         state state = OK;
184
185         if (printInfo.warn.rend(printInfo.time))
186                 state = WARNING;
187         if (printInfo.crit.rend(printInfo.time))
188                 state = CRITICAL;
189
190         switch (state) {
191         case OK:
192                 wcout << L"UPTIME OK " << printInfo.time << TunitStr(printInfo.unit) << L" | uptime=" << printInfo.time
193                         << TunitStr(printInfo.unit) << L";" << printInfo.warn.pString() << L";"
194                         << printInfo.crit.pString() << L";0;" << endl;
195                 break;
196         case WARNING:
197                 wcout << L"UPTIME WARNING " << printInfo.time << TunitStr(printInfo.unit) << L" | uptime=" << printInfo.time
198                         << TunitStr(printInfo.unit) << L";" << printInfo.warn.pString() << L";"
199                         << printInfo.crit.pString() << L";0;" << endl;
200                 break;
201         case CRITICAL:
202                 wcout << L"UPTIME CRITICAL " << printInfo.time << TunitStr(printInfo.unit) << L" | uptime=" << printInfo.time
203                         << TunitStr(printInfo.unit) << L";" << printInfo.warn.pString() << L";"
204                         << printInfo.crit.pString() << L";0;" << endl;
205                 break;
206         }
207
208         return state;
209 }
210
211 void getUptime(printInfoStruct& printInfo) 
212 {
213         if (debug)
214                 wcout << L"Getting uptime in milliseconds" << endl;
215
216         boost::chrono::milliseconds uptime = boost::chrono::milliseconds(GetTickCount64());
217         
218         if (debug)
219                 wcout << L"Converting requested unit (default: seconds)" << endl;
220
221         switch (printInfo.unit) {
222         case TunitH: 
223                 printInfo.time = boost::chrono::duration_cast<boost::chrono::hours>(uptime).count();
224                 break;
225         case TunitM:
226                 printInfo.time = boost::chrono::duration_cast<boost::chrono::minutes>(uptime).count();
227                 break;
228         case TunitS:
229                 printInfo.time = boost::chrono::duration_cast<boost::chrono::seconds>(uptime).count();
230                 break;
231         case TunitMS:
232                 printInfo.time = uptime.count();
233                 break;
234         }
235 }