source: nscp/modules/CheckSystem/PDHCollector.cpp @ dc65e35

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

2006-03-05 MickeM

  • Fixed -v FILEAGE check_nt (NSClient) check.
  • Added licence agreement header to all files
  • Property mode set to 100644
File size: 8.2 KB
Line 
1//////////////////////////////////////////////////////////////////////////
2// PDH Collector
3//
4// Functions from this file collects data from the PDH subsystem and stores
5// it for later use
6// *NOTICE* that this is done in a separate thread so threading issues has
7// to be handled. I handle threading issues in the CounterListener's get/
8// set accessors.
9//
10// Copyright (c) 2004 MySolutions NORDIC (http://www.medin.nu)
11//
12// Date: 2004-03-13
13// Author: Michael Medin - <michael@medin.name>
14//
15// This software is provided "AS IS", without a warranty of any kind.
16// You are free to use/modify this code but leave this header intact.
17//
18//////////////////////////////////////////////////////////////////////////
19
20#include "stdafx.h"
21#include "PDHCollector.h"
22#include <Settings.h>
23#include <sysinfo.h>
24
25
26PDHCollector::PDHCollector() : hStopEvent_(NULL) {
27        checkIntervall_ = NSCModuleHelper::getSettingsInt(C_SYSTEM_SECTION_TITLE, C_SYSTEM_CHECK_RESOLUTION, C_SYSTEM_CHECK_RESOLUTION_DEFAULT);
28        std::string s = NSCModuleHelper::getSettingsString(C_SYSTEM_SECTION_TITLE, C_SYSTEM_CPU_BUFFER_TIME, C_SYSTEM_CPU_BUFFER_TIME_DEFAULT);
29        unsigned int i = strEx::stoui_as_time(s, checkIntervall_*100);
30        cpu.resize(i/(checkIntervall_*100));
31}
32
33PDHCollector::~PDHCollector()
34{
35        if (hStopEvent_)
36                CloseHandle(hStopEvent_);
37}
38
39/**
40* Thread that collects the data every "CHECK_INTERVAL" seconds.
41*
42* @param lpParameter Not used
43* @return thread exit status
44*
45* @author mickem
46*
47* @date 03-13-2004               
48*
49* @bug If we have "custom named" counters ?
50* @bug This whole concept needs work I think.
51*
52*/
53DWORD PDHCollector::threadProc(LPVOID lpParameter) {
54        hStopEvent_ = CreateEvent(NULL, TRUE, FALSE, NULL);
55        if (!hStopEvent_) {
56                NSC_LOG_ERROR_STD("Create StopEvent failed: " + strEx::itos(GetLastError()));
57                return 0;
58        }
59        PDH::PDHQuery pdh;
60
61
62        if (NSCModuleHelper::getSettingsInt(C_SYSTEM_SECTION_TITLE, C_SYSTEM_AUTODETECT_PDH, C_SYSTEM_AUTODETECT_PDH_DEFAULT) == 1) {
63
64                SettingsT settings;
65                std::string prefix;
66                std::string section;
67                settings.setFile(NSCModuleHelper::getBasePath() + "\\counters.defs", true);
68
69                NSC_LOG_ERROR_STD("Getting counter info...");
70
71                try {
72                        OSVERSIONINFO osVer = systemInfo::getOSVersion();
73                        if (!systemInfo::isNTBased(osVer)) {
74                                NSC_LOG_ERROR_STD("Detected Windows 3.x or Windows 9x, PDH will be disabled.");
75                                NSC_LOG_ERROR_STD("To manual set performance counters you need to first set " C_SYSTEM_AUTODETECT_PDH "=0 in the config file, and then you also need to configure the various counter.");
76                                return 0;
77                        }
78
79                        LANGID langId = -1;
80                        if (systemInfo::isBelowNT4(osVer)) {
81                                NSC_DEBUG_MSG_STD("Autodetected NT4, using NT4 PDH counters.");
82                                prefix = "NT4";
83                                langId = systemInfo::GetSystemDefaultLangID();
84                        } else if (systemInfo::isAboveW2K(osVer)) {
85                                NSC_DEBUG_MSG_STD("Autodetected w2k or later, using w2k PDH counters.");
86                                prefix = "W2K";
87                                langId = systemInfo::GetSystemDefaultUILanguage();
88                        } else {
89                                NSC_LOG_ERROR_STD("Unknown OS detected, PDH will be disabled.");
90                                NSC_LOG_ERROR_STD("To manual set performance counters you need to first set " C_SYSTEM_AUTODETECT_PDH "=0 in the config file, and then you also need to configure the various counter.");
91                                return 0;
92                        }
93
94                        section = "0000" + strEx::ihextos(langId);
95                        section = "0x" + section.substr(section.length()-4);
96                        if (settings.getString(section, "Description", "_NOT_FOUND") == "_NOT_FOUND") {
97                                NSC_LOG_ERROR_STD("Detected language: " + section + " but it could not be found in: counters.defs");
98                                NSC_LOG_ERROR_STD("You need to manually configure performance counters!");
99                                return 0;
100                        }
101                        NSC_DEBUG_MSG_STD("Detected language: " + settings.getString(section, "Description", "Not found") + " (" + section + ")");
102                } catch (const systemInfo::SystemInfoException &e) {
103                        //NSC_LOG_ERROR_STD("System detection failed, PDH will be disabled: " + e.getError());
104                        NSC_LOG_ERROR_STD("To manual set performance counters you need to first set " C_SYSTEM_AUTODETECT_PDH "=0 in the config file, and then you also need to configure the various counter.");
105                        return -1;
106                }
107
108                pdh.addCounter(settings.getString(section, prefix + "_" + C_SYSTEM_MEM_PAGE_LIMIT, C_SYSTEM_MEM_PAGE_LIMIT_DEFAULT), &memCmtLim);
109                pdh.addCounter(settings.getString(section, prefix + "_" + C_SYSTEM_MEM_PAGE, C_SYSTEM_MEM_PAGE_DEFAULT), &memCmt);
110                pdh.addCounter(settings.getString(section, prefix + "_" + C_SYSTEM_UPTIME, C_SYSTEM_UPTIME_DEFAULT), &upTime);
111                pdh.addCounter(settings.getString(section, prefix + "_" + C_SYSTEM_CPU, C_SYSTEM_MEM_CPU_DEFAULT), &cpu);
112        } else {
113                pdh.addCounter(NSCModuleHelper::getSettingsString(C_SYSTEM_SECTION_TITLE, C_SYSTEM_MEM_PAGE_LIMIT, C_SYSTEM_MEM_PAGE_LIMIT_DEFAULT), &memCmtLim);
114                pdh.addCounter(NSCModuleHelper::getSettingsString(C_SYSTEM_SECTION_TITLE, C_SYSTEM_MEM_PAGE, C_SYSTEM_MEM_PAGE_DEFAULT), &memCmt);
115                pdh.addCounter(NSCModuleHelper::getSettingsString(C_SYSTEM_SECTION_TITLE, C_SYSTEM_UPTIME, C_SYSTEM_UPTIME_DEFAULT), &upTime);
116                pdh.addCounter(NSCModuleHelper::getSettingsString(C_SYSTEM_SECTION_TITLE, C_SYSTEM_CPU, C_SYSTEM_MEM_CPU_DEFAULT), &cpu);
117        }
118
119        NSC_LOG_ERROR_STD("Attempting to open counter...");
120        try {
121                pdh.open();
122                NSC_LOG_ERROR_STD("Counters opend...");
123        } catch (const PDH::PDHException &e) {
124                NSC_LOG_ERROR_STD("Failed to open performance counters: " + e.getError());
125                return 0;
126        }
127
128
129        DWORD waitStatus = 0;
130        bool first = true;
131        do {
132                MutexLock mutex(mutexHandler);
133                if (!mutex.hasMutex())
134                        NSC_LOG_ERROR("Failed to get Mutex!");
135                else {
136                        try {
137                                pdh.gatherData();
138                        } catch (const PDH::PDHException &e) {
139                                if (first) {    // If this is the first run an error will be thrown since the data is not yet avalible
140                                                                // This is "ok" but perhaps another solution would be better, but this works :)
141                                        first = false;
142                                } else {
143                                        NSC_LOG_ERROR_STD("Failed to query performance counters: " + e.getError());
144                                }
145                        }
146                }
147        }while (((waitStatus = WaitForSingleObject(hStopEvent_, checkIntervall_*100)) == WAIT_TIMEOUT));
148        if (waitStatus != WAIT_OBJECT_0) {
149                NSC_LOG_ERROR("Something odd happened, terminating PDH collection thread!");
150        }
151
152        {
153                MutexLock mutex(mutexHandler);
154                if (!mutex.hasMutex()) {
155                        NSC_LOG_ERROR("Failed to get Mute when closing thread!");
156                }
157
158                if (!CloseHandle(hStopEvent_)) {
159                        NSC_LOG_ERROR_STD("Failed to close stopEvent handle: " + strEx::itos(GetLastError()));
160                } else
161                        hStopEvent_ = NULL;
162                try {
163                        pdh.close();
164                } catch (const PDH::PDHException &e) {
165                        NSC_LOG_ERROR_STD("Failed to close performance counters: " + e.getError());
166                }
167        }
168        return 0;
169}
170
171
172/**
173* Request termination of the thread (waiting for thread termination is not handled)
174*/
175void PDHCollector::exitThread(void) {
176        if (hStopEvent_ == NULL)
177                NSC_LOG_ERROR("Stop event is not created!");
178        else
179                if (!SetEvent(hStopEvent_)) {
180                        NSC_LOG_ERROR_STD("SetStopEvent failed");
181                }
182}
183/**
184* Get the average CPU usage for "time"
185* @param time Time to check
186* @return average CPU usage
187*/
188int PDHCollector::getCPUAvrage(std::string time) {
189        unsigned int mseconds = strEx::stoui_as_time(time, checkIntervall_*100);
190        MutexLock mutex(mutexHandler);
191        if (!mutex.hasMutex()) {
192                NSC_LOG_ERROR("Failed to get Mutex!");
193                return -1;
194        }
195        return static_cast<int>(cpu.getAvrage(mseconds / (checkIntervall_*100)));
196}
197/**
198* Get uptime from counter
199* @bug Do we need to collect this all the time ? (perhaps we can collect this in real time ?)
200* @return uptime for the system
201* @bug Are we overflow protected here ? (seem to recall some issues with overflow before ?)
202*/
203long long PDHCollector::getUptime() {
204        MutexLock mutex(mutexHandler);
205        if (!mutex.hasMutex()) {
206                NSC_LOG_ERROR("Failed to get Mutex!");
207                return -1;
208        }
209        return upTime.getValue();
210}
211/**
212* Memory commit limit (your guess is as good as mine to what this is :)
213* @return Some form of memory check
214*/
215unsigned long long PDHCollector::getMemCommitLimit() {
216        MutexLock mutex(mutexHandler);
217        if (!mutex.hasMutex()) {
218                NSC_LOG_ERROR("Failed to get Mutex!");
219                return -1;
220        }
221        return memCmtLim.getValue();
222}
223/**
224*
225* Memory committed bytes (your guess is as good as mine to what this is :)
226* @return Some form of memory check
227*/
228unsigned long long PDHCollector::getMemCommit() {
229        MutexLock mutex(mutexHandler);
230        if (!mutex.hasMutex()) {
231                NSC_LOG_ERROR("Failed to get Mutex!");
232                return -1;
233        }
234        return memCmt.getValue();
235}
Note: See TracBrowser for help on using the repository browser.