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

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

Lots of update (I really should checkin more often :)

  • Property mode set to 100644
File size: 7.5 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 (mickem@medin.nu)
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");
68
69
70                try {
71                        OSVERSIONINFO osVer = systemInfo::getOSVersion();
72                        if (!systemInfo::isNTBased(osVer)) {
73                                NSC_LOG_ERROR_STD("Detected Windows 3.x or Windows 9x, PDH will be disabled.");
74                                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.");
75                                return 0;
76                        }
77
78                        LANGID langId = -1;
79                        if (systemInfo::isBelowNT4(osVer)) {
80                                NSC_DEBUG_MSG_STD("Autodetected NT4, using NT4 PDH counters.");
81                                prefix = "NT4";
82                                langId = systemInfo::GetSystemDefaultLangID();
83                        } else if (systemInfo::isAboveW2K(osVer)) {
84                                NSC_DEBUG_MSG_STD("Autodetected w2k or later, using w2k PDH counters.");
85                                prefix = "W2K";
86                                langId = systemInfo::GetSystemDefaultUILanguage();
87                        } else {
88                                NSC_LOG_ERROR_STD("Unknown OS detected, PDH will be disabled.");
89                                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.");
90                                return 0;
91                        }
92
93                        section = "0000" + strEx::ihextos(langId);
94                        section = "0x" + section.substr(section.length()-4);
95                        NSC_DEBUG_MSG_STD("Detected language: " + settings.getString(section, "Description", "Not found") + " (" + section + ")");
96                } catch (systemInfo::SystemInfoException e) {
97                        NSC_LOG_ERROR_STD("System detection failed, PDH will be disabled: " + e.error_);
98                        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.");
99                        return -1;
100                }
101
102                pdh.addCounter(settings.getString(section, prefix + "_" + C_SYSTEM_MEM_PAGE_LIMIT, C_SYSTEM_MEM_PAGE_LIMIT_DEFAULT), &memCmtLim);
103                pdh.addCounter(settings.getString(section, prefix + "_" + C_SYSTEM_MEM_PAGE, C_SYSTEM_MEM_PAGE_DEFAULT), &memCmt);
104                pdh.addCounter(settings.getString(section, prefix + "_" + C_SYSTEM_UPTIME, C_SYSTEM_UPTIME_DEFAULT), &upTime);
105                pdh.addCounter(settings.getString(section, prefix + "_" + C_SYSTEM_CPU, C_SYSTEM_MEM_CPU_DEFAULT), &cpu);
106        } else {
107                pdh.addCounter(NSCModuleHelper::getSettingsString(C_SYSTEM_SECTION_TITLE, C_SYSTEM_MEM_PAGE_LIMIT, C_SYSTEM_MEM_PAGE_LIMIT_DEFAULT), &memCmtLim);
108                pdh.addCounter(NSCModuleHelper::getSettingsString(C_SYSTEM_SECTION_TITLE, C_SYSTEM_MEM_PAGE, C_SYSTEM_MEM_PAGE_DEFAULT), &memCmt);
109                pdh.addCounter(NSCModuleHelper::getSettingsString(C_SYSTEM_SECTION_TITLE, C_SYSTEM_UPTIME, C_SYSTEM_UPTIME_DEFAULT), &upTime);
110                pdh.addCounter(NSCModuleHelper::getSettingsString(C_SYSTEM_SECTION_TITLE, C_SYSTEM_CPU, C_SYSTEM_MEM_CPU_DEFAULT), &cpu);
111        }
112
113        try {
114                pdh.open();
115        } catch (const PDH::PDHException &e) {
116                NSC_LOG_ERROR_STD("Failed to open performance counters: " + e.getError());
117                return 0;
118        }
119
120
121        DWORD waitStatus = 0;
122        do {
123                MutexLock mutex(mutexHandler);
124                if (!mutex.hasMutex())
125                        NSC_LOG_ERROR("Failed to get Mutex!");
126                else {
127                        try {
128                                pdh.gatherData();
129                        } catch (const PDH::PDHException &e) {
130                                NSC_LOG_ERROR_STD("Failed to query performance counters: " + e.getError());
131                        }
132                }
133        }while (((waitStatus = WaitForSingleObject(hStopEvent_, checkIntervall_*100)) == WAIT_TIMEOUT));
134        if (waitStatus != WAIT_OBJECT_0) {
135                NSC_LOG_ERROR("Something odd happened, terminating PDH collection thread!");
136        }
137
138        {
139                MutexLock mutex(mutexHandler);
140                if (!mutex.hasMutex()) {
141                        NSC_LOG_ERROR("Failed to get Mute when closing thread!");
142                }
143
144                if (!CloseHandle(hStopEvent_)) {
145                        NSC_LOG_ERROR_STD("Failed to close stopEvent handle: " + strEx::itos(GetLastError()));
146                } else
147                        hStopEvent_ = NULL;
148                try {
149                        pdh.close();
150                } catch (const PDH::PDHException &e) {
151                        NSC_LOG_ERROR_STD("Failed to close performance counters: " + e.getError());
152                }
153        }
154        return 0;
155}
156
157
158/**
159* Request termination of the thread (waiting for thread termination is not handled)
160*/
161void PDHCollector::exitThread(void) {
162        if (hStopEvent_ == NULL)
163                NSC_LOG_ERROR("Stop event is not created!");
164        else
165                if (!SetEvent(hStopEvent_)) {
166                        NSC_LOG_ERROR_STD("SetStopEvent failed");
167                }
168}
169/**
170* Get the average CPU usage for "time"
171* @param time Time to check
172* @return average CPU usage
173*/
174int PDHCollector::getCPUAvrage(std::string time) {
175        unsigned int mseconds = strEx::stoui_as_time(time, checkIntervall_*100);
176        MutexLock mutex(mutexHandler);
177        if (!mutex.hasMutex()) {
178                NSC_LOG_ERROR("Failed to get Mutex!");
179                return -1;
180        }
181        return static_cast<int>(cpu.getAvrage(mseconds / (checkIntervall_*100)));
182}
183/**
184* Get uptime from counter
185* @bug Do we need to collect this all the time ? (perhaps we can collect this in real time ?)
186* @return uptime for the system
187* @bug Are we overflow protected here ? (seem to recall some issues with overflow before ?)
188*/
189long long PDHCollector::getUptime() {
190        MutexLock mutex(mutexHandler);
191        if (!mutex.hasMutex()) {
192                NSC_LOG_ERROR("Failed to get Mutex!");
193                return -1;
194        }
195        return upTime.getValue();
196}
197/**
198* Memory commit limit (your guess is as good as mine to what this is :)
199* @return Some form of memory check
200*/
201unsigned long long PDHCollector::getMemCommitLimit() {
202        MutexLock mutex(mutexHandler);
203        if (!mutex.hasMutex()) {
204                NSC_LOG_ERROR("Failed to get Mutex!");
205                return -1;
206        }
207        return memCmtLim.getValue();
208}
209/**
210*
211* Memory committed bytes (your guess is as good as mine to what this is :)
212* @return Some form of memory check
213*/
214unsigned long long PDHCollector::getMemCommit() {
215        MutexLock mutex(mutexHandler);
216        if (!mutex.hasMutex()) {
217                NSC_LOG_ERROR("Failed to get Mutex!");
218                return -1;
219        }
220        return memCmt.getValue();
221}
Note: See TracBrowser for help on using the repository browser.