bool PerfCounterMuninNodePlugin::OpenCounter() { PDH_STATUS status; m_Name = m_SectionName.substr(strlen(PerfCounterMuninNodePlugin::SectionPrefix)); OSVERSIONINFO osvi; ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); if (!GetVersionEx(&osvi) || (osvi.dwPlatformId != VER_PLATFORM_WIN32_NT)) { _Module.LogError("PerfCounter plugin: %s: unknown OS or not NT based", m_Name.c_str()); return false; //unknown OS or not NT based } // Create a PDH query status = PdhOpenQuery(NULL, 0, &m_PerfQuery); if (status != ERROR_SUCCESS) { _Module.LogError("PerfCounter plugin: %s: PdhOpenQuery error=%x", m_Name.c_str(), status); return false; } TString objectName = A2TConvert(g_Config.GetValue(m_SectionName, "Object", "LogicalDisk")); TString counterName = A2TConvert(g_Config.GetValue(m_SectionName, "Counter", "% Disk Time")); DWORD counterListLength = 0; DWORD instanceListLength = 0; if (g_Config.GetValueB(m_SectionName, "UseEnglishObjectNames", true)) { counterName = GetPdhCounterLocalizedName(counterName.c_str()); objectName = GetPdhCounterLocalizedName(objectName.c_str()); } status = PdhEnumObjectItems(NULL, NULL, objectName.c_str(), NULL, &counterListLength, NULL, &instanceListLength, PERF_DETAIL_EXPERT, 0); if (status != PDH_MORE_DATA) { _Module.LogError("PerfCounter plugin: %s: PdhEnumObjectItems error=%x", m_Name.c_str(), status); return false; } TCHAR *counterList = new TCHAR[counterListLength+2]; TCHAR *instanceList = new TCHAR[instanceListLength+2]; counterList[0] = NULL; instanceList[0] = NULL; counterList[1] = NULL; instanceList[1] = NULL; status = PdhEnumObjectItems(NULL, NULL, objectName.c_str(), counterList, &counterListLength, instanceList, &instanceListLength, PERF_DETAIL_EXPERT, 0); if (status != ERROR_SUCCESS) { delete [] counterList; delete [] instanceList; _Module.LogError("PerfCounter plugin: %s: PdhEnumObjectItems error=%x", m_Name.c_str(), status); return false; } int pos = 0; TCHAR *instanceName = instanceList; while (instanceName[0] != NULL) { std::string counterInstanceName = T2AConvert(instanceName); m_CounterNames.push_back(counterInstanceName); while (instanceName[0] != NULL) instanceName++; instanceName++; } delete [] counterList; delete [] instanceList; TCHAR counterPath[MAX_PATH] = {0}; HCOUNTER counterHandle; if (!m_CounterNames.empty()) { if (g_Config.GetValueB(m_SectionName, "DropTotal", true)) { assert(m_CounterNames.back().compare("_Total") == 0); // We drop the last instance name as it is _Total m_CounterNames.pop_back(); } for (size_t i = 0; i < m_CounterNames.size(); i++) { TString instanceNameStr = A2TConvert(m_CounterNames[i]); _sntprintf(counterPath, MAX_PATH, _T("\\%s(%s)\\%s"), objectName.c_str(), instanceNameStr.c_str(), counterName.c_str()); // Associate the uptime counter with the query status = PdhAddCounter(m_PerfQuery, counterPath, 0, &counterHandle); if (status != ERROR_SUCCESS) { _Module.LogError("PerfCounter plugin: %s: PDH add counter error=%x", m_Name.c_str(), status); return false; } m_Counters.push_back(counterHandle); } } else { // A counter with a single instance (Uptime for example) m_CounterNames.push_back("0"); _sntprintf(counterPath, MAX_PATH, _T("\\%s\\%s"), objectName.c_str(), counterName.c_str()); // Associate the uptime counter with the query status = PdhAddCounter(m_PerfQuery, counterPath, 0, &counterHandle); if (status != ERROR_SUCCESS) { _Module.LogError("PerfCounter plugin: %s: PDH add counter error=%x", m_Name.c_str(), status); return false; } m_Counters.push_back(counterHandle); } // Collect init data status = PdhCollectQueryData(m_PerfQuery); if (status != ERROR_SUCCESS) { if (status == PDH_INVALID_HANDLE) { _Module.LogError("PerfCounter plugin: %s: PDH collect data: PDH_INVALID_HANDLE", m_Name.c_str()); return false; } if (status == PDH_NO_DATA) { _Module.LogError("PerfCounter plugin: %s: PDH collect data: PDH_NO_DATA", m_Name.c_str()); return false; } _Module.LogError("PerfCounter plugin: %s: PDH collect data error", m_Name.c_str()); return false; } // Setup Counter Format m_dwCounterFormat = PDH_FMT_DOUBLE; std::string counterFormatStr = g_Config.GetValue(m_SectionName, "CounterFormat", "double"); if (!counterFormatStr.compare("double") || !counterFormatStr.compare("float")) { m_dwCounterFormat = PDH_FMT_DOUBLE; } else if (!counterFormatStr.compare("int") || !counterFormatStr.compare("long")) { m_dwCounterFormat = PDH_FMT_LONG; } else if (!counterFormatStr.compare("int64") || !counterFormatStr.compare("longlong") || !counterFormatStr.compare("large")) { m_dwCounterFormat = PDH_FMT_LARGE; } else { _Module.LogError("PerfCounter plugin: %s: Unknown CounterFormat", m_Name.c_str()); assert(!"Unknown CounterFormat!"); } m_CounterMultiply = g_Config.GetValueF(m_SectionName, "CounterMultiply", 1.0); return true; }
bool DiskTimeMuninNodePlugin::OpenCounter() { PDH_STATUS status; OSVERSIONINFO osvi; ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); if (!GetVersionEx(&osvi) || (osvi.dwPlatformId != VER_PLATFORM_WIN32_NT)) return false; //unknown OS or not NT based // Create a PDH query status = PdhOpenQuery(NULL, 0, &m_PerfQuery); if (status != ERROR_SUCCESS) return false; TString logicalDiskCounterName = A2TConvert(g_Config.GetValue("DiskTimePlugin", "CounterNameLogicalDisk", "LogicalDisk")); TString diskTimeCounterName = A2TConvert(g_Config.GetValue("DiskTimePlugin", "CounterNameDiskTime", "% Disk Time")); DWORD counterListLength = 0; DWORD instanceListLength = 0; status = PdhEnumObjectItems(NULL, NULL, logicalDiskCounterName.c_str(), NULL, &counterListLength, NULL, &instanceListLength, PERF_DETAIL_EXPERT, 0); if (status != PDH_MORE_DATA) return false; TCHAR *counterList = new TCHAR[counterListLength]; TCHAR *instanceList = new TCHAR[instanceListLength]; counterList[0] = NULL; instanceList[0] = NULL; status = PdhEnumObjectItems(NULL, NULL, logicalDiskCounterName.c_str(), counterList, &counterListLength, instanceList, &instanceListLength, PERF_DETAIL_EXPERT, 0); if (status != ERROR_SUCCESS) { delete [] counterList; delete [] instanceList; return false; } int pos = 0; TCHAR *instanceName = instanceList; while (instanceName[0] != NULL && instanceName[1] != NULL) { std::string diskName = T2AConvert(instanceName); m_DiskTimeNames.push_back(diskName); while (instanceName[0] != NULL) instanceName++; instanceName++; } delete [] counterList; delete [] instanceList; // We drop the last instance name as it is _Total m_DiskTimeNames.pop_back(); TCHAR diskTimeCounterPath[MAX_PATH] = {0}; HCOUNTER diskTimeCounter; for (size_t i = 0; i < m_DiskTimeNames.size(); i++) { _sntprintf(diskTimeCounterPath, MAX_PATH, _T("\\%s(%s)\\%s"), logicalDiskCounterName.c_str(), m_DiskTimeNames[i].c_str(), diskTimeCounterName.c_str()); // Associate the uptime counter with the query status = PdhAddCounter(m_PerfQuery, diskTimeCounterPath, 0, &diskTimeCounter); if (status != ERROR_SUCCESS) return false; m_DiskTimeCounters.push_back(diskTimeCounter); } // Collect init data status = PdhCollectQueryData(m_PerfQuery); if (status != ERROR_SUCCESS) return false; return true; }
bool PerfCounterMuninNodePlugin::OpenCounter() { PDH_STATUS status; m_Name = m_SectionName.substr(strlen(PerfCounterMuninNodePlugin::SectionPrefix)); OSVERSIONINFO osvi; ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); if (!GetVersionEx(&osvi) || (osvi.dwPlatformId != VER_PLATFORM_WIN32_NT)) { _Module.LogError("PerfCounter plugin: %s: unknown OS or not NT based", m_Name.c_str()); return false; //unknown OS or not NT based } // Create a PDH query status = PdhOpenQuery(NULL, 0, &m_PerfQuery); if (status != ERROR_SUCCESS) { _Module.LogError("PerfCounter plugin: %s: PdhOpenQuery error=%x", m_Name.c_str(), status); return false; } TString objectName = A2TConvert(g_Config.GetValue(m_SectionName, "Object", "LogicalDisk")); TString counterName = A2TConvert(g_Config.GetValue(m_SectionName, "Counter", "% Disk Time")); TString instanceName = A2TConvert(g_Config.GetValue(m_SectionName, "Instance", "*")); bool useEnglishNames = g_Config.GetValueB(m_SectionName, "UseEnglishObjectNames", true); if (useEnglishNames) { counterName = GetPdhCounterLocalizedName(counterName.c_str()); objectName = GetPdhCounterLocalizedName(objectName.c_str()); // NB: instance names are not localized } TCHAR *counterPath = new TCHAR[MAX_PATH]; status = _sntprintf(counterPath, MAX_PATH, _T("\\%s(%s)\\%s"), objectName.c_str(), instanceName.c_str(), counterName.c_str()); DWORD pathListBufsz = 0; status = PdhExpandWildCardPath(NULL, counterPath, NULL, &pathListBufsz, 0); if (status != PDH_MORE_DATA && status != PDH_INSUFFICIENT_BUFFER) { _Module.LogError("PerfCounter plugin: %s: PdhExpandWildCardPath error=%x", m_Name.c_str(), status); return false; } TCHAR *pathList = new TCHAR[pathListBufsz+2]; status = PdhExpandWildCardPath(NULL, counterPath, (PZZTSTR)pathList, &pathListBufsz, 0); if (status != ERROR_SUCCESS) { _Module.LogError("PerfCounter plugin: %s: PdhExpandWildCardPath error=%x", m_Name.c_str(), status); return false; } // read config TString includeRE = A2TConvert(g_Config.GetValue(m_SectionName, "IncludePaths", ".+")); TString excludeRE = A2TConvert(g_Config.GetValue(m_SectionName, "ExcludePaths", "^$")); // create regex matchers CRegexpT <TCHAR> includeRegEx(includeRE.c_str(), IGNORECASE); CRegexpT <TCHAR> excludeRegEx(excludeRE.c_str(), IGNORECASE); HCOUNTER counterHandle; for (; *pathList; pathList += _tcslen(pathList) + 1) { /* anatomy of a PDH path: \\machine\object(instance)\counter * anomalies of a PDH path: the instance name is optional, and * may contain parantheses and/or backslashes * thus, the safest way is to check for the first '(' and the * last '\' to separate the object, counter, instance names */ int backslashes[2] = {0, 0}; int para = 0; int idx; for (idx = 2; pathList[idx]; idx++) { if (pathList[idx] == '\\') { if (backslashes[0]) { backslashes[1] = idx; } else { backslashes[0] = idx; } } else if (pathList[idx] == '(' && (!para) && backslashes[0] && (!backslashes[1])) { para = idx; } } TCHAR *matchPath; // use regex matching either on the original path or the // back-translated constructed path if (useEnglishNames) { DWORD instPos = para ? para : backslashes[1]; TCHAR *oName = new TCHAR[instPos - backslashes[0]]; TCHAR *cName = new TCHAR[idx - backslashes[1] + 1]; TCHAR *iName = new TCHAR[backslashes[1] - para + 1]; // copy the object name wcsncpy(oName, pathList + backslashes[0] + 1, instPos - backslashes[0] - 1); oName[instPos - backslashes[0] - 1] = 0; // copy the counter name (end of complete path, so \0 already exists) wcsncpy(cName, pathList + backslashes[1] + 1, idx - backslashes[1]); cName[idx - backslashes[1]] = 0; // if there's an instance name, copy it, too. if (para) { wcsncpy(iName, pathList + para, backslashes[1] - para); } iName[backslashes[1] - para] = 0; matchPath = new TCHAR[MAX_PATH]; _snwprintf(matchPath, MAX_PATH, _T("\\%s%s\\%s"), GetPdhCounterEnglishName(oName), iName, GetPdhCounterEnglishName(cName)); delete oName; delete cName; delete iName; } else { matchPath = pathList; } // handle includes & excludes if (!includeRegEx.MatchExact(matchPath).IsMatched() || excludeRegEx.MatchExact(matchPath).IsMatched()) { if (useEnglishNames) { delete matchPath; } continue; } if (useEnglishNames) { delete matchPath; } // add the counter status = PdhAddCounter(m_PerfQuery, pathList, 0, &counterHandle); if (status != ERROR_SUCCESS) { _Module.LogError("PerfCounter plugin: %s: PDH add counter error=%x", m_Name.c_str(), status); return false; } // replace the backslash before the counter name with a space pathList[backslashes[1]] = ' '; std::string cn = W2IConvert(pathList + (para ? para : (backslashes[1] + 1))); _Module.LogEvent("PerfCounter plugin: %s: added counter %s", m_Name.c_str(), cn.c_str()); m_Counters.push_back(counterHandle); m_CounterNames.push_back(cn); } // Collect init data status = PdhCollectQueryData(m_PerfQuery); if (status != ERROR_SUCCESS) { if (status == PDH_INVALID_HANDLE) { _Module.LogError("PerfCounter plugin: %s: PDH collect data: PDH_INVALID_HANDLE", m_Name.c_str()); return false; } if (status == PDH_NO_DATA) { _Module.LogError("PerfCounter plugin: %s: PDH collect data: PDH_NO_DATA", m_Name.c_str()); return false; } _Module.LogError("PerfCounter plugin: %s: PDH collect data error", m_Name.c_str()); return false; } // Setup Counter Format m_dwCounterFormat = PDH_FMT_DOUBLE; std::string counterFormatStr = g_Config.GetValue(m_SectionName, "CounterFormat", "double"); if (!counterFormatStr.compare("double") || !counterFormatStr.compare("float")) { m_dwCounterFormat = PDH_FMT_DOUBLE; } else if (!counterFormatStr.compare("int") || !counterFormatStr.compare("long")) { m_dwCounterFormat = PDH_FMT_LONG; } else if (!counterFormatStr.compare("int64") || !counterFormatStr.compare("longlong") || !counterFormatStr.compare("large")) { m_dwCounterFormat = PDH_FMT_LARGE; } else { _Module.LogError("PerfCounter plugin: %s: Unknown CounterFormat", m_Name.c_str()); assert(!"Unknown CounterFormat!"); } m_CounterMultiply = g_Config.GetValueF(m_SectionName, "CounterMultiply", 1.0); return true; }