Changeset 48b6b97 in nscp


Ignore:
Timestamp:
08/06/12 08:12:58 (10 months ago)
Author:
Michael Medin <michael@…>
Branches:
master, 0.4.1, 0.4.2
Children:
fff754b
Parents:
24f6e3f
Message:
  • Re implemented INSTANCES command via the new pdh exec subsystem. Still has an unfixed isue as it return duplicates (one for each counter on the object) which will be fixed later today.
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • changelog

    r24f6e3f r48b6b97  
    44 * Fix dependonservice LanManWorkStation (old win) 
    55 * Fix RtlStringFromGUID problem on NT4 
     6 
     72012-08-04 MickeM 
     8 * Re implemented INSTANCES command via the new pdh exec subsystem. 
     9   Still has an unfixed isue as it return duplicates (one for each counter on the object) which will be fixed later today. 
    610 
    7112012-08-04 MickeM 
  • include/pdh/enumerations.hpp

    r523576e r48b6b97  
    3232  class Enumerations { 
    3333  public: 
    34  
    35     struct Counter { 
    36       std::wstring name; 
    37     }; 
    38     typedef std::list<Counter> Counters; 
    39     struct Instance { 
    40       std::wstring name; 
    41     }; 
    42     typedef std::list<Instance> Instances; 
    4334    struct Object { 
    4435      std::wstring name; 
    4536      std::string error; 
    46       Instances instances; 
    47       Counters counters; 
     37      std::list<std::wstring> instances; 
     38      std::list<std::wstring> counters; 
    4839    }; 
    4940 
     
    9384              cp=szCounterBuffer; 
    9485              while(*cp != '\0') { 
    95                 Counter c; 
    96                 c.name = cp; 
    97                 o.counters.push_back(c); 
     86                o.counters.push_back(cp); 
    9887                cp += lstrlen(cp)+1; 
    9988              } 
     
    10291              cp=szInstanceBuffer; 
    10392              while(*cp != '\0') { 
    104                 Instance i; 
    105                 i.name = cp; 
    106                 o.instances.push_back(i); 
     93                o.counters.push_back(cp); 
    10794                cp += lstrlen(cp)+1; 
    10895              } 
     
    120107    } 
    121108 
    122     struct pdh_object_details { 
    123       typedef std::list<std::wstring> list; 
    124       list counters; 
    125       list instances; 
    126     }; 
    127     static pdh_object_details EnumObjectInstances(std::wstring object, DWORD wanted_counter_len = PDH_INDEX_BUF_LEN, DWORD wanted_instance_len = PDH_INDEX_BUF_LEN) { 
    128       DWORD counter_len = wanted_counter_len; 
    129       DWORD instance_len = wanted_instance_len; 
    130       TCHAR *counter_buffer = new TCHAR[counter_len+1]; 
    131       TCHAR *instance_buffer = new TCHAR[instance_len+1]; 
    132       PDH::PDHError status = PDH::PDHFactory::get_impl()->PdhEnumObjectItems(NULL, NULL, object.c_str(), counter_buffer, &counter_len, instance_buffer, &instance_len, PERF_DETAIL_WIZARD, 0); 
    133       if (status.is_error()) { 
    134         delete [] counter_buffer; 
    135         delete [] instance_buffer; 
    136         if (status.is_more_data() && wanted_counter_len == PDH_INDEX_BUF_LEN && wanted_instance_len == PDH_INDEX_BUF_LEN) 
    137           return EnumObjectInstances(object, counter_len+10, instance_len+10); 
    138         throw PDHException(_T("RESOLVER"), _T("EnumObjectInstances: Could not find index: ") + object, status); 
     109    static Object EnumObject(std::wstring object, DWORD dwDetailLevel = PERF_DETAIL_WIZARD) { 
     110      Object ret; 
     111      ret.name = object; 
     112      DWORD dwCounterBufLen = 0; 
     113      TCHAR* szCounterBuffer = NULL; 
     114      DWORD dwInstanceBufLen = 0; 
     115      TCHAR* szInstanceBuffer = NULL; 
     116      try { 
     117        PDH::PDHError status = PDH::PDHFactory::get_impl()->PdhEnumObjectItems(NULL, NULL, object.c_str(), szCounterBuffer, &dwCounterBufLen, szInstanceBuffer, &dwInstanceBufLen, dwDetailLevel, 0); 
     118        if (status.is_more_data()) { 
     119          szCounterBuffer = new TCHAR[dwCounterBufLen+1024]; 
     120          szInstanceBuffer = new TCHAR[dwInstanceBufLen+1024]; 
     121 
     122          status = PDH::PDHFactory::get_impl()->PdhEnumObjectItems(NULL, NULL, object.c_str(), szCounterBuffer, &dwCounterBufLen, szInstanceBuffer, &dwInstanceBufLen, dwDetailLevel, 0); 
     123          if (status.is_error()) { 
     124            delete [] szCounterBuffer; 
     125            delete [] szInstanceBuffer; 
     126            throw PDHException(_T("PdhEnumObjectItems failed when trying to retrieve buffer for ") + object, status); 
     127          } 
     128 
     129          if (dwCounterBufLen > 0) { 
     130            TCHAR *cp=szCounterBuffer; 
     131            while(*cp != '\0') { 
     132              ret.counters.push_back(cp); 
     133              cp += lstrlen(cp)+1; 
     134            } 
     135          } 
     136          if (dwInstanceBufLen > 0) { 
     137            TCHAR *cp=szInstanceBuffer; 
     138            while(*cp != '\0') { 
     139              ret.instances.push_back(cp); 
     140              cp += lstrlen(cp)+1; 
     141            } 
     142          } 
     143          delete [] szCounterBuffer; 
     144          delete [] szInstanceBuffer; 
     145        } 
     146      } catch (std::exception &e) { 
     147        ret.error = e.what(); 
     148      } catch (...) { 
     149        ret.error = "Exception fetching data"; 
    139150      } 
    140       pdh_object_details ret; 
    141       ret.counters = PDHHelpers::build_list(counter_buffer, counter_len); 
    142       ret.instances = PDHHelpers::build_list(instance_buffer, instance_len); 
    143       delete [] counter_buffer; 
    144       delete [] instance_buffer; 
    145151      return ret; 
    146152    } 
  • modules/CheckSystem/CheckSystem.cpp

    ree230f7 r48b6b97  
    302302} 
    303303 
     304std::wstring qoute(const std::wstring &s) { 
     305  if (s.find(L',') == std::wstring::npos) 
     306    return s; 
     307  return _T("\"") + s + _T("\""); 
     308} 
     309bool render_list(const PDH::Enumerations::Objects &list, bool validate, bool porcelain, std::wstring filter, std::wstring &result) { 
     310  if (!porcelain) { 
     311    result += _T("Listing all counters\n"); 
     312    result += _T("---------------------------\n"); 
     313  } 
     314  try { 
     315    int total = 0, match = 0; 
     316    BOOST_FOREACH(const PDH::Enumerations::Object &obj, list) { 
     317      if (!obj.error.empty()) { 
     318        result += _T("error,") + obj.name + _T(",") + utf8::to_unicode(obj.error) + _T("\n"); 
     319      } else if (obj.instances.size() > 0) { 
     320        BOOST_FOREACH(const std::wstring &inst, obj.instances) { 
     321          BOOST_FOREACH(const std::wstring &count, obj.counters) { 
     322            std::wstring line = _T("\\") + obj.name + _T("(") + inst + _T(")\\") + count; 
     323            total++; 
     324            if (!filter.empty() && line.find(filter) == std::wstring::npos) 
     325              continue; 
     326            boost::tuple<bool,std::wstring> status; 
     327            if (validate) 
     328              status = validate_counter(line); 
     329            if (porcelain)  
     330              line = _T("counter,") + qoute(obj.name) + _T(",") + qoute(inst) + _T(",") + qoute(count) + _T(", ") + qoute(status.get<1>()); 
     331            else if (validate) 
     332              line = line + _T(": ") + status.get<1>(); 
     333            result += line + _T("\n"); 
     334            match++; 
     335          } 
     336        } 
     337      } else { 
     338        BOOST_FOREACH(const std::wstring &count, obj.counters) { 
     339          std::wstring line = _T("\\") + obj.name + _T("\\") + count; 
     340          total++; 
     341          if (!filter.empty() && line.find(filter) == std::wstring::npos) 
     342            continue; 
     343          boost::tuple<bool,std::wstring> status; 
     344          if (validate) 
     345            status = validate_counter(line); 
     346 
     347          if (porcelain)  
     348            line = _T("counter,") + qoute(obj.name) + _T(",,") + qoute(count)  + _T(", ") + qoute(status.get<1>()); 
     349          else if (validate) 
     350            line = line + _T(": ") + status.get<1>(); 
     351          result += line + _T("\n"); 
     352          match++; 
     353        } 
     354      } 
     355    } 
     356    if (!porcelain) { 
     357      result += _T("---------------------------\n"); 
     358      result += _T("Listed ") + strEx::itos(match) + _T(" of ") + strEx::itos(total) + _T(" counters."); 
     359    } 
     360    return true; 
     361  } catch (const PDH::PDHException e) { 
     362    result = _T("ERROR: Service enumeration failed: ") + e.getError(); 
     363    return false; 
     364  } 
     365} 
     366 
    304367int CheckSystem::commandLineExec(const std::wstring &command, std::list<std::wstring> &arguments, std::wstring &result) { 
    305368  if (command == _T("pdh") || command == _T("help") || command.empty()) { 
     
    354417    if (list) { 
    355418      if (all) { 
    356         if (!porcelain) { 
    357           result += _T("Listing all counters\n"); 
    358           result += _T("---------------------------\n"); 
    359         } 
    360         try { 
    361           int total = 0, match = 0; 
    362           PDH::Enumerations::Objects lst = PDH::Enumerations::EnumObjects(); 
    363           BOOST_FOREACH(PDH::Enumerations::Object &obj, lst) { 
    364             if (!obj.error.empty()) { 
    365               result += _T("error,") + obj.name + _T(",") + utf8::to_unicode(obj.error) + _T("\n"); 
    366             } else if (obj.instances.size() > 0) { 
    367               BOOST_FOREACH(const PDH::Enumerations::Instance &inst, obj.instances) { 
    368                 BOOST_FOREACH(const PDH::Enumerations::Counter &count, obj.counters) { 
    369                   std::wstring line = _T("\\") + obj.name + _T("(") + inst.name + _T(")\\") + count.name; 
    370                   total++; 
    371                   if (!counter.empty() && line.find(counter) == std::wstring::npos) 
    372                     continue; 
    373                   boost::tuple<bool,std::wstring> status; 
    374                   if (validate) 
    375                     status = validate_counter(line); 
    376                   if (porcelain)  
    377                     line = _T("counter,") + obj.name + _T(",") + inst.name + _T(",") + count.name + _T(", ") + status.get<1>(); 
    378                   else if (validate) 
    379                     line = line + _T(": ") + status.get<1>(); 
    380                   result += line + _T("\n"); 
    381                   match++; 
    382                 } 
    383               } 
    384             } else { 
    385               BOOST_FOREACH(const PDH::Enumerations::Counter &count, obj.counters) { 
    386                 std::wstring line = _T("\\") + obj.name + _T("\\") + count.name; 
    387                 total++; 
    388                 if (!counter.empty() && line.find(counter) == std::wstring::npos) 
    389                   continue; 
    390                 boost::tuple<bool,std::wstring> status; 
    391                 if (validate) 
    392                   status = validate_counter(line); 
    393  
    394                 if (porcelain)  
    395                   line = _T("counter,") + obj.name + _T(",,") + _T(",") + count.name  + _T(", ") + status.get<1>(); 
    396                 else if (validate) 
    397                   line = line + _T(": ") + status.get<1>(); 
    398                 result += line + _T("\n"); 
    399                 match++; 
    400               } 
    401             } 
     419        // If we specified all list all counters 
     420        PDH::Enumerations::Objects lst = PDH::Enumerations::EnumObjects(); 
     421        return render_list(lst, validate, porcelain, counter, result)?NSCAPI::isSuccess:NSCAPI::hasFailed; 
     422      } else { 
     423        if (vm.count("counter")) { 
     424          // If we specify a counter object we will only list instances of that 
     425          PDH::Enumerations::Objects lst; 
     426          lst.push_back(PDH::Enumerations::EnumObject(counter)); 
     427          return render_list(lst, validate, porcelain, counter, result)?NSCAPI::isSuccess:NSCAPI::hasFailed; 
     428        } else { 
     429          // If we specify no query we will list all configured counters  
     430          int count = 0, match = 0; 
     431          if (counters.empty()) { 
     432            sh::settings_registry settings(get_settings_proxy()); 
     433            settings.set_alias(_T("check"), _T("system/windows"), _T("system/windows")); 
     434            load_counters(counters, settings); 
     435          } 
     436          if (!porcelain) { 
     437            result += _T("Listing configured counters\n"); 
     438            result += _T("---------------------------\n"); 
     439          }  
     440          BOOST_FOREACH(const counter_map_type::value_type v, counters) { 
     441            std::wstring line = v.first + _T(" = ") + v.second; 
     442            boost::tuple<bool,std::wstring> status; 
     443            count++; 
     444            if (!counter.empty() && line.find(counter) == std::wstring::npos) 
     445              continue; 
     446 
     447            if (validate) 
     448              status = validate_counter(v.second); 
     449 
     450            if (porcelain)  
     451              line = v.first + _T(",") + v.second + _T(",") + status.get<1>(); 
     452            else if (validate) 
     453              line = v.first + _T(" = ") + v.second + _T(": ") + status.get<1>(); 
     454            else  
     455              line = v.first + _T(" = ") + v.second; 
     456            result += line + _T("\n"); 
     457            match++; 
    402458          } 
    403459          if (!porcelain) { 
    404460            result += _T("---------------------------\n"); 
    405             result += _T("Listed ") + strEx::itos(match) + _T(" of ") + strEx::itos(total) + _T(" counters."); 
     461            result += _T("Listed ") + strEx::itos(match) + _T(" of ") + strEx::itos(count) + _T(" counters."); 
    406462          } 
    407         } catch (const PDH::PDHException e) { 
    408           result = _T("ERROR: Service enumeration failed: ") + e.getError(); 
    409           return NSCAPI::hasFailed; 
    410         } 
    411       } else { 
    412         int count = 0, match = 0; 
    413         if (counters.empty()) { 
    414           sh::settings_registry settings(get_settings_proxy()); 
    415           settings.set_alias(_T("check"), _T("system/windows"), _T("system/windows")); 
    416  
    417           load_counters(counters, settings); 
    418         } 
    419         if (!porcelain) { 
    420           result += _T("Listing configured counters\n"); 
    421           result += _T("---------------------------\n"); 
    422         }  
    423         BOOST_FOREACH(const counter_map_type::value_type v, counters) { 
    424           std::wstring line = v.first + _T(" = ") + v.second; 
    425           boost::tuple<bool,std::wstring> status; 
    426           count++; 
    427           if (!counter.empty() && line.find(counter) == std::wstring::npos) 
    428             continue; 
    429  
    430           if (validate) 
    431             status = validate_counter(v.second); 
    432  
    433           if (porcelain)  
    434             line = v.first + _T(",") + v.second + _T(",") + status.get<1>(); 
    435           else if (validate) 
    436             line = v.first + _T(" = ") + v.second + _T(": ") + status.get<1>(); 
    437           else  
    438             line = v.first + _T(" = ") + v.second; 
    439           result += line + _T("\n"); 
    440           match++; 
    441         } 
    442         if (!porcelain) { 
    443           result += _T("---------------------------\n"); 
    444           result += _T("Listed ") + strEx::itos(match) + _T(" of ") + strEx::itos(count) + _T(" counters."); 
    445463        } 
    446464      } 
     
    519537  } else if (command == _T("checkcounter")) { 
    520538    return checkCounter(arguments, message, perf); 
    521   } else if (command == _T("listcounterinstances")) { 
    522     return listCounterInstances(arguments, message, perf); 
    523539  } else if (command == _T("checksingleregentry")) { 
    524540    return checkSingleRegEntry(arguments, message, perf); 
     
    14681484} 
    14691485 
    1470  
    1471  
    1472 /** 
    1473  * List all instances for a given counter. 
    1474  * 
    1475  * @param command Command to execute 
    1476  * @param argLen The length of the argument buffer 
    1477  * @param **char_args The argument buffer 
    1478  * @param &msg String to put message in 
    1479  * @param &perf String to put performance data in  
    1480  * @return The status of the command 
    1481  * 
    1482  * @todo add parsing support for NRPE 
    1483  */ 
    1484 NSCAPI::nagiosReturn CheckSystem::listCounterInstances(std::list<std::wstring> arguments, std::wstring &msg, std::wstring &perf) 
    1485 { 
    1486   typedef checkHolders::CheckContainer<checkHolders::MaxMinBoundsDouble> CounterContainer; 
    1487  
    1488   if (arguments.empty()) { 
    1489     msg = _T("ERROR: Missing argument exception."); 
    1490     return NSCAPI::returnUNKNOWN; 
    1491   } 
    1492  
    1493   std::wstring counter; 
    1494   BOOST_FOREACH(std::wstring s, arguments) { counter+= s + _T(" "); } 
    1495   try { 
    1496     PDH::Enumerations::pdh_object_details obj = PDH::Enumerations::EnumObjectInstances(counter); 
    1497     for (PDH::Enumerations::pdh_object_details::list::const_iterator it = obj.instances.begin(); it!=obj.instances.end();++it) { 
    1498       if (!msg.empty()) 
    1499         msg += _T(", "); 
    1500       msg += (*it); 
    1501     } 
    1502     if (msg.empty()) { 
    1503       msg = _T("ERROR: No instances found"); 
    1504       return NSCAPI::returnUNKNOWN; 
    1505     } 
    1506   } catch (const PDH::PDHException e) { 
    1507     msg = _T("ERROR: Failed to enumerate counter instances: " + e.getError()); 
    1508     return NSCAPI::returnUNKNOWN; 
    1509   } catch (...) { 
    1510     msg = _T("ERROR: Failed to enumerate counter instances: <UNKNOWN EXCEPTION>"); 
    1511     return NSCAPI::returnUNKNOWN; 
    1512   } 
    1513   return NSCAPI::returnOK; 
    1514 } 
    1515  
    15161486////////////////////////////////////////////////////////////////////////// 
    15171487////////////////////////////////////////////////////////////////////////// 
  • modules/CheckSystem/CheckSystem.h

    ree230f7 r48b6b97  
    3737 
    3838public: 
    39   /* 
    40   typedef enum { started, stopped } states; 
    41   typedef struct rB { 
    42     NSCAPI::nagiosReturn code_; 
    43     std::wstring msg_; 
    44     std::wstring perf_; 
    45     rB(NSCAPI::nagiosReturn code, std::wstring msg) : code_(code), msg_(msg) {} 
    46     rB() : code_(NSCAPI::returnUNKNOWN) {} 
    47   } returnBundle; 
    48 */ 
    4939  std::map<DWORD,std::wstring> lookups_; 
    5040 
     
    8979  NSCAPI::nagiosReturn checkProcState(std::list<std::wstring> arguments, std::wstring &msg, std::wstring &perf); 
    9080  NSCAPI::nagiosReturn checkCounter(std::list<std::wstring> arguments, std::wstring &msg, std::wstring &perf); 
    91   NSCAPI::nagiosReturn listCounterInstances(std::list<std::wstring> arguments, std::wstring &msg, std::wstring &perf); 
    9281  NSCAPI::nagiosReturn checkSingleRegEntry(std::list<std::wstring> arguments, std::wstring &message, std::wstring &perf); 
    9382 
  • modules/CheckSystem/PDHCollector.cpp

    ree230f7 r48b6b97  
    6666 
    6767  } 
    68   if (thread_data_->subsystem == _T("fast") || thread_data_->subsystem == _T("auto")) { 
     68  if (thread_data_->subsystem == _T("fast") || thread_data_->subsystem == _T("auto") || thread_data_->subsystem == _T("default")) { 
    6969  } else if (thread_data_->subsystem == _T("thread-safe")) { 
    7070    PDH::PDHFactory::set_threadSafe(); 
    7171  } else { 
    72     NSC_LOG_ERROR_STD(_T("Unknown PDH subsystem (") + thread_data_->subsystem + _T(") valid values are: fast (auto) and thread-safe")); 
     72    NSC_LOG_ERROR_STD(_T("Unknown PDH subsystem (") + thread_data_->subsystem + _T(") valid values are: fast (default) and thread-safe")); 
    7373  } 
    7474 
  • modules/NSClientServer/NSClientServer.cpp

    ra48fd4c r48b6b97  
    2121#include "stdafx.h" 
    2222#include "NSClientServer.h" 
     23 
     24#include <boost/assign.hpp> 
     25 
    2326#include <strEx.h> 
    2427#include <time.h> 
     
    204207} 
    205208 
     209 
     210std::wstring list_instance(std::wstring counter) { 
     211  std::list<std::wstring> exeresult; 
     212  nscapi::core_helper::exec_simple_command(_T("*"), _T("pdh"), boost::assign::list_of(std::wstring(_T("--list")))(_T("--porcelain"))(_T("--counter"))(counter), exeresult); 
     213  std::wstring result; 
     214 
     215  typedef std::basic_istringstream<wchar_t> wistringstream; 
     216  typedef boost::tokenizer< boost::escaped_list_separator<wchar_t>, std::wstring::const_iterator, std::wstring > Tokenizer; 
     217  BOOST_FOREACH(std::wstring s, exeresult) { 
     218    wistringstream iss(s); 
     219    std::wstring line; 
     220    while(std::getline(iss, line, L'\n')) { 
     221      Tokenizer tok(line); 
     222      Tokenizer::const_iterator cit = tok.begin(); 
     223      int i = 2; 
     224      while ((i-->0) && (cit != tok.end())) 
     225        ++cit; 
     226      if (i <= 1) { 
     227        if (!result.empty()) 
     228          result += _T(","); 
     229        result += *cit; 
     230      } else { 
     231        NSC_LOG_ERROR(_T("Invalid line: ") + line); 
     232      } 
     233    } 
     234  } 
     235  return result; 
     236} 
     237 
    206238check_nt::packet NSClientServer::handle(check_nt::packet p) { 
    207239  std::wstring buffer = p.get_payload(); 
     
    282314      break; 
    283315    case REQ_INSTANCES: 
    284       cmd.first = _T("listCounterInstances"); 
    285       args.push_back(cmd.second); 
    286       break; 
     316      return list_instance(cmd.second); 
    287317 
    288318 
  • version.txt

    r24f6e3f r48b6b97  
    11version=0.4.1 
    2 build=30 
    3 date=2012-08-04 
     2build=32 
     3date=2012-08-06 
Note: See TracChangeset for help on using the changeset viewer.