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

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

New build enviornment (static) to work with NT4 and w2k3 and hopefully everything else.
Also fixed the "broken password" issue..

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