diff --git a/include/Host.h b/include/Host.h index 0c60e7f783..e4a11b5b40 100644 --- a/include/Host.h +++ b/include/Host.h @@ -113,6 +113,22 @@ public: **/ int update_info(string &parse_str); + /** + * Inserts the last monitoring, and deletes old monitoring entries. + * + * @param db pointer to the db + * @return 0 on success + */ + int update_monitoring(SqlDB * db); + + /** + * Deletes all monitoring entries. + * + * @param db pointer to the db + * @return 0 on success + */ + int clean_monitoring(SqlDB * db); + /** * Retrives host state * @return HostState code number @@ -355,6 +371,12 @@ private: static const char * table; + static const char * monit_db_names; + + static const char * monit_db_bootstrap; + + static const char * monit_table; + /** * Execute an INSERT or REPLACE Sql query. * @param db The SQL DB @@ -370,9 +392,15 @@ private: */ static int bootstrap(SqlDB * db) { - ostringstream oss_host(Host::db_bootstrap); + int rc; - return db->exec(oss_host); + ostringstream oss_host(Host::db_bootstrap); + ostringstream oss_monit(Host::monit_db_bootstrap); + + rc = db->exec(oss_host); + rc += db->exec(oss_monit); + + return rc; }; /** diff --git a/include/HostPool.h b/include/HostPool.h index 8738117ba2..d13b832e2c 100644 --- a/include/HostPool.h +++ b/include/HostPool.h @@ -197,6 +197,55 @@ public: return PoolSQL::search(oids, Host::table, where); }; + /** + * Dumps the host monitoring information entries in XML format. A filter + * can be also added to the query. + * + * @param oss the output stream to dump the pool contents + * @param where filter for the objects, defaults to all + * + * @return 0 on success + */ + int dump_monitoring(ostringstream& oss, + const string& where); + + /** + * Inserts the last monitoring, and deletes old monitoring entries for this + * host + * + * @param host pointer to the host object + * @return 0 on success + */ + int update_monitoring(Host * host) + { + if ( _host_monitoring_history <= 0 ) + { + return 0; + } + + return host->update_monitoring(db); + }; + + /** + * Deletes all monitoring entries for this host + * + * @param host pointer to the virtual machine object + * @return 0 on success + */ + int clean_monitoring(Host * host) + { + return host->clean_monitoring(db); + }; + + /** + * Get the size, in seconds, of the historical monitoring information + * @return the seconds + */ + static const int& host_monitoring_history() + { + return _host_monitoring_history; + }; + private: /** @@ -217,6 +266,11 @@ private: * @return 0 on success */ int discover_cb(void * _map, int num, char **values, char **names); + + /** + * Size, in seconds, of the historical monitoring information + */ + static int _host_monitoring_history; }; #endif /*HOST_POOL_H_*/ diff --git a/include/RequestManagerHost.h b/include/RequestManagerHost.h index 109542fc91..65f538cf0c 100644 --- a/include/RequestManagerHost.h +++ b/include/RequestManagerHost.h @@ -68,6 +68,26 @@ public: RequestAttributes& att); }; +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class HostMonitoring : public RequestManagerHost +{ +public: + HostMonitoring(): + RequestManagerHost("HostMonitoring", + "Returns the host monitoring records", + "A:si") + { + auth_op = AuthRequest::USE; + }; + + ~HostMonitoring(){}; + + void request_execute(xmlrpc_c::paramList const& _paramList, + RequestAttributes& att); +}; + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/include/RequestManagerPoolInfoFilter.h b/include/RequestManagerPoolInfoFilter.h index a83f9f433c..50bf75b678 100644 --- a/include/RequestManagerPoolInfoFilter.h +++ b/include/RequestManagerPoolInfoFilter.h @@ -238,6 +238,31 @@ public: /* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ +class HostPoolMonitoring : public RequestManagerPoolInfoFilter +{ +public: + + HostPoolMonitoring(): + RequestManagerPoolInfoFilter("HostPoolMonitoring", + "Returns the host monitoring records", + "A:s") + { + Nebula& nd = Nebula::instance(); + pool = nd.get_hpool(); + auth_object = PoolObjectSQL::HOST; + }; + + ~HostPoolMonitoring(){}; + + /* -------------------------------------------------------------------- */ + + void request_execute( + xmlrpc_c::paramList const& paramList, RequestAttributes& att); +}; + +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + class GroupPoolInfo: public RequestManagerPoolInfoFilter { public: diff --git a/include/VirtualMachinePool.h b/include/VirtualMachinePool.h index a8a41172cb..ca5ab6d405 100644 --- a/include/VirtualMachinePool.h +++ b/include/VirtualMachinePool.h @@ -147,7 +147,6 @@ public: * @param vm pointer to the virtual machine object * @return 0 on success */ - int clean_monitoring( VirtualMachine * vm) { diff --git a/src/host/Host.cc b/src/host/Host.cc index 92abb39f65..0015c73d3e 100644 --- a/src/host/Host.cc +++ b/src/host/Host.cc @@ -69,6 +69,14 @@ const char * Host::db_bootstrap = "CREATE TABLE IF NOT EXISTS host_pool (" "last_mon_time INTEGER, uid INTEGER, gid INTEGER, owner_u INTEGER, " "group_u INTEGER, other_u INTEGER, UNIQUE(name))"; + +const char * Host::monit_table = "host_monitoring"; + +const char * Host::monit_db_names = "hid, last_mon_time, body"; + +const char * Host::monit_db_bootstrap = "CREATE TABLE IF NOT EXISTS " + "host_monitoring (hid INTEGER, last_mon_time INTEGER, body TEXT, " + "PRIMARY KEY(hid, last_mon_time))"; /* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */ @@ -153,7 +161,7 @@ error_hostname: goto error_generic; error_generic: - error_str = "Error inserting Group in DB."; + error_str = "Error inserting Host in DB."; error_common: return -1; } @@ -188,6 +196,83 @@ int Host::update_info(string &parse_str) return 0; } +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int Host::update_monitoring(SqlDB * db) +{ + ostringstream oss; + int rc; + + string xml_body; + string error_str; + char * sql_xml; + + sql_xml = db->escape_str(to_xml(xml_body).c_str()); + + if ( sql_xml == 0 ) + { + goto error_body; + } + + if ( validate_xml(sql_xml) != 0 ) + { + goto error_xml; + } + + oss << "DELETE FROM " << monit_table + << " WHERE hid=" << oid + << " AND last_mon_time < (" << last_monitored + << " - " << HostPool::host_monitoring_history() << ")"; + + db->exec(oss); + + oss.str(""); + oss << "INSERT INTO " << monit_table << " ("<< monit_db_names <<") VALUES (" + << oid << "," + << last_monitored << "," + << "'" << sql_xml << "')"; + + db->free_str(sql_xml); + + rc = db->exec(oss); + + return rc; + +error_xml: + db->free_str(sql_xml); + + error_str = "could not transform the Host to XML."; + + goto error_common; + +error_body: + error_str = "could not insert the Host in the DB."; + +error_common: + oss.str(""); + oss << "Error updating Host monitoring information, " << error_str; + + NebulaLog::log("ONE",Log::ERROR, oss); + + return -1; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int Host::clean_monitoring(SqlDB * db) +{ + ostringstream oss; + int rc; + + oss << "DELETE FROM " << monit_table << " WHERE hid=" << oid; + + rc = db->exec(oss); + + return rc; +} + /* ************************************************************************ */ /* Host :: Misc */ /* ************************************************************************ */ diff --git a/src/host/HostPool.cc b/src/host/HostPool.cc index 069245d36b..921449f2ad 100644 --- a/src/host/HostPool.cc +++ b/src/host/HostPool.cc @@ -29,11 +29,16 @@ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +int HostPool::_host_monitoring_history; + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + HostPool::HostPool(SqlDB* db, vector hook_mads, const string& hook_location, const string& remotes_location, - int host_monitoring_history) // TODO + int host_monitoring_history) : PoolSQL(db, Host::table, true) { // ------------------ Initialize Hooks for the pool ---------------------- @@ -143,6 +148,8 @@ HostPool::HostPool(SqlDB* db, add_hook(hook); } + + _host_monitoring_history = host_monitoring_history; } /* -------------------------------------------------------------------------- */ @@ -290,3 +297,26 @@ int HostPool::discover(map * discovered_hosts, int host_limit) return rc; } + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int HostPool::dump_monitoring( + ostringstream& oss, + const string& where) +{ + ostringstream cmd; + + cmd << "SELECT " << Host::monit_table << ".body FROM " << Host::monit_table + << " INNER JOIN " << Host::table + << " WHERE hid = oid"; + + if ( !where.empty() ) + { + cmd << " AND " << where; + } + + cmd << " ORDER BY hid, " << Host::monit_table << ".last_mon_time;"; + + return PoolSQL::dump(oss, "MONITORING_DATA", cmd); +} diff --git a/src/im/InformationManagerDriver.cc b/src/im/InformationManagerDriver.cc index 3af422e13c..990638f0f3 100644 --- a/src/im/InformationManagerDriver.cc +++ b/src/im/InformationManagerDriver.cc @@ -128,6 +128,7 @@ void InformationManagerDriver::protocol( host->touch(true); hpool->update(host); + hpool->update_monitoring(host); host->unlock(); } diff --git a/src/rm/RequestManager.cc b/src/rm/RequestManager.cc index 56264a0fbf..8ce9deaec9 100644 --- a/src/rm/RequestManager.cc +++ b/src/rm/RequestManager.cc @@ -306,6 +306,8 @@ void RequestManager::register_xml_methods() // Host Methods xmlrpc_c::methodPtr host_enable(new HostEnable()); + xmlrpc_c::methodPtr host_monitoring(new HostMonitoring()); + xmlrpc_c::methodPtr host_pool_monitoring(new HostPoolMonitoring()); // Image Methods xmlrpc_c::methodPtr image_persistent(new ImagePersistent()); @@ -373,8 +375,10 @@ void RequestManager::register_xml_methods() RequestManagerRegistry.addMethod("one.host.allocate", host_allocate); RequestManagerRegistry.addMethod("one.host.delete", host_delete); RequestManagerRegistry.addMethod("one.host.info", host_info); + RequestManagerRegistry.addMethod("one.host.monitoring", host_monitoring); RequestManagerRegistry.addMethod("one.hostpool.info", hostpool_info); + RequestManagerRegistry.addMethod("one.hostpool.monitoring", host_pool_monitoring); /* Group related methods */ RequestManagerRegistry.addMethod("one.group.allocate", group_allocate); diff --git a/src/rm/RequestManagerHost.cc b/src/rm/RequestManagerHost.cc index f4f1b1fd9d..dd405651f2 100644 --- a/src/rm/RequestManagerHost.cc +++ b/src/rm/RequestManagerHost.cc @@ -67,3 +67,40 @@ void HostEnable::request_execute(xmlrpc_c::paramList const& paramList, /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +void HostMonitoring::request_execute( + xmlrpc_c::paramList const& paramList, + RequestAttributes& att) +{ + int id = xmlrpc_c::value_int(paramList.getInt(1)); + + ostringstream oss; + string where; + int rc; + + if ( basic_authorization(id, att) == false ) + { + return; + } + + oss << "oid = " << id; + + where = oss.str(); + + oss.str(""); + + rc = (static_cast(pool))->dump_monitoring(oss, where); + + if ( rc != 0 ) + { + failure_response(INTERNAL,request_error("Internal Error",""), att); + return; + } + + success_response(oss.str(), att); + + return; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + diff --git a/src/rm/RequestManagerPoolInfoFilter.cc b/src/rm/RequestManagerPoolInfoFilter.cc index 094f781758..53b4f3c225 100644 --- a/src/rm/RequestManagerPoolInfoFilter.cc +++ b/src/rm/RequestManagerPoolInfoFilter.cc @@ -163,6 +163,7 @@ void VirtualMachinePoolMonitoring::request_execute( return; } + /* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ @@ -176,6 +177,32 @@ void HostPoolInfo::request_execute( /* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ +void HostPoolMonitoring::request_execute( + xmlrpc_c::paramList const& paramList, + RequestAttributes& att) +{ + ostringstream oss; + string where; + int rc; + + where_filter(att, ALL, -1, -1, "", "", where); + + rc = (static_cast(pool))->dump_monitoring(oss, where); + + if ( rc != 0 ) + { + failure_response(INTERNAL,request_error("Internal Error",""), att); + return; + } + + success_response(oss.str(), att); + + return; +} + +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + void GroupPoolInfo::request_execute( xmlrpc_c::paramList const& paramList, RequestAttributes& att)