Changeset ee230f7 in nscp


Ignore:
Timestamp:
08/04/12 07:34:11 (10 months ago)
Author:
Michael Medin <michael@…>
Branches:
master, 0.4.1, 0.4.2
Children:
c91916f
Parents:
6aac723
Message:
  • Hopefully fixed the "cant load counter" issue by reowrking how counters are handled.
Files:
3 deleted
7 edited

Legend:

Unmodified
Added
Removed
  • changelog

    rc1810e3 ree230f7  
    44 * Fix dependonservice LanManWorkStation (old win) 
    55 * Fix RtlStringFromGUID problem on NT4 
     6 
     72012-08-03 MickeM 
     8 * Hopefully fixed the "cant load counter" issue by reowrking how counters are handled. 
    69 
    7102012-08-02 MickeM 
  • modules/CheckSystem/CMakeLists.txt

    rc1810e3 ree230f7  
    4949  ${Boost_FILESYSTEM_LIBRARY} 
    5050  ${Boost_REGEX_LIBRARY} 
     51  ${Boost_THREAD_LIBRARY} 
    5152  ${Boost_PROGRAM_OPTIONS_LIBRARY} 
    5253  ${NSCP_DEF_PLUGIN_LIB} 
  • modules/CheckSystem/CheckSystem.cpp

    r6aac723 ree230f7  
    4747 * @return  
    4848 */ 
    49 CheckSystem::CheckSystem() : pdhThread(_T("pdhThread")) {} 
     49CheckSystem::CheckSystem() {} 
    5050/** 
    5151 * Default d-tor 
     
    6565} 
    6666 
     67boost::tuple<bool,std::wstring> validate_counter(std::wstring counter) { 
     68  std::pair<bool,std::wstring> ret; 
     69  /* 
     70  std::wstring error; 
     71  if (!PDH::PDHResolver::validate(counter, error, false)) { 
     72    NSC_DEBUG_MSG(_T("not found (but due to bugs in pdh this is common): ") + error); 
     73  } 
     74  */ 
     75 
     76  typedef boost::shared_ptr<PDH::PDHCounter> counter_ptr; 
     77  counter_ptr pCounter; 
     78  PDH::PDHQuery pdh; 
     79  typedef PDHCollectors::StaticPDHCounterListener<double, PDH_FMT_DOUBLE> counter_type; 
     80  boost::shared_ptr<counter_type> collector(new counter_type()); 
     81  try { 
     82    pdh.addCounter(counter, collector); 
     83    pdh.open(); 
     84    pdh.gatherData(); 
     85    pdh.close(); 
     86    return boost::make_tuple(true, _T("ok(") + strEx::itos(collector->getValue()) + _T(")")); 
     87  } catch (const PDH::PDHException e) { 
     88    try { 
     89      pdh.gatherData(); 
     90      pdh.close(); 
     91      return boost::make_tuple(true, _T("ok-rate(") + strEx::itos(collector->getValue()) + _T(")")); 
     92    } catch (const PDH::PDHException e) { 
     93      return boost::make_tuple(false, _T("query failed: ") + e.getError()); 
     94    } 
     95  } 
     96} 
     97std::wstring find_system_counter(std::wstring counter) { 
     98  if (counter == PDH_SYSTEM_KEY_UPT) { 
     99    wchar_t *keys[] = {_T("\\2\\674"), _T("\\System\\System Up Time"), _T("\\System\\Systembetriebszeit"), _T("\\Sistema\\Tempo di funzionamento sistema"), _T("\\Système\\Temps d'activité système")}; 
     100    BOOST_FOREACH(const wchar_t *key, keys) { 
     101      boost::tuple<bool,std::wstring> result = validate_counter(key); 
     102      if (result.get<0>()) { 
     103        NSC_DEBUG_MSG(_T("Found alternate key for ") + counter + _T(": ") + key); 
     104        return key; 
     105      } 
     106    } 
     107    return keys[0]; 
     108  } 
     109  if (counter == PDH_SYSTEM_KEY_MCL) { 
     110    wchar_t *keys[] = {_T("\\4\\30"), _T("\\Memory\\Commit Limit"), _T("\\Speicher\\Zusagegrenze"), _T("\\Memoria\\Limite memoria vincolata"), _T("\\Mémoire\\Limite de mémoire dédiée")}; 
     111    BOOST_FOREACH(const wchar_t *key, keys) { 
     112      boost::tuple<bool,std::wstring> result = validate_counter(key); 
     113      if (result.get<0>()) { 
     114        NSC_DEBUG_MSG(_T("Found alternate key for ") + counter + _T(": ") + key); 
     115        return key; 
     116      } 
     117    } 
     118    return keys[0]; 
     119  } 
     120  if (counter == PDH_SYSTEM_KEY_MCB) { 
     121    wchar_t *keys[] = {_T("\\4\\26"), _T("\\Memory\\Committed Bytes"), _T("\\Speicher\\Zugesicherte Bytes"), _T("\\Memoria\\Byte vincolati"), _T("\\Mémoire\\Octets dédiés")}; 
     122    BOOST_FOREACH(const wchar_t *key, keys) { 
     123      boost::tuple<bool,std::wstring> result = validate_counter(key); 
     124      if (result.get<0>()) { 
     125        NSC_DEBUG_MSG(_T("Found alternate key for ") + counter + _T(": ") + key); 
     126        return key; 
     127      } 
     128    } 
     129    return keys[0]; 
     130  } 
     131  if (counter == PDH_SYSTEM_KEY_CPU) { 
     132    wchar_t *keys[] = {_T("\\238(_total)\\6"), _T("\\Processor(_total)\\% Processor Time"), _T("\\Prozessor(_Total)\\Prozessorzeit (%)"), _T("\\Processore(_total)\\% Tempo processore"), _T("\\Processeur(_Total)\\% Temps processeur")}; 
     133    BOOST_FOREACH(const wchar_t *key, keys) { 
     134      boost::tuple<bool,std::wstring> result = validate_counter(key); 
     135      if (result.get<0>()) { 
     136        NSC_DEBUG_MSG(_T("Found alternate key for ") + counter + _T(": ") + key); 
     137        return key; 
     138      } 
     139    } 
     140    return keys[0]; 
     141  } 
     142} 
     143 
     144 
     145void load_counters(std::map<std::wstring,std::wstring> &counters, sh::settings_registry &settings) { 
     146  settings.alias().add_path_to_settings() 
     147    (_T("pdh/counters"), sh::wstring_map_path(&counters) 
     148    , _T("PDH COUNTERS"), _T("Define various PDH counters to check.")) 
     149    ; 
     150 
     151  settings.register_all(); 
     152  settings.notify(); 
     153  settings.clear(); 
     154 
     155  std::wstring path = settings.alias().get_settings_path(_T("pdh/counters")); 
     156  if (counters[PDH_SYSTEM_KEY_CPU] == _T("")) { 
     157    settings.register_key(path + _T("/") + PDH_SYSTEM_KEY_CPU, _T("collection strategy"), NSCAPI::key_string, _T("Collection Strategy"), _T("Collection strategy for CPP is usually round robin."), _T("round robin"), false); 
     158  } 
     159  wchar_t *keys[] = {PDH_SYSTEM_KEY_UPT, PDH_SYSTEM_KEY_MCL, PDH_SYSTEM_KEY_MCB, PDH_SYSTEM_KEY_CPU}; 
     160  BOOST_FOREACH(const wchar_t *key, keys) { 
     161    if (counters[key] == _T("")) { 
     162      counters[key] = find_system_counter(key); 
     163      settings.register_key(path, key, NSCAPI::key_string, key, _T("System counter for check_xx commands.."), counters[key], false); 
     164    } 
     165  } 
     166} 
     167 
    67168/** 
    68169 * New version of the load call. 
     
    70171 * @return true 
    71172 */ 
    72  
    73 bool missing_system_counters(std::map<std::wstring,std::wstring> &counters)  
    74 { 
    75   wchar_t *keys[] = {PDH_SYSTEM_KEY_UPT, PDH_SYSTEM_KEY_MCL, PDH_SYSTEM_KEY_MCB, PDH_SYSTEM_KEY_CPU}; 
    76   BOOST_FOREACH(const wchar_t *cnt, keys) { 
    77     if (counters.find(cnt) == counters.end()) 
    78       return true; 
    79   } 
    80   return false; 
    81 } 
    82  
    83 void load_counters(std::map<std::wstring,std::wstring> &counters, sh::settings_registry &settings) { 
    84   settings.alias().add_path_to_settings() 
    85     (_T("pdh/counters"), sh::wstring_map_path(&counters) 
    86     , _T("PDH COUNTERS"), _T("Define various PDH counters to check.")) 
    87     ; 
    88  
    89   settings.register_all(); 
    90   settings.notify(); 
    91   settings.clear(); 
    92  
    93   std::wstring path = settings.alias().get_settings_path(_T("pdh/counters")); 
    94   if (counters[PDH_SYSTEM_KEY_UPT] == _T("")) { 
    95     counters[PDH_SYSTEM_KEY_UPT] = _T("\\2\\674"); 
    96     settings.register_key(path, PDH_SYSTEM_KEY_UPT, NSCAPI::key_string, _T("UPTIME"), _T("PDH Key for system uptime."), _T("\\2\\674"), false); 
    97   } 
    98   if (counters[PDH_SYSTEM_KEY_MCL] == _T("")) { 
    99     counters[PDH_SYSTEM_KEY_MCL] = _T("\\4\\30"); 
    100     settings.register_key(path, PDH_SYSTEM_KEY_MCL, NSCAPI::key_string, _T("Commit limit"), _T("PDH key for memory commit limit"), _T("\\4\\30"), false); 
    101   } 
    102   if (counters[PDH_SYSTEM_KEY_MCB] == _T("")) { 
    103     counters[PDH_SYSTEM_KEY_MCB] = _T("\\4\\26"); 
    104     settings.register_key(path, PDH_SYSTEM_KEY_MCB, NSCAPI::key_string, _T("Commit bytes"), _T("PDH Key for system CPU load."), _T("\\4\\26"), false); 
    105   } 
    106   if (counters[PDH_SYSTEM_KEY_CPU] == _T("")) { 
    107     counters[PDH_SYSTEM_KEY_CPU] = _T("\\238(_total)\\6"); 
    108     settings.register_key(path, PDH_SYSTEM_KEY_CPU, NSCAPI::key_string, _T("CPU Load"), _T("PDH Key for system CPU load."), _T("\\238(_total)\\6"), false); 
    109     settings.register_key(path + _T("/") + PDH_SYSTEM_KEY_CPU, _T("collection strategy"), NSCAPI::key_string, _T("Collection Strategy"), _T("Collection strategy for CPP is usually round robin."), _T("round robin"), false); 
    110   } 
    111 } 
    112173bool CheckSystem::loadModuleEx(std::wstring alias, NSCAPI::moduleLoadMode mode) { 
    113   PDHCollector::system_counter_data *data = new PDHCollector::system_counter_data; 
     174  boost::shared_ptr<PDHCollector::system_counter_data> data(new PDHCollector::system_counter_data); 
    114175  data->check_intervall = 1; 
    115176  try { 
     
    117178    settings.set_alias(_T("check"), alias, _T("system/windows")); 
    118179 
    119     load_counters(counters, settings); 
     180    if (mode == NSCAPI::normalStart) { 
     181      load_counters(counters, settings); 
     182    } 
    120183 
    121184    settings.alias().add_path_to_settings() 
     
    135198      _T("DEFAULT INTERVALL"), _T("Used to define the default intervall for range buffer checks (ie. CPU)."), true) 
    136199 
     200      (_T("subsystem"), sh::wstring_key(&data->subsystem, _T("default")), 
     201      _T("PDH SUBSYSTEM"), _T("Set which pdh subsystem to use."), true) 
     202       
    137203      ; 
    138204 
     
    163229 
    164230     
    165     typedef PDHCollector::system_counter_data::counter cnt; 
    166     /* 
    167     if (default_counters) { 
    168       data->counters.push_back(cnt(PDH_SYSTEM_KEY_MCL, _T("\\4\\30"), cnt::type_int64, cnt::format_large, cnt::value)); 
    169       data->counters.push_back(cnt(PDH_SYSTEM_KEY_CPU, _T("\\238(_total)\\6"), cnt::type_int64, cnt::format_large, cnt::rrd)); 
    170       data->counters.push_back(cnt(PDH_SYSTEM_KEY_MCB, _T("\\4\\26"), cnt::type_int64, cnt::format_large, cnt::value)); 
    171       data->counters.push_back(cnt(PDH_SYSTEM_KEY_UPT, _T("\\2\\674"), cnt::type_int64, cnt::format_large, cnt::value)); 
    172     } 
    173     */ 
    174     BOOST_FOREACH(counter_map_type::value_type c, counters) { 
    175       data->counters.push_back(cnt(c.first, c.second, cnt::type_int64, cnt::format_large, cnt::value)); 
     231    if (mode == NSCAPI::normalStart) { 
     232      typedef PDHCollector::system_counter_data::counter cnt; 
     233      BOOST_FOREACH(counter_map_type::value_type c, counters) { 
     234        std::wstring path = c.second; 
     235        boost::tuple<bool, std::wstring> result = validate_counter(path); 
     236        if (!result.get<0>()) { 
     237          NSC_LOG_ERROR(_T("Failed to load counter ") + c.first + _T("(") + path + _T(": ") + result.get<1>()); 
     238        } 
     239        // TODO: parse coolection strategy here! 
     240        data->counters.push_back(cnt(c.first, path, cnt::type_int64, cnt::format_large, cnt::value)); 
     241      } 
    176242    } 
    177243 
     
    205271 
    206272  if (mode == NSCAPI::normalStart) { 
    207     pdhThread.createThread(data); 
     273    pdh_collector.start(data); 
    208274  } 
    209275 
     
    216282 */ 
    217283bool CheckSystem::unloadModule() { 
    218   if (!pdhThread.exitThread(20000)) { 
    219     std::wcout << _T("MAJOR ERROR: Could not unload thread...") << std::endl; 
     284  if (!pdh_collector.stop()) { 
    220285    NSC_LOG_ERROR(_T("Could not exit the thread, memory leak and potential corruption may be the result...")); 
    221286  } 
     
    235300bool CheckSystem::hasMessageHandler() { 
    236301  return false; 
    237 } 
    238  
    239 std::wstring validate_counter(std::wstring counter) { 
    240   std::wstring error; 
    241   if (!PDH::PDHResolver::validate(counter, error, false)) { 
    242     NSC_LOG_ERROR_STD(_T("not found: ") + error); 
    243   } 
    244  
    245   typedef boost::shared_ptr<PDH::PDHCounter> counter_ptr; 
    246   counter_ptr pCounter; 
    247   PDH::PDHQuery pdh; 
    248   typedef PDHCollectors::StaticPDHCounterListener<double, PDH_FMT_DOUBLE> counter_type; 
    249   boost::shared_ptr<counter_type> collector(new counter_type()); 
    250   try { 
    251     pdh.addCounter(counter, collector); 
    252     pdh.open(); 
    253     pdh.gatherData(); 
    254     pdh.close(); 
    255     return _T("ok(") + strEx::itos(collector->getValue()) + _T(")"); 
    256   } catch (const PDH::PDHException e) { 
    257     try { 
    258       pdh.gatherData(); 
    259       pdh.close(); 
    260       return _T("ok-rate(") + strEx::itos(collector->getValue()) + _T(")"); 
    261     } catch (const PDH::PDHException e) { 
    262       return _T("query failed: ") + e.getError(); 
    263     } 
    264   } 
    265302} 
    266303 
     
    334371                  if (!counter.empty() && line.find(counter) == std::wstring::npos) 
    335372                    continue; 
    336                   std::wstring status; 
     373                  boost::tuple<bool,std::wstring> status; 
    337374                  if (validate) 
    338375                    status = validate_counter(line); 
    339376                  if (porcelain)  
    340                     line = _T("counter,") + obj.name + _T(",") + inst.name + _T(",") + count.name + _T(", ") + status; 
     377                    line = _T("counter,") + obj.name + _T(",") + inst.name + _T(",") + count.name + _T(", ") + status.get<1>(); 
    341378                  else if (validate) 
    342                     line = line + _T(": ") + status; 
     379                    line = line + _T(": ") + status.get<1>(); 
    343380                  result += line + _T("\n"); 
    344381                  match++; 
     
    351388                if (!counter.empty() && line.find(counter) == std::wstring::npos) 
    352389                  continue; 
    353                 std::wstring status; 
     390                boost::tuple<bool,std::wstring> status; 
    354391                if (validate) 
    355392                  status = validate_counter(line); 
    356393 
    357394                if (porcelain)  
    358                   line = _T("counter,") + obj.name + _T(",,") + _T(",") + count.name  + _T(", ") + status; 
     395                  line = _T("counter,") + obj.name + _T(",,") + _T(",") + count.name  + _T(", ") + status.get<1>(); 
    359396                else if (validate) 
    360                   line = line + _T(": ") + status; 
     397                  line = line + _T(": ") + status.get<1>(); 
    361398                result += line + _T("\n"); 
    362399                match++; 
     
    386423        BOOST_FOREACH(const counter_map_type::value_type v, counters) { 
    387424          std::wstring line = v.first + _T(" = ") + v.second; 
    388           std::wstring status; 
     425          boost::tuple<bool,std::wstring> status; 
    389426          count++; 
    390427          if (!counter.empty() && line.find(counter) == std::wstring::npos) 
     
    395432 
    396433          if (porcelain)  
    397             line = v.first + _T(",") + v.second + _T(",") + status; 
     434            line = v.first + _T(",") + v.second + _T(",") + status.get<1>(); 
    398435          else if (validate) 
    399             line = v.first + _T(" = ") + v.second + _T(": ") + status; 
     436            line = v.first + _T(" = ") + v.second + _T(": ") + status.get<1>(); 
    400437          else  
    401438            line = v.first + _T(" = ") + v.second; 
     
    470507 */ 
    471508NSCAPI::nagiosReturn CheckSystem::handleCommand(const std::wstring &target, const std::wstring &command, std::list<std::wstring> &arguments, std::wstring &message, std::wstring &perf) { 
    472   CheckSystem::returnBundle rb; 
    473509  if (command == _T("checkcpu")) { 
    474510    return checkCPU(arguments, message, perf); 
     
    560596  for (std::list<CPULoadContainer>::const_iterator it = list.begin(); it != list.end(); ++it) { 
    561597    CPULoadContainer load = (*it); 
    562     PDHCollector *pObject = pdhThread.getThread(); 
    563     if (!pObject) { 
    564       msg = _T("ERROR: PDH Collection thread not running."); 
    565       return NSCAPI::returnUNKNOWN; 
    566     } 
    567     int value = pObject->getCPUAvrage(load.data + _T("m")); 
     598    int value = pdh_collector.getCPUAvrage(load.data + _T("m")); 
    568599    if (value == -1) { 
    569600      msg = _T("ERROR: Could not get data for ") + load.getAlias() + _T(" perhaps we don't collect data this far back?"); 
     
    614645 
    615646 
    616   PDHCollector *pObject = pdhThread.getThread(); 
    617   if (!pObject) { 
    618     msg = _T("ERROR: PDH Collection thread not running."); 
    619     return NSCAPI::returnUNKNOWN; 
    620   } 
    621   unsigned long long value = pObject->getUptime(); 
     647  unsigned long long value = pdh_collector.getUptime(); 
    622648  if (value == -1) { 
    623649    msg = _T("ERROR: Could not get value"); 
     
    863889    if (firstPaged && (check.data == _T("paged"))) { 
    864890      firstPaged = false; 
    865       PDHCollector *pObject = pdhThread.getThread(); 
    866       if (!pObject) { 
    867         msg = _T("ERROR: PDH Collection thread not running."); 
    868         return NSCAPI::returnUNKNOWN; 
    869       } 
    870       dataPaged.value = pObject->getMemCommit(); 
     891      dataPaged.value = pdh_collector.getMemCommit(); 
    871892      if (dataPaged.value == -1) { 
    872893        msg = _T("ERROR: Failed to get PDH value."); 
    873894        return NSCAPI::returnUNKNOWN; 
    874895      } 
    875       dataPaged.total = pObject->getMemCommitLimit(); 
     896      dataPaged.total = pdh_collector.getMemCommitLimit(); 
    876897      if (dataPaged.total == -1) { 
    877898        msg = _T("ERROR: Failed to get PDH value."); 
     
    14091430      double value = 0; 
    14101431      if (counter.data.find('\\') == std::wstring::npos) { 
    1411         PDHCollector *pObject = pdhThread.getThread(); 
    1412         if (!pObject) { 
    1413           msg = _T("ERROR: PDH Collection thread not running."); 
    1414           return NSCAPI::returnUNKNOWN; 
    1415         } 
    1416         value = pObject->get_double(counter.data); 
     1432        value = pdh_collector.get_double(counter.data); 
    14171433        if (value == -1) { 
    14181434          msg = _T("ERROR: Failed to get counter value: ") + counter.data; 
  • modules/CheckSystem/CheckSystem.h

    rc1810e3 ree230f7  
    3131private: 
    3232  CheckMemory memoryChecker; 
    33   PDHCollectorThread pdhThread; 
     33  PDHCollector pdh_collector; 
    3434 
    3535  typedef std::map<std::wstring,std::wstring> counter_map_type; 
     
    3737 
    3838public: 
     39  /* 
    3940  typedef enum { started, stopped } states; 
    4041  typedef struct rB { 
     
    4546    rB() : code_(NSCAPI::returnUNKNOWN) {} 
    4647  } returnBundle; 
    47  
     48*/ 
    4849  std::map<DWORD,std::wstring> lookups_; 
    4950 
     
    9192  NSCAPI::nagiosReturn checkSingleRegEntry(std::list<std::wstring> arguments, std::wstring &message, std::wstring &perf); 
    9293 
    93  
    9494}; 
  • modules/CheckSystem/PDHCollector.cpp

    rd6c3131 ree230f7  
    2323#include "settings.hpp" 
    2424 
    25 PDHCollector::PDHCollector() : hStopEvent_(NULL)/*, data_(NULL)*/ { 
    26   std::wstring subsystem = SETTINGS_GET_STRING(check_system::PDH_SUBSYSTEM); 
    27   if (subsystem == setting_keys::check_system::PDH_SUBSYSTEM_FAST) { 
    28   } else if (subsystem == setting_keys::check_system::PDH_SUBSYSTEM_THREAD_SAFE) { 
    29     PDH::PDHFactory::set_threadSafe(); 
    30   } else { 
    31     NSC_LOG_ERROR_STD(_T("Unknown PDH subsystem (") + subsystem + _T(") valid values are: fast and thread-safe")); 
    32   } 
     25PDHCollector::PDHCollector() : stop_event_(NULL) { 
    3326} 
    3427 
    3528PDHCollector::~PDHCollector() 
    3629{ 
    37   if (hStopEvent_) 
    38     CloseHandle(hStopEvent_); 
    39 //  delete data_; 
     30  if (stop_event_ != NULL) 
     31    CloseHandle(stop_event_); 
    4032} 
    4133 
     
    6759* 
    6860*/ 
    69 DWORD PDHCollector::threadProc(LPVOID lpParameter) { 
    70   hStopEvent_ = CreateEvent(NULL, TRUE, FALSE, NULL); 
    71   if (!hStopEvent_) { 
    72     NSC_LOG_ERROR_STD(_T("Create StopEvent failed: ") + error::lookup::last_error()); 
    73     return 0; 
    74   } 
    75  
    76   system_counter_data *data = reinterpret_cast<system_counter_data*>(lpParameter); 
    77  
    78   check_intervall_ = data->check_intervall; 
    79   std::wstring default_buffer_length = data->buffer_length; 
     61void PDHCollector::thread_proc() { 
     62 
     63  if (!thread_data_) { 
     64    NSC_LOG_ERROR_STD(_T("No configuration for PDH thread: Exiting")); 
     65    return; 
     66 
     67  } 
     68  if (thread_data_->subsystem == _T("fast") || thread_data_->subsystem == _T("auto")) { 
     69  } else if (thread_data_->subsystem == _T("thread-safe")) { 
     70    PDH::PDHFactory::set_threadSafe(); 
     71  } else { 
     72    NSC_LOG_ERROR_STD(_T("Unknown PDH subsystem (") + thread_data_->subsystem + _T(") valid values are: fast (auto) and thread-safe")); 
     73  } 
     74 
     75  check_intervall_ = thread_data_->check_intervall; 
     76  std::wstring default_buffer_length = thread_data_->buffer_length; 
    8077  PDH::PDHQuery pdh; 
    81   bool bInit = true; 
     78 
     79  if (thread_data_->counters.empty()) { 
     80    NSC_LOG_ERROR_STD(_T("No counters configure in PDH thread.")); 
     81    return; 
     82  } 
    8283 
    8384  { 
    8485    SetThreadLocale(MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT)); 
    85     WriteLock lock(&mutex_, true, 5000); 
    86     if (!lock.IsLocked()) { 
    87       NSC_LOG_ERROR_STD(_T("Failed to get mutex when trying to start thread... thread will now die...")); 
    88       bInit = false; 
    89     } else { 
    90       pdh.removeAllCounters(); 
    91       NSC_DEBUG_MSG_STD(_T("Loading counters...")); 
    92       BOOST_FOREACH(system_counter_data::counter c, data->counters) { 
     86    boost::unique_lock<boost::shared_mutex> writeLock(mutex_, boost::get_system_time() + boost::posix_time::seconds(10)); 
     87    if (!writeLock.owns_lock()) { 
     88      NSC_LOG_ERROR_STD(_T("Failed to get mutex when trying to start thread.")); 
     89      return; 
     90    } 
     91    pdh.removeAllCounters(); 
     92    BOOST_FOREACH(system_counter_data::counter c, thread_data_->counters) { 
     93      try { 
     94        NSC_DEBUG_MSG_STD(_T("Loading counter: ") + c.alias + _T(" = ") + c.path); 
     95        c.set_default_buffer_size(default_buffer_length); 
     96        collector_ptr collector = c.create(check_intervall_); 
     97        if (collector) { 
     98          counters_[c.alias] = collector; 
     99          pdh.addCounter(c.path, collector); 
     100        } else { 
     101          NSC_LOG_ERROR_STD(_T("Failed to load counter: ") + c.alias + _T(" = ") + c.path); 
     102        } 
     103      } catch (...) { 
     104        NSC_LOG_ERROR_STD(_T("EXCEPTION: Failed to load counter: ") + c.alias + _T(" = ") + c.path); 
     105      } 
     106    } 
     107    try { 
     108      pdh.open(); 
     109    } catch (const PDH::PDHException &e) { 
     110      NSC_LOG_ERROR_STD(_T("Failed to open performance counters: ") + e.getError()); 
     111      return; 
     112    } 
     113  } 
     114 
     115  DWORD waitStatus = 0; 
     116  bool first = true; 
     117  do { 
     118    std::list<std::wstring> errors; 
     119    { 
     120      boost::unique_lock<boost::shared_mutex> writeLock(mutex_, boost::get_system_time() + boost::posix_time::seconds(5)); 
     121      if (!writeLock.owns_lock()) { 
     122        NSC_LOG_ERROR(_T("Failed to get Mutex!")); 
     123      } else { 
    93124        try { 
    94           NSC_DEBUG_MSG_STD(_T("Loading counter: ") + c.alias + _T(" = ") + c.path); 
    95  
    96           c.set_default_buffer_size(default_buffer_length); 
    97           collector_ptr collector = c.create(check_intervall_); 
    98           if (collector) { 
    99             counters_[c.alias] = collector; 
    100             PDH::PDHQuery::counter_ptr counter = pdh.addCounter(c.path, collector); 
    101             PDH::PDHError status = counter->validate(); 
    102             if (status.is_error()) { 
    103               NSC_DEBUG_MSG_STD(_T("Counter status: ") + status.to_wstring()); 
    104             } 
     125          pdh.gatherData(); 
     126        } catch (const PDH::PDHException &e) { 
     127          if (first) {  // If this is the first run an error will be thrown since the data is not yet available 
     128            // This is "ok" but perhaps another solution would be better, but this works :) 
     129            first = false; 
    105130          } else { 
    106             NSC_LOG_ERROR_STD(_T("Failed to load counter: ") + c.alias + _T(" = ") + c.path); 
     131            errors.push_back(_T("Failed to query performance counters: ") + e.getError()); 
    107132          } 
    108133        } catch (...) { 
    109           NSC_LOG_ERROR_STD(_T("EXCEPTION: Failed to load counter: ") + c.alias + _T(" = ") + c.path); 
     134          errors.push_back(_T("Failed to query performance counters: ")); 
    110135        } 
    111       } 
    112       try { 
    113         pdh.open(); 
    114       } catch (const PDH::PDHException &e) { 
    115         NSC_LOG_ERROR_STD(_T("Failed to open performance counters: ") + e.getError()); 
    116         bInit = false; 
    117       } 
    118     } 
    119   } 
    120   data = NULL; 
    121   delete data; 
    122  
    123   DWORD waitStatus = 0; 
    124   if (bInit) { 
    125     bool first = true; 
    126     do { 
    127       std::list<std::wstring> errors; 
    128       { 
    129         ReadLock lock(&mutex_, true, 5000); 
    130         if (!lock.IsLocked()) { 
    131           NSC_LOG_ERROR(_T("Failed to get Mutex!")); 
    132         } else { 
    133           try { 
    134             pdh.gatherData(); 
    135           } catch (const PDH::PDHException &e) { 
    136             if (first) {  // If this is the first run an error will be thrown since the data is not yet available 
    137               // This is "ok" but perhaps another solution would be better, but this works :) 
    138               first = false; 
    139             } else { 
    140               errors.push_back(_T("Failed to query performance counters: ") + e.getError()); 
    141             } 
    142           } catch (...) { 
    143             errors.push_back(_T("Failed to query performance counters: ")); 
    144           } 
    145         }  
    146       } 
    147       for (std::list<std::wstring>::const_iterator cit = errors.begin(); cit != errors.end(); ++cit) { 
    148         NSC_LOG_ERROR_STD(*cit); 
    149       } 
    150     } while (((waitStatus = WaitForSingleObject(hStopEvent_, check_intervall_*100)) == WAIT_TIMEOUT)); 
    151   } else { 
    152     NSC_LOG_ERROR_STD(_T("No performance counters were found we will not wait for the end instead...")); 
    153     waitStatus = WaitForSingleObject(hStopEvent_, INFINITE); 
    154   } 
     136      }  
     137    } 
     138    for (std::list<std::wstring>::const_iterator cit = errors.begin(); cit != errors.end(); ++cit) { 
     139      NSC_LOG_ERROR_STD(*cit); 
     140    } 
     141  } while (((waitStatus = WaitForSingleObject(stop_event_, check_intervall_*100)) == WAIT_TIMEOUT)); 
    155142  if (waitStatus != WAIT_OBJECT_0) { 
    156143    NSC_LOG_ERROR(_T("Something odd happened when terminating PDH collection thread!")); 
     144    return; 
    157145  } 
    158146 
    159147  { 
    160     WriteLock lock(&mutex_, true, 5000); 
    161     if (!lock.IsLocked()) { 
     148    boost::unique_lock<boost::shared_mutex> writeLock(mutex_, boost::get_system_time() + boost::posix_time::seconds(5)); 
     149    if (!writeLock.owns_lock()) { 
    162150      NSC_LOG_ERROR(_T("Failed to get Mute when closing thread!")); 
    163151    } 
    164  
    165     if (!CloseHandle(hStopEvent_)) { 
    166       NSC_LOG_ERROR_STD(_T("Failed to close stopEvent handle: ") + error::lookup::last_error()); 
    167     } else 
    168       hStopEvent_ = NULL; 
    169152    try { 
    170153      pdh.close(); 
     
    173156    } 
    174157  } 
    175   return 0; 
    176158} 
    177159 
    178160__int64 PDHCollector::get_int_value(std::wstring counter) { 
    179   ReadLock lock(&mutex_, true, 5000); 
    180   if (!lock.IsLocked()) { 
     161  boost::shared_lock<boost::shared_mutex> readLock(mutex_, boost::get_system_time() + boost::posix_time::seconds(5)); 
     162  if (!readLock.owns_lock()) { 
    181163    NSC_LOG_ERROR(_T("Failed to get Mutex for: ") + counter); 
    182164    return 0; 
     
    191173 
    192174double PDHCollector::get_avg_value(std::wstring counter, unsigned int delta) { 
    193   ReadLock lock(&mutex_, true, 5000); 
    194   if (!lock.IsLocked()) { 
     175  boost::shared_lock<boost::shared_mutex> readLock(mutex_, boost::get_system_time() + boost::posix_time::seconds(5)); 
     176  if (!readLock.owns_lock()) { 
    195177    NSC_LOG_ERROR(_T("Failed to get Mutex for: ") + counter); 
    196178    return 0; 
     
    206188 
    207189/** 
    208 * Request termination of the thread (waiting for thread termination is not handled) 
    209 */ 
    210 void PDHCollector::exitThread(void) { 
    211   if (hStopEvent_ == NULL) { 
    212     NSC_LOG_ERROR(_T("Stop event is not created!")); 
    213   } else if (!SetEvent(hStopEvent_)) { 
    214       NSC_LOG_ERROR_STD(_T("SetStopEvent failed")); 
    215   } 
    216 } 
    217 /** 
    218190* Get the average CPU usage for "time" 
    219191* @param time Time to check  
     
    223195  int frequency; 
    224196  { 
    225     ReadLock lock(&mutex_, true, 5000); 
    226     if (!lock.IsLocked()) { 
     197    boost::shared_lock<boost::shared_mutex> readLock(mutex_, boost::get_system_time() + boost::posix_time::seconds(5)); 
     198    if (!readLock.owns_lock()) { 
    227199      NSC_LOG_ERROR(_T("Failed to get Mutex!")); 
    228200      return -1; 
     
    292264 
    293265double PDHCollector::get_double(std::wstring counter) { 
    294   ReadLock lock(&mutex_, true, 5000); 
    295   if (!lock.IsLocked()) { 
     266  boost::shared_lock<boost::shared_mutex> readLock(mutex_, boost::get_system_time() + boost::posix_time::seconds(5)); 
     267  if (!readLock.owns_lock()) { 
    296268    NSC_LOG_ERROR(_T("Failed to get Mutex!")); 
    297269    return -1; 
     
    312284  } 
    313285} 
     286 
     287void PDHCollector::start(boost::shared_ptr<system_counter_data> data) 
     288{ 
     289  if (thread_) 
     290    return; 
     291  thread_data_ = data; 
     292  stop_event_ = CreateEvent(NULL, TRUE, FALSE, _T("PDHCollectorShutdown")); 
     293  thread_ = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&PDHCollector::thread_proc, this))); 
     294} 
     295 
     296bool PDHCollector::stop() 
     297{ 
     298  SetEvent(stop_event_); 
     299  if (thread_) 
     300    return thread_->timed_join(boost::posix_time::seconds(5)); 
     301  return true; 
     302} 
  • modules/CheckSystem/PDHCollector.h

    rc391984 ree230f7  
    2121#pragma once 
    2222 
     23#include <boost/thread.hpp> 
     24 
    2325#include <pdh.hpp> 
    24 #include <thread.h> 
    25 #include <MutexRW.h> 
    2626#include <boost/unordered_map.hpp> 
    2727#include <boost/shared_ptr.hpp> 
     
    105105    unsigned int check_intervall; 
    106106    std::wstring buffer_length; 
     107    std::wstring subsystem; 
    107108 
    108109    std::list<counter> counters; 
     
    111112private: 
    112113 
    113   //system_counter_data *data_; 
    114   MutexRW mutex_; 
    115   HANDLE hStopEvent_; 
     114  boost::shared_mutex mutex_; 
     115  HANDLE stop_event_; 
    116116  typedef boost::shared_ptr<PDHCollectors::PDHCollector> collector_ptr; 
    117117  typedef boost::unordered_map<std::wstring,collector_ptr > counter_map; 
    118118  counter_map counters_; 
    119119  int check_intervall_; 
     120  boost::shared_ptr<boost::thread> thread_; 
     121  boost::shared_ptr<system_counter_data> thread_data_; 
    120122 
    121123public: 
    122124  PDHCollector(); 
    123125  virtual ~PDHCollector(); 
    124   DWORD threadProc(LPVOID lpParameter); 
     126  void thread_proc(); 
    125127  void exitThread(void); 
    126128 
     
    135137  double get_avg_value(std::wstring counter, unsigned int delta); 
    136138  double get_double(std::wstring counter); 
     139  void start(boost::shared_ptr<system_counter_data> data); 
     140  bool stop(); 
    137141}; 
    138  
    139  
    140 typedef Thread<PDHCollector> PDHCollectorThread; 
  • version.txt

    r6aac723 ree230f7  
    11version=0.4.1 
    2 build=27 
     2build=28 
    33date=2012-08-03 
Note: See TracChangeset for help on using the changeset viewer.