00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include <core/SystemMonitor.h>
00037 #include <core/ObjectFactory.h>
00038 #include <core/PersistenceManager.h>
00039 #include <core/SecurityManager.h>
00040 #include <core/WoshKernel.h>
00041 #include <core/SharedMemory.h>
00042 #include <core/MethodsCommon.h>
00043 #include <core/FilePath.h>
00044 #include <core/Utilities.h>
00045 #include <core/DateTime.h>
00046 #include <core/DataSet.h>
00047
00048
00049
00050 #ifdef _OS_POSIX
00051 # include <core/posix/processes.h>
00052 # include <core/posix/desktop.h>
00053 #elif _OS_WIN32
00054 # include <core/win32/processes.h>
00055 # include <core/win32/desktop.h>
00056 #elif _OS_WINCE
00057 # include <core/wince/processes.h>
00058 # include <core/wince/desktop.h>
00059 #else
00060 long getCurrentProcessPID() { return 0L; }
00061 bool getSystemUserName( std::string& ) { return false; }
00062 bool retrieveProcessInfo( long , std::map<std::string, std::string>& ) { return false; }
00063 #endif
00064
00065
00066
00067 using namespace std;
00068 namespace wosh {
00069
00070
00071
00072
00073
00074 extern "C" {
00075 SystemMonitor* SystemMonitor::getInstance() {
00076 if ( WoshKernel::getInstance() == NULL ) return NULL;
00077 return &WoshKernel::getInstance()->monitor();
00078 }
00079 };
00080
00081
00082 WOSH_REGISTER_INTERFACE(wosh::SystemMonitor, wosh::WoshModule, _SystemMonitor_VER, core_SystemMonitor)
00083
00084
00085
00086
00087 SystemMonitor::SystemMonitor( const WoshKernel* parent )
00088 : WoshModule(parent, _SystemMonitor_NAME, _SystemMonitor_URI) {
00089
00090
00091
00092 #ifdef _ENABLE_PROFILING
00093 Log(LOG_INFO, " Acquiring SystemProfiler instance.. [_ENABLE_PROFILING]" );
00094 this->profiler = &SystemProfiler::getInstance();
00095 #else
00096 Log(LOG_VERBOSE, " Profiling DISABLED." );
00097 #endif
00098
00099 Log(LOG_DEBUG, " Initializing Properties.." );
00100 Properties.set(_SystemMonitor_KEY_SaveOnExit, false, Permission(Permission::RW, Permission::Read, Permission::Read) );
00101 Properties.set(_SystemMonitor_KEY_ProcessPID, 0, Permission(Permission::Read) );
00102 Properties.set(_SystemMonitor_KEY_SystemUser, "", Permission(Permission::Read) );
00103 Properties.update( _KEY_Description, "Core-Module: Monitor System for failures and errors, provides functionalities for debugging" );
00104 Properties.update( _KEY_Version, _SystemMonitor_VER );
00105
00106 Log(LOG_DEBUG, " Registering Methods.." );
00107 MethodRequest* mmProfilesList = Methods.create<MethodRequest>( _SystemMonitor_METHOD_profiles, "list profiling info", Permission::R_XR_XR__() );
00108 mmProfilesList->setMethod( this, (MethodRequestPtr)&SystemMonitor::mmDoProfilesList );
00109
00110 MethodRequest* mmListDeprecated = Methods.create<MethodRequest>( _SystemMonitor_METHOD_deprecated, "list deprecated", Permission::R_XR_XR__() );
00111 mmListDeprecated->setMethod( this, (MethodRequestPtr)&SystemMonitor::mmDoListDeprecated );
00112
00113 MethodWRESULT* mmSaveErrors = Methods.create<MethodWRESULT>( _SystemMonitor_METHOD_save_errors, "save errors", Permission::R_XR_XR__() );
00114 mmSaveErrors->setMethod( this, (MethodWRESULTPtr)&SystemMonitor::mmDoSaveErrors );
00115
00116 MethodWRESULT* mmCleanErrors = Methods.create<MethodWRESULT>( _SystemMonitor_METHOD_clear_errors, "clean errors", Permission::R_XR_XR__() );
00117 mmCleanErrors->setMethod( this, (MethodWRESULTPtr)&SystemMonitor::mmDoCleanErrors );
00118
00119 MethodWRESULT* mmUpdateSysInfo = Methods.create<MethodWRESULT>( _SystemMonitor_METHOD_update_sysinfo, "update sysinfo", Permission::R_XR_XR__() );
00120 mmUpdateSysInfo->setMethod( this, (MethodWRESULTPtr)&SystemMonitor::updateSystemInfo );
00121
00122 MethodDataSetFields* mmListErrors = Methods.create<MethodDataSetFields>( _METHOD_List, "List SystemInfo(s)", Permission::R_XR__R__() );
00123 mmListErrors->setRetriever( DataSetFieldsReader_X<SystemInfo>::createFrom(&this->infoCache) );
00124
00125 MethodRetrieve* mmRetrieveErrors = Methods.create<MethodRetrieve>( _METHOD_Retrieve, "Retrieve SystemInfo(s)", Permission::R_XR_XR__() );
00126 mmRetrieveErrors->setRetriever( DataSetRetriever_X<SystemInfo>::createFrom<int64>(&this->infoCache, &SystemInfo::getID ) );
00127
00128 MethodDataSetFields* mmListDSMs = Methods.create<MethodDataSetFields>( _SystemMonitor_METHOD_dsm, "List DSM", Permission::R_XR_XR__() );
00129 mmListDSMs->setRetriever( DataSetFieldsReader_X<SharedMemory>::createFrom(&SharedMemory::getInstances()) );
00130
00131 #ifdef _ENABLE_PROFILING
00132 this->profiler = &SystemProfiler::getInstance();
00133 #endif
00134 }
00135
00136 SystemMonitor::~SystemMonitor() {
00137 Log(LOG_DEBUG, ":~SystemMonitor() Destroying.." );
00138
00139
00140
00141 this->infoProxies.transactionBeginWrite();
00142 Log(LOG_DEBUG, ":~SecurityManager() Freeing InfoProxy [%d]..", this->infoProxies.size() );
00143 ObjectFactory::destroySequence(this->infoProxies);
00144 this->infoProxies.clear();
00145 this->infoProxies.transactionEnd();
00146
00147 Log(LOG_VERBOSE, ":~SecurityManager() Freeing Cache [%d]..", this->infoCache.size_safe() );
00148 this->infoCache.free_safe();
00149
00150 Log(LOG_VERBOSE, " Destroyed." );
00151 }
00152
00153
00154
00155
00156
00157 WRESULT SystemMonitor::onKernelInitializing() {
00158 WRESULT ret = WoshModule::onKernelInitializing();
00159
00160 long pid = getCurrentProcessPID();
00161 Properties.transactionBeginWrite();
00162 Properties.update(_SystemMonitor_KEY_ProcessPID, pid );
00163 Properties.transactionEnd();
00164 Log(LOG_INFO, "init() : PID updated to %ld", pid );
00165 ret += updateSystemInfo_(true, true);
00166
00167 return ret;
00168 }
00169
00170 WRESULT SystemMonitor::onKernelInitialized() {
00171 WRESULT ret = WoshModule::onKernelInitialized();
00172 if ( Properties.exists(_SystemMonitor_KEY_AutoLoadSystemInfoProxies) ) {
00173 vector<string> proxies;
00174 string proxiesStr = Properties.getValueOf(_SystemMonitor_KEY_AutoLoadSystemInfoProxies).toString();
00175 String::split(proxies, proxiesStr, _WoshSettings_SEPARATOR, _String_SPLIT_OPTION_NOT_EMPTY | _String_SPLIT_OPTION_TRIM | _String_SPLIT_OPTION_UNIQUE);
00176 Log(LOG_INFO, ":onKernelInitializing() Loading %d SystemInfoProxy", proxies.size() );
00177 WRESULT ret_c = WRET_OK;
00178 std::vector<std::string>::iterator it;
00179 for ( it=proxies.begin(); it!=proxies.end(); ++it ) {
00180 ret_c = installSystemInfoProxies(*it);
00181 ret += ret_c;
00182 }
00183 }
00184 return ret;
00185 }
00186
00187 WRESULT SystemMonitor::onKernelStopped() {
00188 WRESULT ret = WRET_OK;
00189 Variant saveMsg = this->Properties.getValueOf(_SystemMonitor_KEY_SaveOnExit);
00190 if ( !saveMsg.isEmpty() && saveMsg.toBoolean(true) ) {
00191 Log(LOG_INFO, "onKernelStopped() Saving Errors.." );
00192 ret += mmDoSaveErrors();
00193 }
00194 if ( WFAILED(ret) )
00195 Log(LOG_CRITICAL, ":onKernelStopped() ERROR#%d Saving Errors.", ret );
00196 ret = WoshModule::onKernelStopped();
00197 return ret;
00198 }
00199
00200
00201
00202
00203
00204 bool SystemMonitor::readingProperty( Property* property_curr, const PropertiesProvider* source ) {
00205 if ( property_curr != NULL && property_curr->getKey().find("SysInfo") == 0 )
00206 updateSystemInfo_(false, false);
00207 return WoshModule::readingProperty( property_curr, source );
00208 }
00209
00210
00211
00212
00213
00214 WRESULT SystemMonitor::updateSystemInfo_( bool lock_props, bool force_update ) {
00215 if ( !force_update ) {
00216 if ( DateTime::std_time_sec() - this->systemInfoTs < _SystemMonitor_SystemInfoMinRefresh )
00217 return WRET_ERR_ILLEGAL_USE;
00218 }
00219 this->systemInfoTs = DateTime::std_time_sec();
00220 Log(LOG_VERBOSE, "updateSystemInfo_(%d) Updating System Info..", lock_props );
00221
00222 string username;
00223 bool userOk = getSystemUserName(username);
00224 if ( !userOk ) {
00225 Log(LOG_CRITICAL, "updateSystemInfo_(%d) Error retrieving system user", lock_props );
00226 }
00227 long pid = getCurrentProcessPID();
00228
00229 Properties.transactionBeginWrite();
00230 Properties.update(_SystemMonitor_KEY_SystemUser, username);
00231 Properties.transactionEnd();
00232
00233 map<string, string> fields; Variant tmp;
00234 bool memInfo = retrieveProcessInfo( pid, fields );
00235 if ( memInfo ) {
00236 Properties.transactionBeginWrite();
00237 std::map<string, string>::const_iterator it;
00238 for ( it=fields.begin(); it!=fields.end(); ++it ) {
00239 tmp.fromString(it->second);
00240 Properties.update(it->first, tmp);
00241 }
00242 Properties.transactionEnd();
00243 }
00244 else {
00245 Log(LOG_CRITICAL, "updateSystemInfo_() ERRORS retrieving process info." );
00246 return WRET_ERR_INTERNAL;
00247 }
00248 return WRET_OK;
00249 }
00250
00251
00252
00253
00254 WRESULT SystemMonitor::mmDoSaveErrors() {
00255 FilePath xmlFile;
00256 xmlFile.set("$DATABASE/systemerrors.xml");
00257 Log(LOG_VERBOSE, ":mmDoSaveErrors() : Saving to %s", xmlFile.getPathLocal().c_str() );
00258 this->infoCache.transactionBeginRead();
00259 WRESULT ret = PersistenceManager::saveObjects( this->infoCache.getContainer(), "XML", xmlFile.getPathLocal() );
00260 this->infoCache.transactionEnd();
00261 return ret;
00262 }
00263
00264
00265
00266
00267
00268 void SystemMonitor::busMessage( const Message& message, const Bus* source ) {
00269 if ( message.isEmpty() ) return;
00270 WoshModule::busMessage( message, source );
00271 if ( message.getSourceUUID() == this->getEntityID() ) return;
00272 if ( message.getContent()->isSystemInfo() ) return;
00273 WRESULT valid;
00274 this->infoProxies.transactionBeginRead();
00275 tSystemInfoProxyList::ConstIterator it;
00276 const tSystemInfoProxyList::ConstIterator it_end = this->infoProxies.end();
00277 for( it=this->infoProxies.begin(); it!=it_end; ++it ) {
00278 if ( *it == NULL ) continue;
00279 valid = (*it)->validate(&message);
00280 if ( WFAILED(valid) ) continue;
00281
00282 SystemInfo* sysinfo = (*it)->transform(&message);
00283 if ( sysinfo == NULL ) continue;
00284 Log(LOG_INFO, ":busMessage() : Adding SystemInfo#%"PRId64, sysinfo->getID() );
00285 this->infoCache.push_back_safe( sysinfo );
00286 }
00287 this->infoProxies.transactionEnd();
00288
00289 return;
00290 }
00291
00292
00293
00294 WRESULT SystemMonitor::installSystemInfoProxy( SystemInfoProxy* systeminfo_proxy ) {
00295 if ( systeminfo_proxy == NULL )
00296 if ( this->infoProxies.push_back_safe( systeminfo_proxy ) ) {
00297 Log(LOG_WARNING, ":installSystemInfoProxy(%p) FAILED", systeminfo_proxy );
00298 return WRET_ERR_PARAM;
00299 }
00300 Log(LOG_INFO, ":installSystemInfoProxy(%p)", systeminfo_proxy );
00301 return WRET_OK;
00302 }
00303
00304 WRESULT SystemMonitor::installSystemInfoProxy( const std::string& systeminfo_proxy_classname_pattern, double version ) {
00305 Log(LOG_INFO, ":installSystemInfoProxy(%s, %g)", systeminfo_proxy_classname_pattern.c_str(), version );
00306 SystemInfoProxy* sip = ObjectFactory::createTypeOf<SystemInfoProxy>(systeminfo_proxy_classname_pattern, version);
00307 return installSystemInfoProxy(sip);
00308 }
00309
00310 WRESULT SystemMonitor::installSystemInfoProxies( const std::string& systeminfo_proxy_classname_pattern ) {
00311 Log(LOG_INFO, ":installSystemInfoProxies(%s)", systeminfo_proxy_classname_pattern.c_str() );
00312 WRESULT ret = WRET_OK;
00313 VectorT<SystemInfoProxy*> proxies;
00314 ObjectFactory::createTypesOf<SystemInfoProxy>(proxies, systeminfo_proxy_classname_pattern);
00315 VectorT<SystemInfoProxy*>::Iterator it;
00316 for (it=proxies.begin(); it!=proxies.end(); ++it ) {
00317 ret |= installSystemInfoProxy(*it);
00318 }
00319 return ret;
00320 }
00321
00322
00323
00324
00325 WRESULT SystemMonitor::mmDoCleanErrors() {
00326 Log(LOG_INFO, ":mmCleanErrors() Cleaning.. [%d records]", this->infoCache.size() );
00327 this->infoCache.free();
00328 return WRET_OK;
00329 }
00330
00331
00332
00333
00334 Response* SystemMonitor::mmDoProfilesList( const Request* request ) {
00335 if ( request == NULL ) return NULL;
00336 Variant target; Variant option1;
00337 request->extractArguments(target, option1);
00338 if ( !target.isStringNotEmpty() )
00339 return request->replyResponse(WRET_ERR_PARAM, "specify target {properties, methods, connectors}");
00340 Log(LOG_VERBOSE, ":mmDoProfilesList(%s)", target.asString().c_str() );
00341 #ifdef _ENABLE_PROFILING
00342 if ( this->profiler == NULL )
00343 return request->replyResponse(WRET_ERR_INTERNAL, "Internal error: Profiler is NULL");
00344
00345 if ( target.asString() == "properties" )
00346 return request->replyResponse(WRET_OK, this->profiler->getProfilesPropertiesTable(option1.toInt64(1)) );
00347 else if ( target.asString() == "methods" )
00348 return request->replyResponse(WRET_OK, this->profiler->getProfilesMethodsTable(option1.toInt64(0)) );
00349 else if ( target.asString() == "connectors" )
00350 return request->replyResponse(WRET_OK, this->profiler->getProfilesConnectorsTable(option1.toInt64(0)) );
00351 #else
00352 return request->replyResponse(WRET_ERR_ILLEGAL_USE, "Profiling is not enabled in this built.");
00353 #endif
00354 return request->replyResponse(WRET_ERR_PARAM, "specify valid target {properties, methods, connectors}");
00355 }
00356
00357 Response* SystemMonitor::mmDoListDeprecated( const Request* request ) {
00358 if ( request == NULL ) return NULL;
00359 string option = request->getArgument().toString();
00360 Log(LOG_VERBOSE, ":mmDoListDeprecated(%s)", option.c_str() );
00361
00362 WOSH_DEPRECATE( "SystemMonitor::mmDoListDeprecated", "SAMPLE" )
00363
00364 #ifdef _ENABLE_PROFILING
00365 if ( this->profiler == NULL )
00366 return request->replyResponse(WRET_ERR_INTERNAL, "Internal error: Profiler is NULL");
00367 return request->replyResponse(WRET_OK, this->profiler->getDeprecatedTable() );
00368 #else
00369 return request->replyResponse(WRET_ERR_ILLEGAL_USE, "Deprecated Calls logging is not enabled in this built.");
00370 #endif
00371 }
00372
00373
00374
00375
00376
00377 WRESULT SystemMonitor::save( SystemInfo* sysInfo, const Object* source, bool raise_message ) {
00378 if ( sysInfo == NULL) return WRET_ERR_PARAM;
00379 if ( SystemMonitor::getInstance() == NULL ) return WRET_ERR_INTERNAL;
00380 if ( raise_message ) {
00381 Message* msg_system = new Message(sysInfo->clone());
00382 msg_system->setSource(source);
00383 msg_system->setDestinationBroadcast(false);
00384 msg_system->setDestinationBus(_Bus_Core);
00385 SecurityManager::getCredentialImplicit().signMessage(msg_system, source);
00386 SystemMonitor::getInstance()->BusCore.postMessage(msg_system);
00387 }
00388
00389 SystemMonitor::getInstance()->Log(LOG_INFO, ":save() : Adding SystemInfo#%"PRId64, sysInfo->getID() );
00390 SystemMonitor::getInstance()->infoCache.push_back_safe( sysInfo );
00391 return WRET_OK;
00392 }
00393
00394
00395
00396
00397
00398
00399 };