source: nscp/modules/CheckSystem/CheckSystem.cpp @ 0687108

0.4.00.4.10.4.2stable
Last change on this file since 0687108 was 0687108, checked in by Michael Medin <michael@…>, 7 years ago

+ Added support for empty NRPE checking (i.e.. chec_nrpe without a -c argument)

  • Added error message when detected language is missing from counters.defs + Added Swedish locale to counters.defs (yes, I switched to Swedish XP on my computer :)
  • Fixed : (and possibly other problems) in counters when checking from check_nt (via NSCLient protocol) + Added CheckAllExcept? to CheckDrive? to check all except the specified drives.
  • Property mode set to 100644
File size: 29.5 KB
Line 
1// NSClientCompat.cpp : Defines the entry point for the DLL application.
2//
3
4#include "stdafx.h"
5#include "CheckSystem.h"
6#include <utils.h>
7#include <tlhelp32.h>
8#include <EnumNtSrv.h>
9#include <EnumProcess.h>
10#include <sysinfo.h>
11#include <checkHelpers.hpp>
12#include <map>
13
14CheckSystem gCheckSystem;
15
16/**
17 * DLL Entry point
18 * @param hModule
19 * @param ul_reason_for_call
20 * @param lpReserved
21 * @return
22 */
23BOOL APIENTRY DllMain( HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
24{
25        NSCModuleWrapper::wrapDllMain(hModule, ul_reason_for_call);
26        return TRUE;
27}
28
29/**
30 * Default c-tor
31 * @return
32 */
33CheckSystem::CheckSystem() : processMethod_(0), pdhThread("pdhThread") {}
34/**
35 * Default d-tor
36 * @return
37 */
38CheckSystem::~CheckSystem() {}
39/**
40 * Load (initiate) module.
41 * Start the background collector thread and let it run until unloadModule() is called.
42 * @return true
43 */
44bool CheckSystem::loadModule() {
45        pdhThread.createThread();
46
47        std::string wantedMethod = NSCModuleHelper::getSettingsString(C_SYSTEM_SECTION_TITLE, C_SYSTEM_ENUMPROC_METHOD, C_SYSTEM_ENUMPROC_METHOD_DEFAULT);
48
49        CEnumProcess tmp;
50        int method = tmp.GetAvailableMethods();
51
52
53
54        if (wantedMethod == C_SYSTEM_ENUMPROC_METHOD_AUTO) {
55                OSVERSIONINFO osVer = systemInfo::getOSVersion();
56                if (systemInfo::isBelowNT4(osVer)) {
57                        NSC_DEBUG_MSG_STD("Autodetected NT4<, using PSAPI process enumeration.");
58                        processMethod_ = ENUM_METHOD::PSAPI;
59                } else if (systemInfo::isAboveW2K(osVer)) {
60                        NSC_DEBUG_MSG_STD("Autodetected W2K>, using TOOLHELP process enumeration.");
61                        processMethod_ = ENUM_METHOD::TOOLHELP;
62                } else {
63                        NSC_DEBUG_MSG_STD("Autodetected failed, using PSAPI process enumeration.");
64                        processMethod_ = ENUM_METHOD::PSAPI;
65                }
66        } else if (wantedMethod == C_SYSTEM_ENUMPROC_METHOD_PSAPI) {
67                NSC_DEBUG_MSG_STD("Using PSAPI method.");
68                if (method == (method|ENUM_METHOD::PSAPI)) {
69                        processMethod_ = ENUM_METHOD::PSAPI;
70                } else {
71                        NSC_LOG_ERROR_STD("PSAPI method not available, check " C_SYSTEM_ENUMPROC_METHOD " option.");
72                }
73        } else {
74                NSC_DEBUG_MSG_STD("Using TOOLHELP method.");
75                if (method == (method|ENUM_METHOD::TOOLHELP)) {
76                        processMethod_ = ENUM_METHOD::TOOLHELP;
77                } else {
78                        NSC_LOG_ERROR_STD("TOOLHELP method not avalible, check " C_SYSTEM_ENUMPROC_METHOD " option.");
79                }
80        }
81        return true;
82}
83/**
84 * Unload (terminate) module.
85 * Attempt to stop the background processing thread.
86 * @return true if successfully, false if not (if not things might be bad)
87 */
88bool CheckSystem::unloadModule() {
89        if (!pdhThread.exitThread(20000)) {
90                std::cout << "MAJOR ERROR: Could not unload thread..." << std::endl;
91                NSC_LOG_ERROR("Could not exit the thread, memory leak and potential corruption may be the result...");
92        }
93        return true;
94}
95/**
96 * Check if we have a command handler.
97 * @return true (as we have a command handler)
98 */
99bool CheckSystem::hasCommandHandler() {
100        return true;
101}
102/**
103 * Check if we have a message handler.
104 * @return false as we have no message handler
105 */
106bool CheckSystem::hasMessageHandler() {
107        return false;
108}
109
110int CheckSystem::commandLineExec(const char* command,const unsigned int argLen,char** args) {
111        if (stricmp(command, "debugpdh") == 0) {
112                PDH::Enumerations::Objects lst = PDH::Enumerations::EnumObjects();
113                for (PDH::Enumerations::Objects::iterator it = lst.begin();it!=lst.end();++it) {
114                        if ((*it).instances.size() > 0) {
115                                for (PDH::Enumerations::Instances::const_iterator it2 = (*it).instances.begin();it2!=(*it).instances.end();++it2) {
116                                        for (PDH::Enumerations::Counters::const_iterator it3 = (*it).counters.begin();it3!=(*it).counters.end();++it3) {
117                                                std::string counter = "\\" + (*it).name + "(" + (*it2).name + ")\\" + (*it3).name;
118                                                std::cout << "testing: " << counter << ": ";
119                                                std::list<std::string> errors;
120                                                std::list<std::string> status;
121                                                std::string error;
122                                                bool bStatus = true;
123                                                if (PDH::Enumerations::validate(counter, error)) {
124                                                        status.push_back("open");
125                                                } else {
126                                                        errors.push_back("NOT found: " + error);
127                                                        bStatus = false;
128                                                }
129                                                if (bStatus) {
130                                                        PDH::PDHCounter *pCounter = NULL;
131                                                        PDH::PDHQuery pdh;
132                                                        try {
133                                                                PDHCollectors::StaticPDHCounterListener<double, PDH_FMT_DOUBLE> cDouble;
134                                                                pCounter = pdh.addCounter(counter, &cDouble);
135                                                                pdh.open();
136
137                                                                if (pCounter != NULL) {
138                                                                        try {
139                                                                                PDH::PDHCounterInfo info = pCounter->getCounterInfo();
140                                                                                errors.push_back("CounterName: " + info.szCounterName);
141                                                                                errors.push_back("ExplainText: " + info.szExplainText);
142                                                                                errors.push_back("FullPath: " + info.szFullPath);
143                                                                                errors.push_back("InstanceName: " + info.szInstanceName);
144                                                                                errors.push_back("MachineName: " + info.szMachineName);
145                                                                                errors.push_back("ObjectName: " + info.szObjectName);
146                                                                                errors.push_back("ParentInstance: " + info.szParentInstance);
147                                                                                errors.push_back("Type: " + strEx::itos(info.dwType));
148                                                                                errors.push_back("Scale: " + strEx::itos(info.lScale));
149                                                                                errors.push_back("Default Scale: " + strEx::itos(info.lDefaultScale));
150                                                                                errors.push_back("Status: " + strEx::itos(info.CStatus));
151                                                                                status.push_back("described");
152                                                                        } catch (const PDH::PDHException e) {
153                                                                                errors.push_back("Describe failed: " + e.getError());
154                                                                                bStatus = false;
155                                                                        }
156                                                                }
157
158                                                                pdh.gatherData();
159                                                                pdh.close();
160                                                                status.push_back("queried");
161                                                        } catch (const PDH::PDHException e) {
162                                                                errors.push_back("Query failed: " + e.getError());
163                                                                bStatus = false;
164                                                                try {
165                                                                        pdh.gatherData();
166                                                                        pdh.close();
167                                                                        bStatus = true;
168                                                                } catch (const PDH::PDHException e) {
169                                                                        errors.push_back("Query failed (again!): " + e.getError());
170                                                                }
171                                                        }
172
173                                                }
174                                                if (!bStatus) {
175                                                        std::list<std::string>::const_iterator cit = status.begin();
176                                                        for (;cit != status.end(); ++cit) {
177                                                                std::cout << *cit << ", ";
178                                                        }
179                                                        std::cout << std::endl;
180                                                        std::cout << "  | Log" << std::endl;
181                                                        std::cout << "--+------  --    -" << std::endl;
182                                                        cit = errors.begin();
183                                                        for (;cit != errors.end(); ++cit) {
184                                                                std::cout << "  | " << *cit << std::endl;
185                                                        }
186                                                } else {
187                                                        std::list<std::string>::const_iterator cit = status.begin();
188                                                        for (;cit != status.end(); ++cit) {
189                                                                std::cout << *cit << ", ";;
190                                                        }
191                                                        std::cout << std::endl;
192                                                }
193                                        }
194                                }
195                        } else {
196                                for (PDH::Enumerations::Counters::const_iterator it2 = (*it).counters.begin();it2!=(*it).counters.end();++it2) {
197                                        std::string counter = "\\" + (*it).name + "\\" + (*it2).name;
198                                        std::cout << "testing: " << counter << ": ";
199                                        std::string error;
200                                        if (PDH::Enumerations::validate(counter, error)) {
201                                                std::cout << " found ";
202                                        } else {
203                                                std::cout << " *NOT* found (" << error << ") " << std::endl;
204                                                break;
205                                        }
206                                        bool bOpend = false;
207                                        try {
208                                                PDH::PDHQuery pdh;
209                                                PDHCollectors::StaticPDHCounterListener<double, PDH_FMT_DOUBLE> cDouble;
210                                                pdh.addCounter(counter, &cDouble);
211                                                pdh.open();
212                                                pdh.gatherData();
213                                                pdh.close();
214                                                bOpend = true;
215                                        } catch (const PDH::PDHException e) {
216                                                std::cout << " could *not* be open (" << e.getError() << ") " << std::endl;
217                                                break;
218                                        }
219                                        std::cout << " open ";
220                                        std::cout << std::endl;;
221                                }
222                        }
223                }
224        } else if (stricmp(command, "listpdh") == 0) {
225                PDH::Enumerations::Objects lst = PDH::Enumerations::EnumObjects();
226                for (PDH::Enumerations::Objects::iterator it = lst.begin();it!=lst.end();++it) {
227                        if ((*it).instances.size() > 0) {
228                                for (PDH::Enumerations::Instances::const_iterator it2 = (*it).instances.begin();it2!=(*it).instances.end();++it2) {
229                                        for (PDH::Enumerations::Counters::const_iterator it3 = (*it).counters.begin();it3!=(*it).counters.end();++it3) {
230                                                std::cout << "\\" << (*it).name << "(" << (*it2).name << ")\\" << (*it3).name << std::endl;;
231                                        }
232                                }
233                        } else {
234                                for (PDH::Enumerations::Counters::const_iterator it2 = (*it).counters.begin();it2!=(*it).counters.end();++it2) {
235                                        std::cout << "\\" << (*it).name << "\\" << (*it2).name << std::endl;;
236                                }
237                        }
238                }
239        }
240        return 0;
241}
242
243
244/**
245 * Main command parser and delegator.
246 * This also handles a lot of the simpler responses (though some are deferred to other helper functions)
247 *
248 *
249 * @param command
250 * @param argLen
251 * @param **args
252 * @return
253 */
254NSCAPI::nagiosReturn CheckSystem::handleCommand(const strEx::blindstr command, const unsigned int argLen, char **char_args, std::string &msg, std::string &perf) {
255        std::list<std::string> stl_args;
256        CheckSystem::returnBundle rb;
257        if (command == "checkCPU") {
258                return checkCPU(argLen, char_args, msg, perf);
259        } else if (command == "checkUpTime") {
260                return checkUpTime(argLen, char_args, msg, perf);
261        } else if (command == "checkServiceState") {
262                return checkServiceState(argLen, char_args, msg, perf);
263        } else if (command == "checkProcState") {
264                return checkProcState(argLen, char_args, msg, perf);
265        } else if (command == "checkMem") {
266                return checkMem(argLen, char_args, msg, perf);
267        } else if (command == "checkCounter") {
268                return checkCounter(argLen, char_args, msg, perf);
269        }
270        return NSCAPI::returnIgnored;
271}
272
273
274class cpuload_handler {
275public:
276        static int parse(std::string s) {
277                return strEx::stoi(s);
278        }
279        static int parse_percent(std::string s) {
280                return strEx::stoi(s);
281        }
282        static std::string print(int value) {
283                return strEx::itos(value) + "%";
284        }
285        static std::string print_unformated(int value) {
286                return strEx::itos(value);
287        }
288        static std::string print_percent(int value) {
289                return strEx::itos(value) + "%";
290        }
291        static std::string key_prefix() {
292                return "average load ";
293        }
294        static std::string key_postfix() {
295                return "";
296        }
297};
298NSCAPI::nagiosReturn CheckSystem::checkCPU(const unsigned int argLen, char **char_args, std::string &msg, std::string &perf)
299{
300        typedef checkHolders::CheckConatiner<checkHolders::MaxMinBounds<checkHolders::NumericBounds<int, cpuload_handler> > > CPULoadConatiner;
301
302        std::list<std::string> stl_args = arrayBuffer::arrayBuffer2list(argLen, char_args);
303        if (stl_args.empty()) {
304                msg = "ERROR: Missing argument exception.";
305                return NSCAPI::returnUNKNOWN;
306        }
307        std::list<CPULoadConatiner> list;
308        NSCAPI::nagiosReturn returnCode = NSCAPI::returnOK;
309        bool bNSClient = false;
310        CPULoadConatiner tmpObject;
311
312        tmpObject.data = "cpuload";
313
314        MAP_OPTIONS_BEGIN(stl_args)
315                MAP_OPTIONS_NUMERIC_ALL(tmpObject, "")
316                MAP_OPTIONS_STR("warn", tmpObject.warn.max)
317                MAP_OPTIONS_STR("crit", tmpObject.crit.max)
318                MAP_OPTIONS_STR_AND("time", tmpObject.data, list.push_back(tmpObject))
319                MAP_OPTIONS_STR_AND("Time", tmpObject.data, list.push_back(tmpObject))
320                MAP_OPTIONS_SHOWALL(tmpObject)
321                MAP_OPTIONS_BOOL_TRUE(NSCLIENT, bNSClient)
322                        MAP_OPTIONS_SECONDARY_BEGIN(":", p2)
323                        else if (p2.first == "Time") {
324                                tmpObject.data = p__.second;
325                                tmpObject.alias = p2.second;
326                                list.push_back(tmpObject);
327                        }
328                        MAP_OPTIONS_MISSING_EX(p2, msg, "Unknown argument: ")
329                        MAP_OPTIONS_SECONDARY_END()
330                MAP_OPTIONS_FALLBACK_AND(tmpObject.data, list.push_back(tmpObject))
331        MAP_OPTIONS_END()
332
333        for (std::list<CPULoadConatiner>::const_iterator it = list.begin(); it != list.end(); ++it) {
334                CPULoadConatiner load = (*it);
335                PDHCollector *pObject = pdhThread.getThread();
336                if (!pObject) {
337                        msg = "ERROR: PDH Collection thread not running.";
338                        return NSCAPI::returnUNKNOWN;
339                }
340                int value = pObject->getCPUAvrage(load.data + "m");
341                if (value == -1) {
342                        msg = "ERROR: We don't collect data this far back: " + load.getAlias();
343                        return NSCAPI::returnUNKNOWN;
344                }
345                if (bNSClient) {
346                        if (!msg.empty()) msg += "&";
347                        msg += strEx::itos(value);
348                } else {
349                        load.setDefault(tmpObject);
350                        load.runCheck(value, returnCode, msg, perf);
351                }
352        }
353
354        if (msg.empty())
355                msg = "OK CPU Load ok.";
356        else if (!bNSClient)
357                msg = NSCHelper::translateReturn(returnCode) + ": " + msg;
358        return returnCode;
359}
360
361NSCAPI::nagiosReturn CheckSystem::checkUpTime(const unsigned int argLen, char **char_args, std::string &msg, std::string &perf)
362{
363        typedef checkHolders::CheckConatiner<checkHolders::MaxMinBoundsTime> UpTimeConatiner;
364
365        std::list<std::string> stl_args = arrayBuffer::arrayBuffer2list(argLen, char_args);
366        if (stl_args.empty()) {
367                msg = "ERROR: Missing argument exception.";
368                return NSCAPI::returnUNKNOWN;
369        }
370        NSCAPI::nagiosReturn returnCode = NSCAPI::returnOK;
371        bool bNSClient = false;
372        UpTimeConatiner bounds;
373
374        bounds.data = "uptime";
375
376        MAP_OPTIONS_BEGIN(stl_args)
377                MAP_OPTIONS_NUMERIC_ALL(bounds, "")
378                MAP_OPTIONS_STR("warn", bounds.warn.min)
379                MAP_OPTIONS_STR("crit", bounds.crit.min)
380                MAP_OPTIONS_STR("Alias", bounds.data)
381                MAP_OPTIONS_SHOWALL(bounds)
382                MAP_OPTIONS_BOOL_TRUE(NSCLIENT, bNSClient)
383                MAP_OPTIONS_MISSING(msg, "Unknown argument: ")
384        MAP_OPTIONS_END()
385
386
387        PDHCollector *pObject = pdhThread.getThread();
388        if (!pObject) {
389                msg = "ERROR: PDH Collection thread not running.";
390                return NSCAPI::returnUNKNOWN;
391        }
392        unsigned long long value = pObject->getUptime();
393        if (bNSClient) {
394                msg = strEx::itos(value);
395        } else {
396                value *= 1000;
397                bounds.runCheck(value, returnCode, msg, perf);
398        }
399
400        if (msg.empty())
401                msg = "OK all counters within bounds.";
402        else if (!bNSClient)
403                msg = NSCHelper::translateReturn(returnCode) + ": " + msg;
404        return returnCode;
405}
406
407// @todo state_handler
408
409
410
411/**
412 * Retrieve the service state of one or more services (by name).
413 * Parse a list with a service names and verify that all named services are running.
414 * <pre>
415 * Syntax:
416 * request: checkServiceState <option> [<option> [...]]
417 * Return: <return state>&<service1> : <state1> - <service2> : <state2> - ...
418 * Available options:
419 *              <name>=<state>  Check if a service has a specific state
420 *                      State can be wither started or stopped
421 *              ShowAll                 Show the state of all listed service. If not set only critical services are listed.
422 * Examples:
423 * checkServiceState showAll myService MyService
424 *</pre>
425 *
426 * @param command Command to execute
427 * @param argLen The length of the argument buffer
428 * @param **char_args The argument buffer
429 * @param &msg String to put message in
430 * @param &perf String to put performance data in
431 * @return The status of the command
432 */
433NSCAPI::nagiosReturn CheckSystem::checkServiceState(const unsigned int argLen, char **char_args, std::string &msg, std::string &perf)
434{
435        typedef checkHolders::CheckConatiner<checkHolders::SimpleBoundsStateBoundsInteger> StateConatiner;
436        std::list<std::string> stl_args = arrayBuffer::arrayBuffer2list(argLen, char_args);
437        if (stl_args.empty()) {
438                msg = "ERROR: Missing argument exception.";
439                return NSCAPI::returnUNKNOWN;
440        }
441        std::list<StateConatiner> list;
442        NSCAPI::nagiosReturn returnCode = NSCAPI::returnOK;
443        bool bNSClient = false;
444        StateConatiner tmpObject;
445
446        tmpObject.data = "uptime";
447        tmpObject.warn.state = "started";
448
449        MAP_OPTIONS_BEGIN(stl_args)
450                MAP_OPTIONS_SHOWALL(tmpObject)
451                MAP_OPTIONS_STR("Alias", tmpObject.data)
452                MAP_OPTIONS_BOOL_TRUE(NSCLIENT, bNSClient)
453                MAP_OPTIONS_SECONDARY_BEGIN(":", p2)
454                        else if (p2.first == "Time") {
455                                tmpObject.data = p__.second;
456                                tmpObject.alias = p2.second;
457                                list.push_back(tmpObject);
458                        }
459                        MAP_OPTIONS_MISSING_EX(p2, msg, "Unknown argument: ")
460                MAP_OPTIONS_SECONDARY_END()
461                else {
462                        tmpObject.data = p__.first;
463                        if (p__.second.empty())
464                                tmpObject.crit.state = "started";
465                        else
466                                tmpObject.crit.state = p__.second;
467                        list.push_back(tmpObject);
468                }
469        MAP_OPTIONS_END()
470
471        for (std::list<StateConatiner>::iterator it = list.begin(); it != list.end(); ++it) {
472                TNtServiceInfo info;
473                if (bNSClient) {
474                        try {
475                                info = TNtServiceInfo::GetService((*it).data.c_str());
476                        } catch (NTServiceException e) {
477                                if (!msg.empty()) msg += " - ";
478                                msg += (*it).data + ": Unknown";
479                                NSCHelper::escalteReturnCodeToWARN(returnCode);
480                                continue;
481                        }
482                        if ((info.m_dwCurrentState == SERVICE_RUNNING) && (*it).showAll()) {
483                                if (!msg.empty()) msg += " - ";
484                                msg += (*it).data + ": Started";
485                        } else if (info.m_dwCurrentState == SERVICE_RUNNING) {
486                        } else if (info.m_dwCurrentState == SERVICE_STOPPED) {
487                                if (!msg.empty()) msg += " - ";
488                                msg += (*it).data + ": Stopped";
489                                NSCHelper::escalteReturnCodeToCRIT(returnCode);
490                        } else {
491                                if (!msg.empty()) msg += " - ";
492                                msg += (*it).data + ": Unknown";
493                                NSCHelper::escalteReturnCodeToWARN(returnCode);
494                        }
495                } else {
496                        try {
497                                info = TNtServiceInfo::GetService((*it).data.c_str());
498                        } catch (NTServiceException e) {
499                                NSC_LOG_ERROR_STD(e.getError());
500                                msg = e.getError();
501                                return NSCAPI::returnUNKNOWN;
502                        }
503                        checkHolders::state_type value;
504                        if (info.m_dwCurrentState == SERVICE_RUNNING)
505                                value = checkHolders::state_started;
506                        else if (info.m_dwCurrentState == SERVICE_STOPPED)
507                                value = checkHolders::state_stopped;
508                        else
509                                value = checkHolders::state_none;
510                        (*it).runCheck(value, returnCode, msg, perf);
511                }
512
513        }
514        if (msg.empty())
515                msg = "OK: All services are running.";
516        else if (!bNSClient)
517                msg = NSCHelper::translateReturn(returnCode) + ": " + msg;
518        return returnCode;
519}
520
521
522/**
523 * Check available memory and return various check results
524 * Example: checkMem showAll maxWarn=50 maxCrit=75
525 *
526 * @param command Command to execute
527 * @param argLen The length of the argument buffer
528 * @param **char_args The argument buffer
529 * @param &msg String to put message in
530 * @param &perf String to put performance data in
531 * @return The status of the command
532 */
533NSCAPI::nagiosReturn CheckSystem::checkMem(const unsigned int argLen, char **char_args, std::string &msg, std::string &perf)
534{
535        typedef checkHolders::CheckConatiner<checkHolders::MaxMinBounds<checkHolders::NumericPercentageBounds<checkHolders::PercentageValueType<unsigned __int64, unsigned __int64>, checkHolders::disk_size_handler<unsigned __int64> > > > MemoryConatiner;
536        std::list<std::string> stl_args = arrayBuffer::arrayBuffer2list(argLen, char_args);
537        if (stl_args.empty()) {
538                msg = "ERROR: Missing argument exception.";
539                return NSCAPI::returnUNKNOWN;
540        }
541        NSCAPI::nagiosReturn returnCode = NSCAPI::returnOK;
542        bool bShowAll = false;
543        bool bNSClient = false;
544        MemoryConatiner bounds;
545        typedef enum { tPaged, tPage, tVirtual, tPhysical } check_type;
546        check_type type = tPaged;
547
548        MAP_OPTIONS_BEGIN(stl_args)
549                MAP_OPTIONS_DISK_ALL(bounds, "", "Free", "Used")
550                MAP_OPTIONS_STR("Alias", bounds.data)
551                MAP_OPTIONS_SHOWALL(bounds)
552                MAP_OPTIONS_BOOL_TRUE(NSCLIENT, bNSClient)
553                MAP_OPTIONS_MODE("type", "paged", type, tPaged)
554                MAP_OPTIONS_MODE("type", "page", type, tPage)
555                MAP_OPTIONS_MODE("type", "virtual", type, tVirtual)
556                MAP_OPTIONS_MODE("type", "physical", type, tPhysical)
557                MAP_OPTIONS_MISSING(msg, "Unknown argument: ")
558        MAP_OPTIONS_END()
559
560
561        checkHolders::PercentageValueType<unsigned long long, unsigned long long> value;
562        if (type == tPaged) {
563                PDHCollector *pObject = pdhThread.getThread();
564                if (!pObject) {
565                        msg = "ERROR: PDH Collection thread not running.";
566                        return NSCAPI::returnUNKNOWN;
567                }
568                value.value = pObject->getMemCommit();
569                value.total = pObject->getMemCommitLimit();
570                if (bounds.data.empty())
571                        bounds.data = "paged bytes";
572        } else {
573                CheckMemory::memData data;
574                try {
575                        data = memoryChecker.getMemoryStatus();
576                } catch (CheckMemoryException e) {
577                        msg = e.getError() + ":" + strEx::itos(e.getErrorCode());
578                        return NSCAPI::returnCRIT;
579                }
580//              MEMORYSTATUS mem;
581//              GlobalMemoryStatus(&mem);
582                if (type == tPage) {
583                        value.value = data.pageFile.total-data.pageFile.avail; // mem.dwTotalPageFile-mem.dwAvailPageFile;
584                        value.total = data.pageFile.total; //mem.dwTotalPageFile;
585                        if (bounds.data.empty())
586                                bounds.data = "page file";
587                } else  if (type == tPhysical) {
588                        value.value = data.phys.total-data.phys.avail; //mem.dwTotalPhys-mem.dwAvailPhys;
589                        value.total = data.phys.total; //mem.dwTotalPhys;
590                        if (bounds.data.empty())
591                                bounds.data = "physical memory";
592                } else  if (type == tVirtual) {
593                        value.value = data.virtualMem.total-data.virtualMem.avail;//mem.dwTotalVirtual-mem.dwAvailVirtual;
594                        value.total = data.virtualMem.total;//mem.dwTotalVirtual;
595                        if (bounds.data.empty())
596                                bounds.data = "virtual memory";
597                }
598        }
599
600        if (bNSClient) {
601                msg = strEx::itos(value.total) + "&" + strEx::itos(value.value);
602                return NSCAPI::returnOK;
603        } else {
604                bounds.runCheck(value, returnCode, msg, perf);
605        }
606        if (msg.empty())
607                msg = "OK memory within bounds.";
608        else
609                msg = NSCHelper::translateReturn(returnCode) + ": " + msg;
610        return returnCode;
611}
612typedef struct NSPROCDATA__ {
613        NSPROCDATA__() : count(0) {}
614        NSPROCDATA__(const NSPROCDATA__ &other) {
615                count = other.count;
616                entry = other.entry;
617        }
618
619        unsigned int count;
620        CEnumProcess::CProcessEntry entry;
621} NSPROCDATA;
622typedef std::map<std::string,NSPROCDATA,strEx::case_blind_string_compare> NSPROCLST;
623/**
624* Get a hash_map with all running processes.
625* @return a hash_map with all running processes
626*/
627NSPROCLST GetProcessList(int processMethod)
628{
629        NSPROCLST ret;
630        if (processMethod == 0) {
631                NSC_LOG_ERROR_STD("ProcessMethod not defined or not available.");
632                return ret;
633        }
634        CEnumProcess enumeration;
635        enumeration.SetMethod(processMethod);
636        CEnumProcess::CProcessEntry entry;
637        for (BOOL OK = enumeration.GetProcessFirst(&entry); OK; OK = enumeration.GetProcessNext(&entry) ) {
638                NSPROCLST::iterator it = ret.find(entry.sFilename);
639                if (it == ret.end())
640                        ret[entry.sFilename].entry = entry;
641                else
642                        (*it).second.count++;
643        }
644        return ret;
645}
646
647/**
648 * Check process state and return result
649 *
650 * @param command Command to execute
651 * @param argLen The length of the argument buffer
652 * @param **char_args The argument buffer
653 * @param &msg String to put message in
654 * @param &perf String to put performance data in
655 * @return The status of the command
656 */
657NSCAPI::nagiosReturn CheckSystem::checkProcState(const unsigned int argLen, char **char_args, std::string &msg, std::string &perf)
658{
659        typedef checkHolders::CheckConatiner<checkHolders::MaxMinStateBoundsStateBoundsInteger> StateConatiner;
660        std::list<std::string> stl_args = arrayBuffer::arrayBuffer2list(argLen, char_args);
661        if (stl_args.empty()) {
662                msg = "ERROR: Missing argument exception.";
663                return NSCAPI::returnUNKNOWN;
664        }
665        std::list<StateConatiner> list;
666        NSCAPI::nagiosReturn returnCode = NSCAPI::returnOK;
667        bool bNSClient = false;
668        StateConatiner tmpObject;
669
670        tmpObject.data = "uptime";
671        tmpObject.crit.state = "started";
672
673        MAP_OPTIONS_BEGIN(stl_args)
674                MAP_OPTIONS_NUMERIC_ALL(tmpObject, "Count")
675                MAP_OPTIONS_STR("Alias", tmpObject.alias)
676                MAP_OPTIONS_SHOWALL(tmpObject)
677                MAP_OPTIONS_BOOL_TRUE(NSCLIENT, bNSClient)
678                MAP_OPTIONS_SECONDARY_BEGIN(":", p2)
679                else if (p2.first == "Proc") {
680                        tmpObject.data = p__.second;
681                        tmpObject.alias = p2.second;
682                        list.push_back(tmpObject);
683                }
684                MAP_OPTIONS_MISSING_EX(p2, msg, "Unknown argument: ")
685                        MAP_OPTIONS_SECONDARY_END()
686                else {
687                        tmpObject.data = p__.first;
688                        if (p__.second.empty())
689                                tmpObject.crit.state = "started";
690                        else
691                                tmpObject.crit.state = p__.second;
692                        list.push_back(tmpObject);
693                }
694        MAP_OPTIONS_END()
695
696
697        NSPROCLST runningProcs;
698        try {
699                runningProcs = GetProcessList(processMethod_);
700        } catch (char *c) {
701                NSC_LOG_ERROR_STD("ERROR: " + c);
702                msg = static_cast<std::string>("ERROR: ") + c;
703                return NSCAPI::returnUNKNOWN;
704        }
705
706        for (std::list<StateConatiner>::iterator it = list.begin(); it != list.end(); ++it) {
707                NSPROCLST::iterator proc = runningProcs.find((*it).data);
708                bool bFound = proc != runningProcs.end();
709                std::string tmp;
710                TNtServiceInfo info;
711                if (bNSClient) {
712                        if (bFound && (*it).showAll()) {
713                                if (!msg.empty()) msg += " - ";
714                                msg += (*it).data + ": Started";
715                        } else if (bFound) {
716                        } else {
717                                if (!msg.empty()) msg += " - ";
718                                msg += (*it).data + ": Stopped";
719                                NSCHelper::escalteReturnCodeToCRIT(returnCode);
720                        }
721                } else {
722                        checkHolders::MaxMinStateValueType<int, checkHolders::state_type> value;
723                        if (bFound) {
724                                value.count = (*proc).second.count;
725                                value.state = checkHolders::state_started;
726                        } else {
727                                value.count = 0;
728                                value.state = checkHolders::state_stopped;
729                        }
730                        (*it).runCheck(value, returnCode, msg, perf);
731                }
732
733        }
734        if (msg.empty())
735                msg = "OK: All processes are running.";
736        else if (!bNSClient)
737                msg = NSCHelper::translateReturn(returnCode) + ": " + msg;
738        return returnCode;
739}
740
741
742/**
743 * Check a counter and return the value
744 *
745 * @param command Command to execute
746 * @param argLen The length of the argument buffer
747 * @param **char_args The argument buffer
748 * @param &msg String to put message in
749 * @param &perf String to put performance data in
750 * @return The status of the command
751 *
752 * @todo add parsing support for NRPE
753 */
754NSCAPI::nagiosReturn CheckSystem::checkCounter(const unsigned int argLen, char **char_args, std::string &msg, std::string &perf)
755{
756        typedef checkHolders::CheckConatiner<checkHolders::MaxMinBoundsDouble> CounterConatiner;
757
758        std::list<std::string> stl_args = arrayBuffer::arrayBuffer2list(argLen, char_args);
759        if (stl_args.empty()) {
760                msg = "ERROR: Missing argument exception.";
761                return NSCAPI::returnUNKNOWN;
762        }
763        std::list<CounterConatiner> counters;
764        NSCAPI::nagiosReturn returnCode = NSCAPI::returnOK;
765        bool bNSClient = false;
766        /* average maax */
767        bool bCheckAverages = true;
768        unsigned int averageDelay = 1000;
769        CounterConatiner tmpObject;
770
771        MAP_OPTIONS_BEGIN(stl_args)
772                MAP_OPTIONS_STR_AND("Counter", tmpObject.data, counters.push_back(tmpObject))
773                MAP_OPTIONS_STR("MaxWarn", tmpObject.warn.max)
774                MAP_OPTIONS_STR("MinWarn", tmpObject.warn.min)
775                MAP_OPTIONS_STR("MaxCrit", tmpObject.crit.max)
776                MAP_OPTIONS_STR("MinCrit", tmpObject.crit.min)
777                MAP_OPTIONS_STR("Alias", tmpObject.data)
778                MAP_OPTIONS_SHOWALL(tmpObject)
779                MAP_OPTIONS_BOOL_EX("Averages", bCheckAverages, "true", "false")
780                MAP_OPTIONS_BOOL_TRUE(NSCLIENT, bNSClient)
781                MAP_OPTIONS_SECONDARY_BEGIN(":", p2)
782                        else if (p2.first == "Counter") {
783                                tmpObject.data = p__.second;
784                                tmpObject.alias = p2.second;
785                                counters.push_back(tmpObject);
786                        }
787                        MAP_OPTIONS_MISSING_EX(p2, msg, "Unknown argument: ")
788                MAP_OPTIONS_SECONDARY_END()
789                MAP_OPTIONS_FALLBACK_AND(tmpObject.data, counters.push_back(tmpObject))
790        MAP_OPTIONS_END()
791
792        for (std::list<CounterConatiner>::const_iterator cit = counters.begin(); cit != counters.end(); ++cit) {
793                CounterConatiner counter = (*cit);
794                try {
795                        std::string tstr;
796                        if (!PDH::Enumerations::validate(counter.data, tstr)) {
797                                msg = tstr;
798                                msg += " (" + counter.getAlias() + "|" + counter.data + ")";
799                                return NSCAPI::returnUNKNOWN;
800                        }
801                        PDH::PDHQuery pdh;
802                        PDHCollectors::StaticPDHCounterListener<double, PDH_FMT_DOUBLE> cDouble;
803                        pdh.addCounter(counter.data, &cDouble);
804                        pdh.open();
805                        if (bCheckAverages) {
806                                pdh.collect();
807                                Sleep(1000);
808                        }
809                        pdh.gatherData();
810                        pdh.close();
811                        double value = cDouble.getValue();
812                        std::cout << "Collected double data: " << value << std::endl;
813                        if (bNSClient) {
814                                msg += strEx::itos(value);
815                        } else {
816                                counter.setDefault(tmpObject);
817                                counter.runCheck(value, returnCode, msg, perf);
818                        }
819                } catch (const PDH::PDHException e) {
820                        NSC_LOG_ERROR_STD("ERROR: " + e.getError() + " (" + counter.getAlias() + "|" + counter.data + ")");
821                        msg = static_cast<std::string>("ERROR: ") + e.getError()+ " (" + counter.getAlias() + "|" + counter.data + ")";
822                        return NSCAPI::returnUNKNOWN;
823                }
824        }
825
826        if (msg.empty())
827                msg = "OK all counters within bounds.";
828        else if (!bNSClient)
829                msg = NSCHelper::translateReturn(returnCode) + ": " + msg;
830        return returnCode;
831}
832NSC_WRAPPERS_MAIN_DEF(gCheckSystem);
833NSC_WRAPPERS_IGNORE_MSG_DEF();
834NSC_WRAPPERS_HANDLE_CMD_DEF(gCheckSystem);
835NSC_WRAPPERS_HANDLE_CONFIGURATION(gCheckSystem);
836NSC_WRAPPERS_CLI_DEF(gCheckSystem);
837
838
839
840MODULE_SETTINGS_START(CheckSystem, "System check module", "...")
841
842PAGE("Check options")
843
844ITEM_EDIT_TEXT("Check resolution", "This is how often the PDH data is polled and stored in the CPU buffer. (this is enterd in 1/th: of a second)")
845OPTION("unit", "1/10:th of a second")
846ITEM_MAP_TO("basic_ini_text_mapper")
847OPTION("section", "Check System")
848OPTION("key", "CheckResolution")
849OPTION("default", "10")
850ITEM_END()
851
852ITEM_EDIT_TEXT("CPU buffer size", "This is the size of the buffer that stores CPU history.")
853ITEM_MAP_TO("basic_ini_text_mapper")
854OPTION("section", "Check System")
855OPTION("key", "CPUBufferSize")
856OPTION("default", "1h")
857ITEM_END()
858
859PAGE_END()
860ADVANCED_PAGE("Compatiblity settings")
861
862ITEM_EDIT_TEXT("MemoryCommitByte", "The memory commited bytes used to calculate the avalible memory.")
863OPTION("disableCaption", "Attempt to autodetect this.")
864OPTION("disabled", "auto")
865ITEM_MAP_TO("basic_ini_text_mapper")
866OPTION("section", "Check System")
867OPTION("key", "MemoryCommitByte")
868OPTION("default", "auto")
869ITEM_END()
870
871ITEM_EDIT_TEXT("MemoryCommitLimit", "The memory commit limit used to calculate the avalible memory.")
872OPTION("disableCaption", "Attempt to autodetect this.")
873OPTION("disabled", "auto")
874ITEM_MAP_TO("basic_ini_text_mapper")
875OPTION("section", "Check System")
876OPTION("key", "MemoryCommitLimit")
877OPTION("default", "auto")
878ITEM_END()
879
880ITEM_EDIT_TEXT("SystemSystemUpTime", "The PDH counter for the System uptime.")
881OPTION("disableCaption", "Attempt to autodetect this.")
882OPTION("disabled", "auto")
883ITEM_MAP_TO("basic_ini_text_mapper")
884OPTION("section", "Check System")
885OPTION("key", "SystemSystemUpTime")
886OPTION("default", "auto")
887ITEM_END()
888
889ITEM_EDIT_TEXT("SystemTotalProcessorTime", "The PDH conter usaed to measure CPU load.")
890OPTION("disableCaption", "Attempt to autodetect this.")
891OPTION("disabled", "auto")
892ITEM_MAP_TO("basic_ini_text_mapper")
893OPTION("section", "Check System")
894OPTION("key", "SystemTotalProcessorTime")
895OPTION("default", "auto")
896ITEM_END()
897
898ITEM_EDIT_TEXT("ProcessEnumerationMethod", "The method to use when enumerating processes")
899OPTION("count", "3")
900OPTION("caption_1", "Autodetect (TOOLHELP for NT/4 and PSAPI for W2k)")
901OPTION("value_1", "auto")
902OPTION("caption_2", "TOOLHELP use this for NT/4 systems")
903OPTION("value_2", "TOOLHELP")
904OPTION("caption_3", "PSAPI use this for W2k (and abowe) systems")
905OPTION("value_3", "PSAPI")
906ITEM_MAP_TO("basic_ini_text_mapper")
907OPTION("section", "Check System")
908OPTION("key", "ProcessEnumerationMethod")
909OPTION("default", "auto")
910ITEM_END()
911
912PAGE_END()
913MODULE_SETTINGS_END()
Note: See TracBrowser for help on using the repository browser.