Changeset 523576e in nscp


Ignore:
Timestamp:
02/19/12 22:44:34 (15 months ago)
Author:
Michael Medin <michael@…>
Branches:
master, 0.4.0, 0.4.1, 0.4.2
Children:
72eea1f
Parents:
c710cc7
Message:
  • Added new unit context on command line for running simple unit test cases: nscp unit --language python --script test_nsca
  • Added dependency on Tcpip
  • Dropped OS bit-match requirement so now you can install any version on x64 plattform.
  • Added so you can specify multiple counters for CheckCounter and poll them all in one go (#387)
  • Added test cases (a bit flaky) for counters.
  • Added ${host} and ${domain} to hostname settings option which might be used to construct your own hostname. (#428) Not 100% sure about domain as on my box the "hostname" is only a name ie. has no domain...
  • Fixed so too long log messages are trunacated instead of discarded
  • Added option to truncate logfile if to large (#358) logger max size = 1000
  • Added keyword to reload (settings) to reload settings store (ie. flushing the cache) (#249).
  • Added ability to load all files in a given directory (#366)
  • Tweaked a bit in regards to ExternalScripts? so it works better and handles errors better (#367)
  • Fixed default report mode in 0.4.0 (#290)
  • Made NSCA Client handle timestamps like send_nsca (ie. ignoring local time)
Files:
26 edited

Legend:

Unmodified
Added
Removed
  • changelog

    rc710cc7 r523576e  
    44 * Fixa dependonservice LanManWorkStation (old win) 
    55 * Fix RtlStringFromGUID problem on NT4 
     6 
     72012-02-19 MickeM 
     8 * Added new unit context on command line for running simple unit test cases: 
     9   nscp unit --language python --script test_nsca 
     10 * Added dependency on Tcpip 
     11 * Dropped OS bit-match requirement so now you can install any version on x64 plattform. 
     12 * Added so you can specify multiple counters for CheckCounter and poll them all in one go (#387) 
     13 * Added test cases (a bit flaky) for counters. 
     14 * Added ${host} and ${domain} to hostname settings option which might be used to construct your own hostname. (#428) 
     15   Not 100% sure about domain as on my box the "hostname" is only a name ie. has no domain... 
     16 
     172012-02-18 MickeM 
     18 * Fixed so too long log messages are trunacated instead of discarded 
     19 * Added option to truncate logfile if to large (#358) 
     20   [/settings/file logger] 
     21   max size = 1000 
     22 * Added keyword to reload (settings) to reload settings store (ie. flushing the cache) (#249). 
     23 * Added ability to load all files in a given directory (#366) 
     24 
     252012-02-17 MickeM 
     26 * Tweaked a bit in regards to ExternalScripts so it works better and handles errors better (#367) 
     27 * Fixed default report mode in 0.4.0 (#290) 
     28 * Made NSCA Client handle timestamps like send_nsca (ie. ignoring local time) 
    629 
    7302012-02-16 MickeM 
  • helpers/installers/installer/Product.wxs

    r2906cda r523576e  
    3030 
    3131    <?if "$(var.arch)" = "x64"?> 
    32       <Condition Message="Win32 bit version not supported (by installer) on x64 bit platform (get x64 bit version instead)">VersionNT64</Condition> 
    33     <?else?> 
    3432      <Condition Message="x64 bit version not supported (by installer) on Win32 bit platform (get Win32 bit version instead)">NOT VersionNT64</Condition> 
    3533    <?endif?> 
     
    5048              Type="ownProcess" Start="auto" ErrorControl="normal" Interactive="no" 
    5149              Description="Monitoring agent for nagios (and others) used to respond to status queries" 
    52               Arguments="service --run --name [SERVICE_NAME]" /> 
     50              Arguments="service --run --name [SERVICE_NAME]"> 
     51        <ServiceDependency Id="Tcpip" /> 
     52      </ServiceInstall> 
    5353            <ServiceControl Id="StartSWCNSCP" Name="[SERVICE_NAME]" Start="install" Stop="both" Wait="yes" Remove="uninstall" /> 
    5454            <RemoveFolder Id="RemoveMenuShortcuts" Directory="ProgramMenuDir" On="uninstall" /> 
  • include/execute_process_w32.hpp

    rc710cc7 r523576e  
    111111 
    112112      dwAvail = 0; 
    113       if (!::PeekNamedPipe(hChildOutR, NULL, 0, NULL, &dwAvail, NULL)) 
    114         NSC_LOG_ERROR_STD(_T("Failed to peek buffer: ") + error::lookup::last_error()); 
    115       if (dwAvail > 0) 
     113      if (::PeekNamedPipe(hChildOutR, NULL, 0, NULL, &dwAvail, NULL) && dwAvail > 0) 
    116114        str += readFromFile(buffer, hChildOutR); 
    117115      msg = strEx::string_to_wstring(str); 
  • include/nsca/nsca_packet.hpp

    rb8b2e3d r523576e  
    165165    } 
    166166 
    167     void get_buffer(std::string &buffer) const { 
     167    void get_buffer(std::string &buffer, int servertime=0) const { 
    168168      nsca::data::data_packet *data = reinterpret_cast<nsca::data::data_packet*>(&*buffer.begin()); 
    169169      if (buffer.size() < get_packet_length()) 
     
    171171 
    172172      data->packet_version=swap_bytes::hton<int16_t>(nsca::data::version3); 
    173       data->timestamp=swap_bytes::hton<u_int32_t>(time); 
     173      if (servertime != 0) 
     174        data->timestamp=swap_bytes::hton<u_int32_t>(servertime); 
     175      else 
     176        data->timestamp=swap_bytes::hton<u_int32_t>(time); 
    174177      data->return_code = swap_bytes::hton<int16_t>(code); 
    175178      data->crc32_value= swap_bytes::hton<u_int32_t>(0); 
  • include/nsca/nsca_socket.hpp

    rc5ec0c8 r523576e  
    1818    boost::asio::io_service &io_service_; 
    1919    nsca_encrypt crypt_inst; 
     20    int time; 
    2021  public: 
    2122    typedef boost::asio::basic_socket<tcp,boost::asio::stream_socket_service<tcp> >  basic_socket_type; 
    2223 
    2324  public: 
    24     socket(boost::asio::io_service &io_service) : io_service_(io_service) { 
     25    socket(boost::asio::io_service &io_service) : io_service_(io_service), time(0) { 
    2526      socket_.reset(new tcp::socket(io_service_)); 
    2627    } 
     
    7273      } 
    7374      std::string buffer = crypt_inst.get_rand_buffer(packet.get_packet_length()); 
    74       packet.get_buffer(buffer); 
     75      packet.get_buffer(buffer, time); 
    7576      crypt_inst.encrypt_buffer(buffer); 
    7677      NSC_DEBUG_MSG(_T("Sending data: ") + strEx::itos(buffer.size())); 
     
    9091      nsca::iv_packet iv_packet(std::string(buf.begin(), buf.end())); 
    9192      std::string iv = iv_packet.get_iv(); 
     93      time = iv_packet.get_time(); 
    9294      NSC_DEBUG_MSG(_T("Encrypting using when sending: ") + utf8::cvt<std::wstring>(nsca::nsca_encrypt::helpers::encryption_to_string(encryption_method)) + _T(" and ") + utf8::cvt<std::wstring>(password)); 
    9395      crypt_inst.encrypt_init(password, encryption_method, iv); 
  • include/nscapi/functions.hpp

    r0f7b655 r523576e  
    885885          Plugin::Common_PerformanceData_FloatValue fval = perfData.float_value(); 
    886886 
    887           ss << fval.value(); 
     887          ss << strEx::s::itos_non_sci(fval.value()); 
    888888          if (fval.has_unit()) 
    889889            ss << fval.unit(); 
  • include/pdh/enumerations.hpp

    rf0e6036 r523576e  
    4343    struct Object { 
    4444      std::wstring name; 
     45      std::string error; 
    4546      Instances instances; 
    4647      Counters counters; 
     
    7172      delete [] szObjectBuffer; 
    7273 
    73       for (Objects::iterator it = ret.begin(); it != ret.end(); ++it) { 
     74      BOOST_FOREACH(Object &o, ret) { 
    7475        DWORD dwCounterBufLen = 0; 
    7576        TCHAR* szCounterBuffer = NULL; 
    7677        DWORD dwInstanceBufLen = 0; 
    7778        TCHAR* szInstanceBuffer = NULL; 
    78         status = PDH::PDHFactory::get_impl()->PdhEnumObjectItems(NULL, NULL, (*it).name.c_str(), szCounterBuffer, &dwCounterBufLen, szInstanceBuffer, &dwInstanceBufLen, dwDetailLevel, 0); 
    79         if (!status.is_more_data()) { 
    80           szCounterBuffer = new TCHAR[dwCounterBufLen+1024]; 
    81           szInstanceBuffer = new TCHAR[dwInstanceBufLen+1024]; 
     79        try { 
     80          status = PDH::PDHFactory::get_impl()->PdhEnumObjectItems(NULL, NULL, o.name.c_str(), szCounterBuffer, &dwCounterBufLen, szInstanceBuffer, &dwInstanceBufLen, dwDetailLevel, 0); 
     81          if (status.is_more_data()) { 
     82            szCounterBuffer = new TCHAR[dwCounterBufLen+1024]; 
     83            szInstanceBuffer = new TCHAR[dwInstanceBufLen+1024]; 
    8284 
    83           status = PDH::PDHFactory::get_impl()->PdhEnumObjectItems(NULL, NULL, (*it).name.c_str(), szCounterBuffer, &dwCounterBufLen, szInstanceBuffer, &dwInstanceBufLen, dwDetailLevel, 0); 
    84           if (status.is_error()) { 
     85            status = PDH::PDHFactory::get_impl()->PdhEnumObjectItems(NULL, NULL, o.name.c_str(), szCounterBuffer, &dwCounterBufLen, szInstanceBuffer, &dwInstanceBufLen, dwDetailLevel, 0); 
     86            if (status.is_error()) { 
     87              delete [] szCounterBuffer; 
     88              delete [] szInstanceBuffer; 
     89              throw PDHException(_T("PdhEnumObjectItems failed when trying to retrieve buffer for ") + o.name, status); 
     90            } 
     91 
     92            if (dwCounterBufLen > 0) { 
     93              cp=szCounterBuffer; 
     94              while(*cp != '\0') { 
     95                Counter c; 
     96                c.name = cp; 
     97                o.counters.push_back(c); 
     98                cp += lstrlen(cp)+1; 
     99              } 
     100            } 
     101            if (dwInstanceBufLen > 0) { 
     102              cp=szInstanceBuffer; 
     103              while(*cp != '\0') { 
     104                Instance i; 
     105                i.name = cp; 
     106                o.instances.push_back(i); 
     107                cp += lstrlen(cp)+1; 
     108              } 
     109            } 
    85110            delete [] szCounterBuffer; 
    86111            delete [] szInstanceBuffer; 
    87             throw PDHException(_T("PdhEnumObjectItems failed when trying to retrieve buffer for ") + (*it).name, status); 
    88112          } 
    89  
    90           if (dwCounterBufLen > 0) { 
    91             cp=szCounterBuffer; 
    92             while(*cp != '\0') { 
    93               Counter o; 
    94               o.name = cp; 
    95               (*it).counters.push_back(o); 
    96               cp += lstrlen(cp)+1; 
    97             } 
    98           } 
    99           if (dwInstanceBufLen > 0) { 
    100             cp=szInstanceBuffer; 
    101             while(*cp != '\0') { 
    102               Instance o; 
    103               o.name = cp; 
    104               (*it).instances.push_back(o); 
    105               cp += lstrlen(cp)+1; 
    106             } 
    107           } 
    108           delete [] szCounterBuffer; 
    109           delete [] szInstanceBuffer; 
     113        } catch (std::exception &e) { 
     114          o.error = e.what(); 
     115        } catch (...) { 
     116          o.error = "Exception fetching data"; 
    110117        } 
    111118      } 
  • include/settings/settings_ini.hpp

    r53c1a6e r523576e  
    218218      if (is_loaded_) 
    219219        return; 
     220      if (boost::filesystem::is_directory(get_file_name())) { 
     221 
     222        boost::filesystem::wdirectory_iterator it(get_file_name()), eod; 
     223 
     224        BOOST_FOREACH(boost::filesystem::wpath const &p, std::make_pair(it, eod)) { 
     225          add_child(_T("ini:///") + p.string()); 
     226        } 
     227      } 
    220228      if (!file_exists()) { 
    221229        is_loaded_ = true; 
     
    249257      if (filename_.empty()) { 
    250258        filename_ = get_file_from_context(); 
    251         //filename_ = get_core()->get_base() / boost::filesystem::wpath(get_core()->get_boot_string(get_context(), _T("file"), _T("nsclient.ini"))); 
     259        if (filename_.size() > 0) { 
     260          if (boost::filesystem::is_regular(filename_)) { 
     261          } else if (boost::filesystem::is_regular(filename_.substr(1))) { 
     262            filename_ = filename_.substr(1); 
     263          } else if (boost::filesystem::is_directory(filename_)) { 
     264          } else if (boost::filesystem::is_directory(filename_.substr(1))) { 
     265            filename_ = filename_.substr(1); 
     266          } 
     267        } 
    252268        get_core()->get_logger()->debug(__FILE__, __LINE__, _T("Reading INI settings from: ") + filename_); 
    253269      } 
     
    265281      std::wstring file = url.host + url.path; 
    266282      std::wstring tmp = core->expand_path(file); 
    267       return boost::filesystem::is_regular(tmp); 
     283      if (tmp.size()>1 && tmp[0] == '/') { 
     284        if (boost::filesystem::is_regular(tmp) || boost::filesystem::is_directory(tmp)) 
     285          return true; 
     286        tmp = tmp.substr(1); 
     287      } 
     288      return boost::filesystem::is_regular(tmp) || boost::filesystem::is_directory(tmp); 
    268289    } 
    269290 
  • include/strEx.h

    rf33c12f r523576e  
    271271      return ss.str(); 
    272272    } 
     273    inline std::string itos_non_sci(double i) { 
     274      std::stringstream ss; 
     275      if (i < 10) 
     276        ss.precision(20); 
     277      ss << std::noshowpoint << std::fixed << i; 
     278      std::string s = ss.str(); 
     279      std::string::size_type pos = s.find_last_not_of('0'); 
     280      if (pos == std::wstring::npos) 
     281        return s; 
     282      if (s[pos] != '.') 
     283        pos++; 
     284      return s.substr(0, pos); 
     285    } 
    273286  } 
    274287 
  • modules/CheckExternalScripts/CheckExternalScripts.cpp

    rc710cc7 r523576e  
    8181 
    8282    settings.alias().add_path_to_settings() 
     83 
     84      (_T("wrappings"), sh::wstring_map_path(&wrappings_) 
     85      , _T("EXTERNAL SCRIPT WRAPPINGS SECTION"), _T("A list of templates for wrapped scripts")) 
     86 
     87      ; 
     88 
     89    settings.register_all(); 
     90    settings.notify(); 
     91    settings.clear(); 
     92 
     93    settings.alias().add_path_to_settings() 
    8394      (_T("EXTERNAL SCRIPT SECTION"), _T("Section for external scripts configuration options (CheckExternalScripts).")) 
    8495 
     
    8697      _T("EXTERNAL SCRIPT SCRIPT SECTION"), _T("A list of scripts available to run from the CheckExternalScripts module. Syntax is: <command>=<script> <arguments>")) 
    8798 
    88       (_T("wrappings"), sh::wstring_map_path(&wrappings_) 
    89       , _T("EXTERNAL SCRIPT WRAPPINGS SECTION"), _T("A list of templates for wrapped scripts")) 
    90  
    9199      (_T("alias"), sh::fun_values_path(boost::bind(&CheckExternalScripts::add_alias, this, _1, _2)),  
    92100      _T("EXTERNAL SCRIPT ALIAS SECTION"), _T("A list of aliases available. An alias is an internal command that has been \"wrapped\" (to add arguments). Be careful so you don't create loops (ie check_loop=check_a, check_a=check_loop)")) 
     101 
     102      (_T("wrapped scripts"), sh::fun_values_path(boost::bind(&CheckExternalScripts::add_wrapping, this, _1, _2)),  
     103      _T("EXTERNAL SCRIPT WRAPPED SCRIPTS SECTION"), _T("A list of wrappped scripts (ie. using the template mechanism)")) 
    93104 
    94105      ; 
     
    108119      ; 
    109120 
    110     settings.register_all(); 
    111     settings.notify(); 
    112     settings.clear(); 
    113  
    114     settings.alias().add_path_to_settings() 
    115  
    116       (_T("wrapped scripts"), sh::fun_values_path(boost::bind(&CheckExternalScripts::add_wrapping, this, _1, _2)),  
    117       _T("EXTERNAL SCRIPT WRAPPED SCRIPTS SECTION"), _T("A list of wrappped scripts (ie. using the template mechanism)")) 
    118  
    119       ; 
    120121    settings.register_all(); 
    121122    settings.notify(); 
     
    201202      } 
    202203    } 
     204  } else if (!allowArgs_ && data.args.size() > 0) { 
     205    NSC_LOG_ERROR_STD(_T("Arguments not allowed in CheckExternalScripts set /settings/external scripts/allow arguments=true")) 
    203206  } 
    204207 
  • modules/CheckExternalScripts/CheckExternalScripts.h

    rc710cc7 r523576e  
    9090 
    9191    std::wstring tpl = wrappings_[type]; 
     92    if (tpl.empty() && type == _T("vbs")) 
     93      tpl = _T("cscript.exe //T:30 //NoLogo scripts\\lib\\wrapper.vbs %SCRIPT% %ARGS%"); 
     94    else if (tpl.empty() && type == _T("ps1")) 
     95      tpl = _T("cmd /c echo scripts\\%SCRIPT% %ARGS%; exit($lastexitcode) | powershell.exe -command -"); 
     96    else if (tpl.empty() && type == _T("bat")) 
     97      tpl = _T("scripts\\%SCRIPT% %ARGS%"); 
     98    if (tpl.empty()) { 
     99      NSC_LOG_ERROR(_T("Failed to find wrapping for type: ") + type); 
     100    } else { 
     101      strEx::replace(tpl, _T("%SCRIPT%"), tok.first); 
     102      strEx::replace(tpl, _T("%ARGS%"), tok.second); 
    92103 
    93     strEx::replace(tpl, _T("%SCRIPT%"), tok.first); 
    94     strEx::replace(tpl, _T("%ARGS%"), tok.second); 
    95  
    96     add_command(key,tpl); 
     104      add_command(key,tpl); 
     105    } 
    97106  } 
    98107}; 
  • modules/CheckExternalScripts/commands.hpp

    rc710cc7 r523576e  
    8989        NSC_LOG_ERROR(_T("Failed to parse arguments for command '") + alias + _T("', using old split string method: ") + utf8::to_unicode(e.what())); 
    9090        strEx::splitList list = strEx::splitEx(str, _T(" ")); 
     91        if (list.size() > 0) { 
     92          command = list.front(); 
     93          list.pop_front(); 
     94        } 
     95        arguments.clear(); 
    9196        BOOST_FOREACH(std::wstring s, list) { 
    9297          arguments.push_back(s); 
  • modules/CheckSystem/CheckSystem.cpp

    rc5ec0c8 r523576e  
    205205} 
    206206 
    207 int CheckSystem::commandLineExec(const wchar_t* command,const unsigned int argLen,wchar_t** args) { 
    208   if (command == NULL) { 
     207int CheckSystem::commandLineExec(const std::wstring &command, std::list<std::wstring> &arguments, std::wstring &result) { 
     208  if (command == _T("help")) { 
    209209    std::wcerr << _T("Usage: ... CheckSystem <command>") << std::endl; 
    210210    std::wcerr << _T("Commands: debugpdh, listpdh, pdhlookup, pdhmatch, pdhobject") << std::endl; 
    211211    return -1; 
    212212  } 
    213   if (_wcsicmp(command, _T("debugpdh")) == 0) { 
     213  if (command == _T("debugpdh")) { 
    214214    PDH::Enumerations::Objects lst; 
    215215    try { 
     
    334334      } 
    335335    } 
    336   } else if (_wcsicmp(command, _T("listpdh")) == 0) { 
     336  } else if (command == _T("listpdh")) { 
     337    bool porcelain = arguments.size() > 0 && arguments.front() == _T("--porcelain"); 
    337338    PDH::Enumerations::Objects lst; 
    338339    try { 
    339340      lst = PDH::Enumerations::EnumObjects(); 
    340341    } catch (const PDH::PDHException e) { 
    341       std::wcout << _T("Service enumeration failed: ") << e.getError(); 
    342       return 0; 
    343     } 
    344     for (PDH::Enumerations::Objects::iterator it = lst.begin();it!=lst.end();++it) { 
    345       if ((*it).instances.size() > 0) { 
    346         for (PDH::Enumerations::Instances::const_iterator it2 = (*it).instances.begin();it2!=(*it).instances.end();++it2) { 
    347           for (PDH::Enumerations::Counters::const_iterator it3 = (*it).counters.begin();it3!=(*it).counters.end();++it3) { 
    348             std::wcout << _T("\\") << (*it).name << _T("(") << (*it2).name << _T(")\\") << (*it3).name << std::endl;; 
     342      result = _T("ERROR: Service enumeration failed: ") + e.getError(); 
     343      return NSCAPI::returnUNKNOWN; 
     344    } 
     345    std::wstringstream ss; 
     346    BOOST_FOREACH(PDH::Enumerations::Object &obj, lst) { 
     347      if (!obj.error.empty()) { 
     348        ss << "error," << obj.name << "," << utf8::to_unicode(obj.error) << _T("\n"); 
     349      } else if (obj.instances.size() > 0) { 
     350        BOOST_FOREACH(const PDH::Enumerations::Instance &inst, obj.instances) { 
     351          BOOST_FOREACH(const PDH::Enumerations::Counter &count, obj.counters) { 
     352            if (porcelain)  
     353              ss << "counter," << obj.name << _T(",") << inst.name << _T(",") << count.name << _T("\n"); 
     354            else 
     355              ss << _T("\\") << obj.name << _T("(") << inst.name << _T(")\\") << count.name << _T("\n"); 
    349356          } 
    350357        } 
    351358      } else { 
    352         for (PDH::Enumerations::Counters::const_iterator it2 = (*it).counters.begin();it2!=(*it).counters.end();++it2) { 
    353           std::wcout << _T("\\") << (*it).name << _T("\\") << (*it2).name << std::endl;; 
     359        BOOST_FOREACH(const PDH::Enumerations::Counter &count, obj.counters) { 
     360          if (porcelain)  
     361            ss << obj.name << _T(",") << count.name << _T("\n"); 
     362          else 
     363            ss << _T("\\") << obj.name << _T("\\") << count.name << _T("\n"); 
    354364        } 
    355365      } 
    356366    } 
    357   } else if (_wcsicmp(command, _T("pdhlookup")) == 0) { 
     367    result = ss.str(); 
     368    return NSCAPI::returnOK; 
     369  } else if (command == _T("pdhlookup")) { 
    358370    try { 
    359       std::wstring name = array_buffer::arrayBuffer2string(args, argLen, _T(" ")); 
    360       if (name.empty()) { 
     371      if (arguments.size() == 0) { 
    361372        NSC_LOG_ERROR_STD(_T("Need to specify counter index name!")); 
    362373        return 0; 
    363374      } 
     375      std::wstring name = arguments.front(); 
    364376      DWORD dw = PDH::PDHResolver::lookupIndex(name); 
    365377      NSC_LOG_MESSAGE_STD(_T("--+--[ Lookup Result ]----------------------------------------")); 
     
    370382      return 0; 
    371383    } 
    372   } else if (_wcsicmp(command, _T("pdhmatch")) == 0) { 
     384  } else if (command == _T("pdhmatch")) { 
    373385    try { 
    374       std::wstring name = array_buffer::arrayBuffer2string(args, argLen, _T(" ")); 
    375       if (name.empty()) { 
    376         NSC_LOG_ERROR_STD(_T("Need to specify counter pattern!")); 
     386      if (arguments.size() == 0) { 
     387        NSC_LOG_ERROR_STD(_T("Need to specify counter index name!")); 
    377388        return 0; 
    378389      } 
     390      std::wstring name = arguments.front(); 
    379391      std::list<std::wstring> list = PDH::PDHResolver::PdhExpandCounterPath(name.c_str()); 
    380392      NSC_LOG_MESSAGE_STD(_T("--+--[ Lookup Result ]----------------------------------------")); 
     
    387399      return 0; 
    388400    } 
    389   } else if (_wcsicmp(command, _T("pdhobject")) == 0) { 
     401  } else if (command == _T("pdhobject")) { 
    390402    try { 
    391       std::wstring name = array_buffer::arrayBuffer2string(args, argLen, _T(" ")); 
    392       if (name.empty()) { 
    393         NSC_LOG_ERROR_STD(_T("Need to specify counter pattern!")); 
     403      if (arguments.size() == 0) { 
     404        NSC_LOG_ERROR_STD(_T("Need to specify counter index name!")); 
    394405        return 0; 
    395406      } 
     407      std::wstring name = arguments.front(); 
    396408      PDH::Enumerations::pdh_object_details list = PDH::Enumerations::EnumObjectInstances(name.c_str()); 
    397409      NSC_LOG_MESSAGE_STD(_T("--+--[ Lookup Result ]----------------------------------------")); 
     
    11951207} 
    11961208 
     1209template<class T> 
     1210class PerfDataContainer : public checkHolders::CheckContainer<T> { 
     1211private: 
     1212  typedef PDHCollectors::StaticPDHCounterListener<double, PDH_FMT_DOUBLE> counter_type; 
     1213  typedef boost::shared_ptr<counter_type> ptr_lsnr_type; 
     1214  ptr_lsnr_type cDouble; 
     1215public: 
     1216 
     1217  PerfDataContainer() : CheckContainer<T>() {} 
     1218 
     1219  PerfDataContainer(const PerfDataContainer &other) : CheckContainer<T>(other), cDouble(other.cDouble) {} 
     1220  const PerfDataContainer& operator =(const PerfDataContainer &other) { 
     1221    *((CheckContainer<T>*)this) = other; 
     1222    cDouble = other.cDouble; 
     1223    return *this; 
     1224  } 
     1225  ptr_lsnr_type get_listener() { 
     1226    if (!cDouble) 
     1227      cDouble = ptr_lsnr_type(new counter_type()); 
     1228    return cDouble; 
     1229  } 
     1230}; 
    11971231 
    11981232/** 
     
    12101244NSCAPI::nagiosReturn CheckSystem::checkCounter(std::list<std::wstring> arguments, std::wstring &msg, std::wstring &perf) 
    12111245{ 
    1212   typedef checkHolders::CheckContainer<checkHolders::MaxMinBoundsDouble> CounterContainer; 
     1246  typedef PerfDataContainer<checkHolders::MaxMinBoundsDouble> CounterContainer; 
    12131247 
    12141248  if (arguments.empty()) { 
     
    12601294    return NSCAPI::returnUNKNOWN; 
    12611295  } 
    1262  
    1263   for (std::list<CounterContainer>::const_iterator cit = counters.begin(); cit != counters.end(); ++cit) { 
    1264     CounterContainer counter = (*cit); 
     1296  PDH::PDHQuery pdh; 
     1297 
     1298  bool has_counter = false; 
     1299  BOOST_FOREACH(CounterContainer &counter, counters) { 
    12651300    try { 
    1266  
    1267  
    1268       double value  = 0; 
    12691301      if (counter.data.find('\\') == std::wstring::npos) { 
    1270         PDHCollector *pObject = pdhThread.getThread(); 
    1271         if (!pObject) { 
    1272           msg = _T("ERROR: PDH Collection thread not running."); 
    1273           return NSCAPI::returnUNKNOWN; 
    1274         } 
     1302        /* 
    12751303        value = pObject->get_double(counter.data); 
    12761304        if (value == -1) { 
     
    12781306          return NSCAPI::returnUNKNOWN; 
    12791307        } 
     1308        */ 
    12801309      } else { 
    12811310        std::wstring tstr; 
     
    12931322          } 
    12941323        } 
    1295         PDH::PDHQuery pdh; 
    1296         typedef boost::shared_ptr<PDHCollectors::StaticPDHCounterListener<double, PDH_FMT_DOUBLE> > ptr_lsnr_type; 
    1297         ptr_lsnr_type cDouble(new PDHCollectors::StaticPDHCounterListener<double, PDH_FMT_DOUBLE>()); 
    1298         //boost::shared_ptr<PDHCollectors::StaticPDHCounterListener<double, PDH_FMT_DOUBLE> > cDouble; 
    12991324        if (!extra_format.empty()) { 
    13001325          boost::char_separator<wchar_t> sep(_T(",")); 
     
    13131338            } 
    13141339          } 
    1315           cDouble->set_extra_format(flags); 
     1340          counter.get_listener()->set_extra_format(flags); 
    13161341        } 
    1317         pdh.addCounter(counter.data, cDouble); 
    1318         pdh.open(); 
    1319         if (bCheckAverages) { 
    1320           pdh.collect(); 
    1321           Sleep(1000); 
     1342        pdh.addCounter(counter.data, counter.get_listener()); 
     1343        has_counter = true; 
     1344      } 
     1345    } catch (const PDH::PDHException e) { 
     1346      NSC_LOG_ERROR_STD(_T("ERROR: ") + e.getError() + _T(" (") + counter.getAlias() + _T("|") + counter.data + _T(")")); 
     1347      if (bNSClient) 
     1348        msg = _T("0"); 
     1349      else 
     1350        msg = static_cast<std::wstring>(_T("ERROR: ")) + e.getError()+ _T(" (") + counter.getAlias() + _T("|") + counter.data + _T(")"); 
     1351      return NSCAPI::returnUNKNOWN; 
     1352    } 
     1353  } 
     1354  if (has_counter) { 
     1355    try { 
     1356      pdh.open(); 
     1357      if (bCheckAverages) { 
     1358        pdh.collect(); 
     1359        Sleep(1000); 
     1360      } 
     1361      pdh.collect(); 
     1362      pdh.gatherData(); 
     1363      pdh.close(); 
     1364    } catch (const PDH::PDHException e) { 
     1365      NSC_LOG_ERROR_STD(_T("ERROR: ") + e.getError()); 
     1366      if (bNSClient) 
     1367        msg = _T("0"); 
     1368      else 
     1369        msg = _T("ERROR: ") + e.getError(); 
     1370      return NSCAPI::returnUNKNOWN; 
     1371    } 
     1372  } 
     1373  BOOST_FOREACH(CounterContainer &counter, counters) { 
     1374    try { 
     1375      double value = 0; 
     1376      if (counter.data.find('\\') == std::wstring::npos) { 
     1377        PDHCollector *pObject = pdhThread.getThread(); 
     1378        if (!pObject) { 
     1379          msg = _T("ERROR: PDH Collection thread not running."); 
     1380          return NSCAPI::returnUNKNOWN; 
    13221381        } 
    1323         pdh.gatherData(); 
    1324         pdh.close(); 
    1325         value = cDouble->getValue(); 
    1326       } 
    1327  
     1382        value = pObject->get_double(counter.data); 
     1383        if (value == -1) { 
     1384          msg = _T("ERROR: Failed to get counter value: ") + counter.data; 
     1385          return NSCAPI::returnUNKNOWN; 
     1386        } 
     1387      } else { 
     1388        value = counter.get_listener()->getValue(); 
     1389      } 
    13281390 
    13291391      if (bNSClient) { 
     
    17521814NSC_WRAPPERS_IGNORE_MSG_DEF(); 
    17531815NSC_WRAPPERS_HANDLE_CMD_DEF(); 
    1754 //NSC_WRAPPERS_CLI_DEF(gCheckSystem); 
    1755  
     1816NSC_WRAPPERS_CLI_DEF(); 
  • modules/CheckSystem/CheckSystem.def

    r291548e r523576e  
    1313  NSUnloadModule 
    1414  NSGetModuleDescription 
     15  NSCommandLineExec 
    1516  NSDeleteBuffer 
  • modules/CheckSystem/CheckSystem.h

    ra14aa07 r523576e  
    2828NSC_WRAPPERS_CLI(); 
    2929 
    30 class CheckSystem : public nscapi::impl::simple_command_handler, public nscapi::impl::simple_plugin { 
     30class CheckSystem : public nscapi::impl::simple_command_handler, public nscapi::impl::simple_plugin, public nscapi::impl::simple_command_line_exec { 
    3131private: 
    3232  CheckMemory memoryChecker; 
     
    7777  bool hasMessageHandler(); 
    7878  NSCAPI::nagiosReturn handleCommand(const std::wstring &target, const std::wstring &command, std::list<std::wstring> &arguments, std::wstring &message, std::wstring &perf); 
    79   int commandLineExec(const wchar_t* command,const unsigned int argLen,wchar_t** args); 
     79  NSCAPI::nagiosReturn commandLineExec(const std::wstring &command, std::list<std::wstring> &arguments, std::wstring &result); 
    8080 
    8181  NSCAPI::nagiosReturn checkCPU(std::list<std::wstring> arguments, std::wstring &msg, std::wstring &perf); 
  • modules/FileLogger/FileLogger.cpp

    r8013c0c r523576e  
    2727 
    2828#include <boost/date_time.hpp> 
     29#include <boost/filesystem.hpp> 
    2930 
    3031#include "FileLogger.h" 
     
    3435#include <settings/client/settings_client.hpp> 
    3536#include <settings/macros.h> 
     37#include <protobuf/plugin.pb.h> 
    3638 
    3739namespace sh = nscapi::settings_helper; 
     
    4042} 
    4143FileLogger::~FileLogger() { 
    42 } 
    43 namespace setting_keys { 
    44  
    45   namespace log { 
    46     DEFINE_PATH(SECTION, LOG_SECTION); 
    47     //DESCRIBE_SETTING_ADVANCED(SECTION, "LOG SECTION", "Configure loggning properties."); 
    48  
    49     DEFINE_SETTING_S(FILENAME, LOG_SECTION, "file", "nsclient.log"); 
    50     //DESCRIBE_SETTING_ADVANCED(FILENAME, "SYNTAX", "The file to write log data to. If no directory is used this is relative to the NSClient++ binary."); 
    51  
    52     DEFINE_SETTING_S(ROOT, LOG_SECTION, "root", "auto"); 
    53     //DESCRIBE_SETTING_ADVANCED(ROOT, "TODO", "TODO"); 
    54  
    55     DEFINE_SETTING_S(DATEMASK, LOG_SECTION, "date format", "%Y-%m-%d %H:%M:%S"); 
    56     //DESCRIBE_SETTING_ADVANCED(DATEMASK, "DATEMASK", "The date format used when logging to a file."); 
    57  
    58     DEFINE_SETTING_S(LOG_MASK, LOG_SECTION, "log mask", "normal"); 
    59     //DESCRIBE_SETTING_ADVANCED(LOG_MASK, "LOG MASK", "The log mask information, error, warning, critical, debug"); 
    60  
    61     DEFINE_SETTING_B(DEBUG_LOG, LOG_SECTION, "debug", false); 
    62     //DESCRIBE_SETTING_ADVANCED(DEBUG_LOG, "DEBUG LOGGING", "Enable debug logging can help track down errors and find problems but will impact overall perfoamnce negativly."); 
    63   } 
    6444} 
    6545 
     
    10181    file_ = utf8::cvt<std::string>(cfg_file_); 
    10282    if (file_.empty()) 
    103       file_ = utf8::cvt<std::string>(setting_keys::log::FILENAME_DEFAULT); 
     83      file_ = "nsclient.log"; 
    10484    if (file_.find("\\") == std::wstring::npos) { 
    10585      std::string root = utf8::cvt<std::string>(getFolder(cfg_root_)); 
     
    123103 
    124104    sh::settings_registry settings(get_settings_proxy()); 
    125     settings.set_alias(_T("log"), alias); 
     105    settings.set_alias(_T("file logger"), alias); 
    126106 
    127107    settings.alias().add_path_to_settings() 
     
    129109      ; 
    130110 
    131     settings.alias().add_key_to_settings() 
    132       //(_T("debug"), sh::bool_key(&debug_, false), 
    133       //_T("DEBUG LOGGING"), _T("Enable debug logging can help track down errors and find problems but will impact overall performance negativly.")) 
    134  
    135       (_T("log mask"), sh::wstring_key(&log_mask, _T("false")), 
    136       _T("LOG MASK"), _T("The log mask information, error, warning, critical, debug")) 
     111    settings.alias().add_parent(_T("/settings/log")).add_key_to_settings() 
     112      (_T("level"), sh::wstring_key(&log_mask, _T("info")), 
     113      _T("LOG LEVEL"), _T("The log level info, error, warning, critical, debug")) 
    137114 
    138115      (_T("root"), sh::wstring_key(&cfg_root_, _T("auto")), 
     
    144121      (_T("date format"), sh::string_key(&format_, "%Y-%m-%d %H:%M:%S"), 
    145122      _T("DATEMASK"), _T("The size of the buffer to use when getting messages this affects the speed and maximum size of messages you can recieve.")) 
     123 
     124      (_T("max size"), sh::int_key(&max_size_, 0), 
     125      _T("MAXIMUM FILE SIZE"), _T("When file size reaches this it will be truncated to 50% if set to 0 (default) truncation will be disabled")) 
    146126      ; 
    147127 
     
    166146  init_ = true; 
    167147  std::string hello = "Starting to log for: " + utf8::cvt<std::string>(GET_CORE()->getApplicationName()) + " - " + utf8::cvt<std::string>(GET_CORE()->getApplicationVersionString()); 
    168   handleMessage(NSCAPI::log_level::log, __FILE__, __LINE__, hello); 
    169   handleMessage(NSCAPI::log_level::log, __FILE__, __LINE__, "Log path is: " + file_); 
     148  log(NSCAPI::log_level::log, __FILE__, __LINE__, hello); 
    170149  return true; 
    171150} 
     
    202181*/ 
    203182 
    204 void FileLogger::handleMessage(int msgType, const std::string file, int line, std::string message) { 
     183void FileLogger::handleMessageRAW(std::string data) { 
     184  try { 
     185    Plugin::LogEntry message; 
     186    message.ParseFromString(data); 
     187 
     188    for (int i=0;i<message.entry_size();i++) { 
     189      Plugin::LogEntry::Entry msg = message.entry(i); 
     190      log(msg.level(), msg.file(), msg.line(), msg.message()); 
     191    } 
     192  } catch (std::exception &e) { 
     193    std::cout << "Failed to parse data from: " << strEx::strip_hex(data) << e.what() <<  std::endl;; 
     194  } catch (...) { 
     195    std::cout << "Failed to parse data from: " << strEx::strip_hex(data) << std::endl;; 
     196  } 
     197} 
     198void FileLogger::log(int msgType, const std::string file, int line, std::string message) { 
    205199  if (!init_) { 
    206200    std::wcout << _T("Discarding: ") << utf8::cvt<std::wstring>(message) << std::endl; 
     
    210204    return; 
    211205 
     206  if (max_size_ != 0 &&  boost::filesystem::exists(file_.c_str()) && boost::filesystem::file_size(file_.c_str()) > max_size_) { 
     207    int target_size = max_size_*0.7; 
     208    char *tmpBuffer = new char[target_size+1]; 
     209    try { 
     210      std::ifstream ifs(file_.c_str()); 
     211      ifs.seekg(-target_size, std::ios_base::end);  // One call to find it. . . 
     212      ifs.read(tmpBuffer, target_size); 
     213      ifs.close(); 
     214      std::ofstream ofs(file_.c_str(), std::ios::trunc); 
     215      ofs.write(tmpBuffer, target_size); 
     216    } catch (...) { 
     217      std::cout << "Failed to truncate log file: " << file_ << std::endl;; 
     218    } 
     219    delete [] tmpBuffer; 
     220  } 
    212221  std::ofstream stream(file_.c_str(), std::ios::out|std::ios::app|std::ios::ate); 
    213222  if (!stream) { 
  • modules/FileLogger/FileLogger.h

    r81e420c r523576e  
    2525NSC_WRAPPERS_MAIN(); 
    2626 
    27 class FileLogger : public nscapi::impl::simple_plugin, public nscapi::impl::simple_log_handler { 
     27class FileLogger : public nscapi::impl::simple_plugin { 
    2828private: 
    2929  std::string file_; 
     
    3333  std::wstring cfg_file_; 
    3434  std::wstring cfg_root_; 
     35  int max_size_; 
    3536 
    3637public: 
     
    5758  bool hasCommandHandler(); 
    5859  bool hasMessageHandler(); 
    59   void handleMessage(int msgType, const std::string file, int line, std::string message); 
     60  void handleMessageRAW(std::string data); 
     61  void log(int msgType, const std::string file, int line, std::string message); 
    6062  int handleCommand(wchar_t* command, wchar_t **argument, wchar_t *returnBuffer, int returnBufferLen); 
    6163  //void writeEntry(std::wstring line); 
  • modules/NSCAClient/NSCAClient.cpp

    r0f7b655 r523576e  
    100100    if (hostname_ == "auto") { 
    101101      hostname_ = boost::asio::ip::host_name(); 
     102    } else { 
     103      std::pair<std::string,std::string> dn = strEx::split<std::string>(boost::asio::ip::host_name(), "."); 
     104 
     105      try { 
     106        boost::asio::io_service svc; 
     107        boost::asio::ip::tcp::resolver resolver (svc); 
     108        boost::asio::ip::tcp::resolver::query query (boost::asio::ip::host_name(), ""); 
     109        boost::asio::ip::tcp::resolver::iterator iter = resolver.resolve (query), end; 
     110 
     111        std::string s; 
     112        while (iter != end) { 
     113          s += iter->host_name(); 
     114          s += " - "; 
     115          s += iter->endpoint().address().to_string(); 
     116          iter++; 
     117        } 
     118      } catch (exception& e) { 
     119        cerr << "Error: " << e.what() << endl; 
     120      } 
     121 
     122 
     123      strEx::replace(hostname_, "${host}", dn.first); 
     124      strEx::replace(hostname_, "${domain}", dn.second); 
    102125    } 
    103126  } catch (nscapi::nscapi_exception &e) { 
  • modules/Scheduler/Scheduler.cpp

    r76540c3 r523576e  
    130130      std::string result; 
    131131      get_core()->submit_message(item.channel, response, result); 
     132    } else { 
     133      NSC_DEBUG_MSG(_T("Filter not matched for: ") + item.alias + _T(" so nothing is reported")); 
    132134    } 
    133135  } catch (nscapi::nscapi_exception &e) { 
  • modules/Scheduler/schedules.hpp

    r76540c3 r523576e  
    110110    static void read_object(boost::shared_ptr<nscapi::settings_proxy> proxy, object_type &object) { 
    111111      object.set_command(object.value); 
    112       if (object.alias == _T("default")) 
     112      if (object.alias == _T("default")) { 
    113113        object.set_duration(_T("5m")); 
     114        object.set_report(_T("all")); 
     115      } 
    114116 
    115117      nscapi::settings_helper::settings_registry settings(proxy); 
  • scripts/python/test_w32_system.py

    r0f7b655 r523576e  
     1from NSCP import Settings, Registry, Core, log, status, log_error, sleep 
    12from NSCP import Settings, Registry, Core, log, status, log_error, sleep 
    23from test_helper import BasicTest, TestResult, Callable, setup_singleton, install_testcases, init_testcases, shutdown_testcases 
    34from types import * 
     5import random 
    46import subprocess 
    57 
     
    4749    return result 
    4850     
    49   def test_one_proc(self): 
     51  def run_test_proc(self): 
    5052    result = TestResult('Checking CheckProcState') 
    5153     
     
    6769    return result 
    6870     
     71  def run_test_counters(self): 
     72    result = TestResult('Checking CheckCounter') 
     73    (result_code, result_message) = core.simple_exec('any', 'listpdh', ['--porcelain']) 
     74    count = 0 
     75    data = [] 
     76    for m in result_message: 
     77      data = m.splitlines() 
     78      count = len(data) 
     79    result.add_message(count > 0, 'Managed to retrieve counters: %d'%count) 
     80       
     81    counters = [] 
     82    for x in range(1,10): 
     83      str = random.choice(data) 
     84      lst = str.split(',') 
     85      found = True 
     86      if len(lst) == 4: 
     87        counter = '\\%s(%s)\\%s'%(lst[1], lst[2], lst[3]) 
     88      elif len(lst) == 3: 
     89        counter = '\\%s\\%s'%(lst[1], lst[2]) 
     90      else: 
     91        result.add_message(False, 'Invalid counter found: %s'%lst) 
     92        found = False 
     93      if found: 
     94        (retcode, retmessage, retperf) = core.simple_query('CheckCounter', ['ShowAll', 'MaxWarn=10', 'Counter:001=%s'%counter]) 
     95        result.add_message(retcode != status.UNKNOWN, 'Queried normal: %s'%counter) 
     96        result.add_message(len(retmessage) > 0, 'Queried normal (got message): %s'%retmessage) 
     97        result.add_message(len(retperf) > 0, 'Queried normal (got perf): %s'%retperf) 
     98        if retcode != status.UNKNOWN: 
     99          counters.append('Counter:%d=%s'%(x, counter)) 
     100         
     101    args = ['ShowAll', 'MaxWarn=10'] 
     102    args.extend(counters) 
     103    (retcode, retmessage, retperf) = core.simple_query('CheckCounter', args) 
     104    result.add_message(retcode != status.UNKNOWN, 'Queried normal list of %d counters'%len(counters)) 
     105    result.add_message(len(retmessage) > 0, 'Queried normal (got message): %s'%retmessage) 
     106    result.add_message(len(retperf) > 0, 'Queried normal (got perf): %s'%retperf) 
     107    result.add_message(len(counters) == len(retperf.split(' ')), 'Got all responses: %d'%len(counters)) 
     108    return result 
     109     
    69110  def run_test(self): 
    70     result = TestResult('Testing process checks on windows 32 bit systems') 
    71     result.extend(self.test_one_proc()) 
     111    result = TestResult('Testing W32 systems') 
     112    #result.add(self.run_test_proc()) 
     113    result.add(self.run_test_counters()) 
    72114    return result 
    73115 
  • service/NSClient++.cpp

    re396b2f r523576e  
    954954 
    955955NSCAPI::errorReturn NSClientT::reload(const std::wstring module) { 
    956   if (module == _T("service")) { 
     956  if (module == _T("settings")) { 
     957    try { 
     958      settings_manager::get_settings()->clear_cache(); 
     959      return NSCAPI::isSuccess; 
     960    } catch(const std::exception &e) { 
     961      LOG_ERROR_CORE_STD(_T("Exception raised when reloading: ") + utf8::to_unicode(e.what())); 
     962    } catch(...) { 
     963      LOG_ERROR_CORE_STD(_T("Exception raised when reloading: UNKNOWN")); 
     964    } 
     965  } else if (module == _T("service")) { 
    957966    try { 
    958967      stop_unload_plugins_pre(); 
  • service/cli_parser.hpp

    rc5ec0c8 r523576e  
    1414  po::options_description client; 
    1515  po::options_description common; 
     16  po::options_description unittest; 
    1617 
    1718  bool help; 
     
    2829    , service("Service Options") 
    2930    , client("Client Options") 
     31    , unittest("Unittest Options") 
    3032    , help(false) 
    3133    , version(false) 
     
    3335    root.add_options() 
    3436      ("help", po::bool_switch(&help), "produce help message") 
    35       /* 
    36       ("settings-help", "Produce help message for the various settings related options") 
    37       ("service-help", "Produce help message for the various settings related service management") 
    38       ("client-help", "Produce help message for the various settings related client") 
    39       ("test-help", "Produce help message for the various settings related client") 
    40       */ 
    41 /* 
    42       ("settings", "Enter settings mode and handle settings related commands") 
    43       ("service", "Enter service mode and handle service related commands") 
    44       ("client", "Enter client mode and handle client related commands") 
    45       ("test", "Start test and debug mode") 
    46       */ 
    4737      ("version", po::bool_switch(&version), "Show version information") 
    4838      ; 
     
    8878      ("raw-argument", po::wvalue<std::vector<std::wstring> >(), "List of arguments (does not get -- prefixed)") 
    8979      ; 
     80    unittest.add_options() 
     81      ("language,l", po::value<std::wstring>()->implicit_value(_T("")), "Language tests are written in") 
     82      ("argument,a", po::wvalue<std::vector<std::wstring> >(), "List of arguments (gets -- prefixed automatically)") 
     83      ("raw-argument", po::wvalue<std::vector<std::wstring> >(), "List of arguments (does not get -- prefixed)") 
     84      ; 
    9085 
    9186  } 
     
    120115    handlers["test"] = boost::bind(&cli_parser::parse_test, this, _1, _2); 
    121116    handlers["help"] = boost::bind(&cli_parser::parse_help, this, _1, _2); 
     117    handlers["unit"] = boost::bind(&cli_parser::parse_unittest, this, _1, _2); 
    122118    return handlers; 
    123119  } 
     
    340336  } 
    341337 
    342   int parse_client(int argc, wchar_t* argv[], std::wstring module = _T("")) { 
    343     try { 
    344       po::options_description all("Allowed options (client)"); 
    345       all.add(common).add(client); 
    346  
    347       po::positional_options_description p; 
    348       p.add("arguments", -1); 
    349  
    350       po::variables_map vm; 
    351       po::wparsed_options parsed =  
    352         po::wcommand_line_parser(argc, argv).options(all).allow_unregistered().run(); 
    353       po::store(parsed, vm); 
    354       po::notify(vm); 
    355  
    356       if (process_common_options("client", all)) 
    357         return 1; 
    358  
    359       std::wstring command, combined_query; 
    360       enum modes { exec, query, submit, none, combined}; 
    361       modes mode = none; 
    362  
    363       if (vm.count("exec")) { 
    364         command = vm["exec"].as<std::wstring>(); 
    365         mode = exec; 
    366         if (vm.count("query")) { 
    367           combined_query = vm["query"].as<std::wstring>(); 
    368           mode = combined; 
    369         } 
    370       } else if (vm.count("query")) { 
    371         command = vm["query"].as<std::wstring>(); 
    372         mode = query; 
    373       } else if (vm.count("submit")) { 
    374         command = vm["submit"].as<std::wstring>(); 
    375         mode = submit; 
    376       } 
    377  
    378       if (vm.count("module")) 
    379         module = vm["module"].as<std::wstring>(); 
    380  
    381       bool boot = false; 
    382       if (vm.count("boot")) 
    383         boot = true; 
    384  
    385       std::vector<std::wstring> kvp_args; 
    386       if (vm.count("argument")) 
    387         kvp_args = vm["argument"].as<std::vector<std::wstring> >(); 
    388  
    389       std::vector<std::wstring> arguments = po::collect_unrecognized(parsed.options, po::include_positional); 
    390  
    391       BOOST_FOREACH(std::wstring s, kvp_args) { 
    392         std::wstring::size_type pos = s.find(L'='); 
    393         if (pos == std::wstring::npos) 
    394           arguments.push_back(_T("--") + s); 
    395         else { 
    396           arguments.push_back(_T("--") + s.substr(0,pos)); 
    397           arguments.push_back(s.substr(pos+1)); 
    398         } 
    399       } 
    400  
    401       if (vm.count("raw-argument")) 
    402         kvp_args = vm["raw-argument"].as<std::vector<std::wstring> >(); 
    403       BOOST_FOREACH(std::wstring s, kvp_args) { 
    404         std::wstring::size_type pos = s.find(L'='); 
    405         if (pos == std::wstring::npos) 
    406           arguments.push_back(s); 
    407         else { 
    408           arguments.push_back(s.substr(0,pos)); 
    409           arguments.push_back(s.substr(pos+1)); 
    410         } 
    411       } 
    412  
     338  struct client_arguments { 
     339    std::wstring command, combined_query, module; 
     340    std::vector<std::wstring> arguments; 
     341    enum modes { exec, query, submit, none, combined}; 
     342    modes mode; 
     343    bool boot; 
     344    client_arguments() : mode(none), boot(false) {} 
     345 
     346    void debug() { 
    413347      if (mainClient.should_log(NSCAPI::log_level::debug)) { 
    414348        mainClient.log_info(__FILE__, __LINE__, _T("Module: ") + module); 
    415349        mainClient.log_info(__FILE__, __LINE__, _T("Command: ") + command); 
     350        mainClient.log_info(__FILE__, __LINE__, _T("Extra Query: ") + combined_query); 
    416351        mainClient.log_info(__FILE__, __LINE__, _T("Mode: ") + strEx::itos(mode)); 
    417352        mainClient.log_info(__FILE__, __LINE__, _T("Boot: ") + strEx::itos(boot)); 
     
    424359      } 
    425360 
     361    } 
     362  }; 
     363  int parse_client(int argc, wchar_t* argv[], std::wstring module_ = _T("")) { 
     364    try { 
     365      client_arguments args; 
     366 
     367      args.module = module_; 
     368      po::options_description all("Allowed options (client)"); 
     369      all.add(common).add(client); 
     370 
     371      po::positional_options_description p; 
     372      p.add("arguments", -1); 
     373 
     374      po::variables_map vm; 
     375      po::wparsed_options parsed =  
     376        po::wcommand_line_parser(argc, argv).options(all).allow_unregistered().run(); 
     377      po::store(parsed, vm); 
     378      po::notify(vm); 
     379 
     380      if (process_common_options("client", all)) 
     381        return 1; 
     382 
     383 
     384      if (vm.count("exec")) { 
     385        args.command = vm["exec"].as<std::wstring>(); 
     386        args.mode = client_arguments::exec; 
     387        if (vm.count("query")) { 
     388          args.combined_query = vm["query"].as<std::wstring>(); 
     389          args.mode = client_arguments::combined; 
     390        } 
     391      } else if (vm.count("query")) { 
     392        args.command = vm["query"].as<std::wstring>(); 
     393        args.mode = client_arguments::query; 
     394      } else if (vm.count("submit")) { 
     395        args.command = vm["submit"].as<std::wstring>(); 
     396        args.mode = client_arguments::submit; 
     397      } 
     398 
     399      if (vm.count("module")) 
     400        args.module = vm["module"].as<std::wstring>(); 
     401 
     402      if (vm.count("boot")) 
     403        args.boot = true; 
     404 
     405      std::vector<std::wstring> kvp_args; 
     406      if (vm.count("argument")) 
     407        kvp_args = vm["argument"].as<std::vector<std::wstring> >(); 
     408 
     409      args.arguments = po::collect_unrecognized(parsed.options, po::include_positional); 
     410 
     411      BOOST_FOREACH(std::wstring s, kvp_args) { 
     412        std::wstring::size_type pos = s.find(L'='); 
     413        if (pos == std::wstring::npos) 
     414          args.arguments.push_back(_T("--") + s); 
     415        else { 
     416          args.arguments.push_back(_T("--") + s.substr(0,pos)); 
     417          args.arguments.push_back(s.substr(pos+1)); 
     418        } 
     419      } 
     420 
     421      if (vm.count("raw-argument")) 
     422        kvp_args = vm["raw-argument"].as<std::vector<std::wstring> >(); 
     423      BOOST_FOREACH(std::wstring s, kvp_args) { 
     424        std::wstring::size_type pos = s.find(L'='); 
     425        if (pos == std::wstring::npos) 
     426          args.arguments.push_back(s); 
     427        else { 
     428          args.arguments.push_back(s.substr(0,pos)); 
     429          args.arguments.push_back(s.substr(pos+1)); 
     430        } 
     431      } 
     432      return exec_client_mode(args); 
     433    } catch(const std::exception & e) { 
     434      std::wcerr << _T("Client: Unable to parse command line: ") << utf8::to_unicode(e.what()) << std::endl; 
     435      return 1; 
     436    } catch(...) { 
     437      std::wcerr << _T("Client: Unable to parse command line: UNKNOWN") << std::endl; 
     438      return 1; 
     439    } 
     440  } 
     441 
     442  int parse_unittest(int argc, wchar_t* argv[]) { 
     443    try { 
     444      client_arguments args; 
     445      settings_store = _T("dummy"); 
     446      po::options_description all("Allowed options (client)"); 
     447      all.add(common).add(unittest); 
     448 
     449      po::positional_options_description p; 
     450      p.add("arguments", -1); 
     451 
     452      po::variables_map vm; 
     453      po::wparsed_options parsed =  
     454        po::wcommand_line_parser(argc, argv).options(all).allow_unregistered().run(); 
     455      po::store(parsed, vm); 
     456      po::notify(vm); 
     457 
     458      if (process_common_options("unitest", all)) 
     459        return 1; 
     460 
     461 
     462      if (vm.count("language")) { 
     463        std::wstring lang = vm["language"].as<std::wstring>(); 
     464        if (lang == _T("python") || lang == _T("py")) { 
     465          args.command = _T("python-script"); 
     466          args.combined_query = _T("py_unittest"); 
     467          args.mode = client_arguments::combined; 
     468          args.module = _T("PythonScript"); 
     469        } else { 
     470          std::wcerr << _T("Unknown language: ") << lang << std::endl; 
     471          return 1; 
     472        } 
     473      } else { 
     474        args.command = _T("python-script"); 
     475        args.combined_query = _T("py_unittest"); 
     476        args.mode = client_arguments::combined; 
     477        args.module = _T("PythonScript"); 
     478      } 
     479 
     480      std::vector<std::wstring> kvp_args; 
     481      if (vm.count("argument")) 
     482        kvp_args = vm["argument"].as<std::vector<std::wstring> >(); 
     483 
     484      args.arguments = po::collect_unrecognized(parsed.options, po::include_positional); 
     485 
     486      BOOST_FOREACH(std::wstring s, kvp_args) { 
     487        std::wstring::size_type pos = s.find(L'='); 
     488        if (pos == std::wstring::npos) 
     489          args.arguments.push_back(_T("--") + s); 
     490        else { 
     491          args.arguments.push_back(_T("--") + s.substr(0,pos)); 
     492          args.arguments.push_back(s.substr(pos+1)); 
     493        } 
     494      } 
     495 
     496      if (vm.count("raw-argument")) 
     497        kvp_args = vm["raw-argument"].as<std::vector<std::wstring> >(); 
     498      BOOST_FOREACH(std::wstring s, kvp_args) { 
     499        std::wstring::size_type pos = s.find(L'='); 
     500        if (pos == std::wstring::npos) 
     501          args.arguments.push_back(s); 
     502        else { 
     503          args.arguments.push_back(s.substr(0,pos)); 
     504          args.arguments.push_back(s.substr(pos+1)); 
     505        } 
     506      } 
     507      return exec_client_mode(args); 
     508    } catch(const std::exception & e) { 
     509      std::wcerr << _T("Client: Unable to parse command line: ") << utf8::to_unicode(e.what()) << std::endl; 
     510      return 1; 
     511    } catch(...) { 
     512      std::wcerr << _T("Client: Unable to parse command line: UNKNOWN") << std::endl; 
     513      return 1; 
     514    } 
     515  } 
     516 
     517  int exec_client_mode(client_arguments &args) { 
     518    try { 
     519      args.debug(); 
     520 
    426521      core_->boot_init(); 
    427       if (module.empty()) 
     522      if (args.module.empty()) 
    428523        core_->boot_load_all_plugins(); 
    429524      else 
    430         core_->boot_load_plugin(module); 
    431       core_->boot_start_plugins(boot); 
     525        core_->boot_load_plugin(args.module); 
     526      core_->boot_start_plugins(args.boot); 
    432527      int ret = 0; 
    433528      std::list<std::wstring> resp; 
    434       if (mode == none) { 
    435         mode = exec; 
     529      if (args.mode == client_arguments::none) { 
     530        args.mode = client_arguments::exec; 
    436531        std::wcerr << _T("Since no mode was specified assuming --exec (other options are --query and --submit)") << std::endl; 
    437532      } 
    438       if (mode == query) { 
    439         ret = mainClient.simple_query(module, command, arguments, resp); 
    440       } else if (mode == exec || mode == combined) { 
    441         ret = mainClient.simple_exec(module, command, arguments, resp); 
     533      if (args.mode == client_arguments::query) { 
     534        ret = mainClient.simple_query(args.module, args.command, args.arguments, resp); 
     535      } else if (args.mode == client_arguments::exec || args.mode == client_arguments::combined) { 
     536        ret = mainClient.simple_exec(args.module, args.command, args.arguments, resp); 
    442537        if (ret == NSCAPI::returnIgnored) { 
    443538          ret = 1; 
    444           std::wcout << _T("Command not found (by module): ") << command << std::endl; 
    445           resp.push_back(_T("Command not found: ") + command); 
    446           mainClient.simple_exec(module, _T("help"), arguments, resp); 
    447         } else if (mode == combined) { 
     539          std::wcout << _T("Command not found (by module): ") << args.command << std::endl; 
     540          resp.push_back(_T("Command not found: ") + args.command); 
     541          mainClient.simple_exec(args.module, _T("help"), args.arguments, resp); 
     542        } else if (args.mode == client_arguments::combined) { 
    448543          if (ret == NSCAPI::returnOK) { 
    449544            mainClient.reload(_T("service")); 
    450             ret = mainClient.simple_query(module, combined_query, arguments, resp); 
     545            ret = mainClient.simple_query(args.module, args.combined_query, args.arguments, resp); 
    451546          } else { 
    452547            std::wcerr << _T("Failed to execute command, will not attempt query") << std::endl; 
    453548          } 
    454549        } 
    455       } else if (mode == submit) { 
     550      } else if (args.mode == client_arguments::submit) { 
    456551        std::wcerr << _T("--submit is currently not supported (but you can use --exec submit which is technically the same)") << std::endl; 
    457552      } else { 
  • service/logger.hpp

    r8013c0c r523576e  
    5151        msg->set_line(line); 
    5252        msg->set_message(utf8::cvt<std::string>(logMessage)); 
    53         if (!message.SerializeToString(&str)) { 
    54           return "Failed to generate message"; 
    55         } 
    56         return str; 
     53        return message.SerializeAsString(); 
    5754      } catch (std::exception &e) { 
    58         return std::string("Failed to generate message: ") + e.what(); 
     55        std::cout << "Failed to generate message: " << e.what() << std::endl;; 
    5956      } catch (...) { 
    60         return "Failed to generate message"; 
    61       } 
    62 //      return to_string(logMessage); 
     57        std::cout << "Failed to generate message: " << std::endl;; 
     58      } 
     59      return ""; 
    6360    } 
    6461  }; 
     
    8683 
    8784    public: 
    88       slave() : mq_(ip::open_only,queue_name.c_str()), plugins_loaded_(false), console_log_(false) { 
    89 #ifdef WIN32 
    90 //        if(!SetConsoleOutputCP(CP_UTF8)) { // 65001 
    91 //          std::cerr << "Failed to set console output mode!\n"; 
    92 //        } 
    93 #endif 
    94       } 
     85      slave() : mq_(ip::open_only,queue_name.c_str()), plugins_loaded_(false), console_log_(false) {} 
    9586 
    9687      void add_plugin(plugin_type plugin) { 
     
    206197 
    207198#ifdef WIN32 
    208           s += _T("\n"); 
     199          //s += _T("\n"); 
     200          std::wcout << s << std::endl; 
     201          /* 
    209202          HANDLE const consout = GetStdHandle(STD_OUTPUT_HANDLE); 
    210203          DWORD nNumberOfCharsWritten; 
     
    213206            cerr << "WriteConsole failed with << " << err << "!\n"; 
    214207          } 
     208          */ 
    215209#else 
    216210          std::wcout << s << std::endl; 
     
    310304      } 
    311305 
     306      void truncate_entries(Plugin::LogEntry &message) { 
     307        if (message.entry_size() == 1) 
     308          return; 
     309        Plugin::LogEntry::Entry e = message.entry(0); 
     310        message.clear_entry(); 
     311        message.add_entry()->CopyFrom(e); 
     312        //message.mutable_entry()->add(e); 
     313      } 
     314 
     315      void truncate_string(Plugin::LogEntry &message) { 
     316        if (message.entry_size() == 0) 
     317          return; 
     318        std::string str = message.mutable_entry(0)->message(); 
     319        if (str.size() > max_message_size*0.7) 
     320          str = str.substr(0, max_message_size*0.7); 
     321        message.mutable_entry(0)->set_message("TRUNCATED(" + str + "...)"); 
     322      } 
     323 
    312324      void log(std::string data) { 
    313325        if (!mq_) { 
     
    316328        } 
    317329        if (data.size() >= max_message_size) { 
    318           log_fatal_error("Message to large to fit buffer: " + to_string(data.size()) + " > " + to_string(max_message_size)); 
    319           return; 
     330          Plugin::LogEntry message; 
     331          message.ParseFromString(data); 
     332          truncate_entries(message); 
     333          data = message.SerializeAsString(); 
     334          if (data.size() >= max_message_size) { 
     335            truncate_string(message); 
     336            data = message.SerializeAsString(); 
     337          } 
     338          if (data.size() >= max_message_size) { 
     339            log_fatal_error("Message to large to fit buffer: " + to_string(data.size()) + " > " + to_string(max_message_size)); 
     340            return; 
     341          } 
     342          data = message.SerializeAsString(); 
    320343        } 
    321344        try { 
     
    330353        OutputDebugString(strEx::string_to_wstring(message).c_str()); 
    331354#endif 
    332         std::cout << "TODO: " << message << std::endl; 
     355        std::cout << "FATAL ERROR: " << message << std::endl; 
    333356      } 
    334357 
  • version.hpp

    r2906cda r523576e  
    11#ifndef VERSION_HPP 
    22#define VERSION_HPP 
    3 #define PRODUCTVER     0,4,0,134 
    4 #define STRPRODUCTVER  "0,4,0,134" 
    5 #define STRPRODUCTDATE "2012-02-13" 
     3#define PRODUCTVER     0,4,0,135 
     4#define STRPRODUCTVER  "0,4,0,135" 
     5#define STRPRODUCTDATE "2012-02-19" 
    66#endif // VERSION_HPP 
  • version.txt

    r2906cda r523576e  
    11version=0.4.0 
    2 build=134 
    3 date=2012-02-13 
     2build=135 
     3date=2012-02-19 
Note: See TracChangeset for help on using the changeset viewer.