From 330ecc6dd45fabe95d8cda1e744e8e7a3d9e6498 Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: Mon, 18 Jul 2011 14:45:30 +0200 Subject: [PATCH] Memory stats --- include/transport/networkplugin.h | 2 + include/transport/networkpluginserver.h | 4 + spectrum/src/sample.cfg | 4 +- spectrum_manager/src/spectrum_manager.cfg | 10 +- src/admininterface.cpp | 136 ++++++++++++++++++++-- src/networkplugin.cpp | 23 ++++ src/networkpluginserver.cpp | 17 +++ src/pbnetwork.proto | 7 ++ 8 files changed, 189 insertions(+), 14 deletions(-) diff --git a/include/transport/networkplugin.h b/include/transport/networkplugin.h index a27a20c3..7fc937f1 100644 --- a/include/transport/networkplugin.h +++ b/include/transport/networkplugin.h @@ -104,6 +104,7 @@ class NetworkPlugin { void send(const std::string &data); void sendPong(); + void sendMemoryUsage(); void pingTimeout(); Swift::SafeByteArray m_data; @@ -114,6 +115,7 @@ class NetworkPlugin { boost::shared_ptr m_conn; Swift::Timer::ref m_pingTimer; bool m_pingReceived; + double m_init_res; }; diff --git a/include/transport/networkpluginserver.h b/include/transport/networkpluginserver.h index 36b40469..ec9c39bc 100644 --- a/include/transport/networkpluginserver.h +++ b/include/transport/networkpluginserver.h @@ -47,6 +47,9 @@ class NetworkPluginServer { std::list users; Swift::SafeByteArray data; boost::shared_ptr connection; + unsigned long res; + unsigned long init_res; + unsigned long shared; }; NetworkPluginServer(Component *component, Config *config, UserManager *userManager); @@ -78,6 +81,7 @@ class NetworkPluginServer { void handleChatStatePayload(const std::string &payload, Swift::ChatState::ChatStateType type); void handleAuthorizationPayload(const std::string &payload); void handleAttentionPayload(const std::string &payload); + void handleStatsPayload(Backend *c, const std::string &payload); void handleUserCreated(User *user); void handleRoomJoined(User *user, const std::string &room, const std::string &nickname, const std::string &password); diff --git a/spectrum/src/sample.cfg b/spectrum/src/sample.cfg index ba0d900a..18fe146e 100644 --- a/spectrum/src/sample.cfg +++ b/spectrum/src/sample.cfg @@ -13,8 +13,8 @@ admin_password=test users_per_backend=1 backend=../../backends/libpurple/spectrum_libpurple_backend #backend=../../backends/libircclient-qt/spectrum_libircclient-qt_backend -#protocol=prpl-jabber -protocol=prpl-msn +protocol=prpl-jabber +#protocol=prpl-msn #protocol=prpl-icq [logging] diff --git a/spectrum_manager/src/spectrum_manager.cfg b/spectrum_manager/src/spectrum_manager.cfg index 4b9ec622..1973021f 100644 --- a/spectrum_manager/src/spectrum_manager.cfg +++ b/spectrum_manager/src/spectrum_manager.cfg @@ -1,8 +1,8 @@ [service] -admin_username=admin_ -admin_password=test_ +admin_username=admin +admin_password=test [servers] -#server=localhost -server=icq.spectrum.im -server=msn.spectrum.im \ No newline at end of file +server=localhost +#server=icq.spectrum.im +#server=msn.spectrum.im \ No newline at end of file diff --git a/src/admininterface.cpp b/src/admininterface.cpp index 1185151f..985be8cb 100644 --- a/src/admininterface.cpp +++ b/src/admininterface.cpp @@ -28,6 +28,8 @@ #include "transport/networkpluginserver.h" #include "storageresponder.h" #include "log4cxx/logger.h" +#include "memoryusage.h" +#include using namespace log4cxx; @@ -129,15 +131,135 @@ void AdminInterface::handleMessageReceived(Swift::Message::ref message) { int backends = m_server->getBackendCount() - 1; message->setBody(boost::lexical_cast(backends)); } + else if (message->getBody() == "res_memory") { + double shared = 0; + double rss = 0; +#ifndef WIN32 + process_mem_usage(shared, rss); +#endif + + const std::list &backends = m_server->getBackends(); + BOOST_FOREACH(NetworkPluginServer::Backend * backend, backends) { + rss += backend->res; + } + + message->setBody(boost::lexical_cast(rss)); + } + else if (message->getBody() == "shr_memory") { + double shared = 0; + double rss = 0; +#ifndef WIN32 + process_mem_usage(shared, rss); +#endif + + const std::list &backends = m_server->getBackends(); + BOOST_FOREACH(NetworkPluginServer::Backend * backend, backends) { + shared += backend->shared; + } + + message->setBody(boost::lexical_cast(shared)); + } + else if (message->getBody() == "used_memory") { + double shared = 0; + double rss = 0; +#ifndef WIN32 + process_mem_usage(shared, rss); +#endif + rss -= shared; + + const std::list &backends = m_server->getBackends(); + BOOST_FOREACH(NetworkPluginServer::Backend * backend, backends) { + rss += backend->res - backend->shared; + } + + message->setBody(boost::lexical_cast(rss)); + } + else if (message->getBody() == "average_memory_per_user") { + if (m_userManager->getUserCount() == 0) { + message->setBody(boost::lexical_cast(0)); + } + else { + unsigned long per_user = 0; + const std::list &backends = m_server->getBackends(); + BOOST_FOREACH(NetworkPluginServer::Backend * backend, backends) { + per_user += (backend->res - backend->init_res); + } + + message->setBody(boost::lexical_cast(per_user / m_userManager->getUserCount())); + } + } + else if (message->getBody() == "res_memory_per_backend") { + std::string lst; + int id = 1; + const std::list &backends = m_server->getBackends(); + BOOST_FOREACH(NetworkPluginServer::Backend * backend, backends) { + lst += "Backend " + boost::lexical_cast(id) + ": " + boost::lexical_cast(backend->res) + "\n"; + id++; + } + + message->setBody(lst); + } + else if (message->getBody() == "shr_memory_per_backend") { + std::string lst; + int id = 1; + const std::list &backends = m_server->getBackends(); + BOOST_FOREACH(NetworkPluginServer::Backend * backend, backends) { + lst += "Backend " + boost::lexical_cast(id) + ": " + boost::lexical_cast(backend->shared) + "\n"; + id++; + } + + message->setBody(lst); + } + else if (message->getBody() == "used_memory_per_backend") { + std::string lst; + int id = 1; + const std::list &backends = m_server->getBackends(); + BOOST_FOREACH(NetworkPluginServer::Backend * backend, backends) { + lst += "Backend " + boost::lexical_cast(id) + ": " + boost::lexical_cast(backend->res - backend->shared) + "\n"; + id++; + } + + message->setBody(lst); + } + else if (message->getBody() == "average_memory_per_user_per_backend") { + std::string lst; + int id = 1; + const std::list &backends = m_server->getBackends(); + BOOST_FOREACH(NetworkPluginServer::Backend * backend, backends) { + if (backend->users.size() == 0) { + lst += "Backend " + boost::lexical_cast(id) + ": 0\n"; + } + else { + lst += "Backend " + boost::lexical_cast(id) + ": " + boost::lexical_cast((backend->init_res - backend->shared) / backend->users.size()) + "\n"; + } + id++; + } + + message->setBody(lst); + } else if (message->getBody().find("help") == 0) { std::string help; - help += "status - shows instance status\n"; - help += "online_users - returns list of all online users\n"; - help += "online_users_count - number of online users\n"; - help += "online_users_per_backend - shows online users per backends\n"; - help += "has_online_user - returns 1 if user is online\n"; - help += "backends_count - number of active backends\n"; - help += "reload - Reloads config file\n"; + help += "General:\n"; + help += " status - shows instance status\n"; + help += " reload - Reloads config file\n"; + help += "Users:\n"; + help += " online_users - returns list of all online users\n"; + help += " online_users_count - number of online users\n"; + help += " online_users_per_backend - shows online users per backends\n"; + help += " has_online_user - returns 1 if user is online\n"; + help += "Backends:\n"; + help += " backends_count - number of active backends\n"; + help += "Memory:\n"; + help += " res_memory - Total RESident memory spectrum2 and its backends use in KB\n"; + help += " shr_memory - Total SHaRed memory spectrum2 backends share together in KB\n"; + help += " used_memory - (res_memory - shr_memory)\n"; + help += " average_memory_per_user - (memory_used_without_any_user - res_memory)\n"; + help += " res_memory_per_backend - RESident memory used by backends in KB\n"; + help += " shr_memory_per_backend - SHaRed memory used by backends in KB\n"; + help += " used_memory_per_backend - (res_memory - shr_memory) per backend\n"; + help += " average_memory_per_user_per_backend - (memory_used_without_any_user - res_memory) per backend\n"; + + message->setBody(help); } else { diff --git a/src/networkplugin.cpp b/src/networkplugin.cpp index e1bb0155..d296f70b 100644 --- a/src/networkplugin.cpp +++ b/src/networkplugin.cpp @@ -31,6 +31,7 @@ #include "pbnetwork.pb.h" #include "log4cxx/logger.h" #include "log4cxx/basicconfigurator.h" +#include "memoryusage.h" using namespace log4cxx; @@ -56,6 +57,9 @@ NetworkPlugin::NetworkPlugin(Swift::EventLoop *loop, const std::string &host, in m_pingTimer = m_factories->getTimerFactory()->createTimer(30000); m_pingTimer->onTick.connect(boost::bind(&NetworkPlugin::pingTimeout, this)); connect(); + + double shared; + process_mem_usage(shared, m_init_res); } NetworkPlugin::~NetworkPlugin() { @@ -491,6 +495,25 @@ void NetworkPlugin::sendPong() { send(message); LOG4CXX_INFO(logger, "PONG"); + sendMemoryUsage(); +} + +void NetworkPlugin::sendMemoryUsage() { + pbnetwork::Stats stats; + + stats.set_init_res(m_init_res); + double res; + double shared; + process_mem_usage(shared, res); + stats.set_res(res); + stats.set_shared(shared); + + std::string message; + stats.SerializeToString(&message); + + WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_STATS); + + send(message); } void NetworkPlugin::pingTimeout() { diff --git a/src/networkpluginserver.cpp b/src/networkpluginserver.cpp index 42baf81f..d4d43147 100644 --- a/src/networkpluginserver.cpp +++ b/src/networkpluginserver.cpp @@ -176,6 +176,9 @@ void NetworkPluginServer::handleNewClientConnection(boost::shared_ptrpongReceived = true; client->connection = c; + client->res = 0; + client->init_res = 0; + client->shared = 0; LOG4CXX_INFO(logger, "New backend " << client << " connected. Current backend count=" << (m_clients.size() + 1)); @@ -458,6 +461,17 @@ void NetworkPluginServer::handleAttentionPayload(const std::string &data) { conv->handleMessage(msg); } +void NetworkPluginServer::handleStatsPayload(Backend *c, const std::string &data) { + pbnetwork::Stats payload; + if (payload.ParseFromString(data) == false) { + // TODO: ERROR + return; + } + c->res = payload.res(); + c->init_res = payload.init_res(); + c->shared = payload.shared(); +} + void NetworkPluginServer::handleDataRead(Backend *c, const Swift::SafeByteArray &data) { c->data.insert(c->data.end(), data.begin(), data.end()); while (c->data.size() != 0) { @@ -524,6 +538,9 @@ void NetworkPluginServer::handleDataRead(Backend *c, const Swift::SafeByteArray case pbnetwork::WrapperMessage_Type_TYPE_ATTENTION: handleAttentionPayload(wrapper.payload()); break; + case pbnetwork::WrapperMessage_Type_TYPE_STATS: + handleStatsPayload(c, wrapper.payload()); + break; default: return; } diff --git a/src/pbnetwork.proto b/src/pbnetwork.proto index 83e0dcd8..77e95303 100644 --- a/src/pbnetwork.proto +++ b/src/pbnetwork.proto @@ -72,6 +72,12 @@ message Status { optional string statusMessage = 4; } +message Stats { + required int32 res = 1; + required int32 init_res = 2; + required int32 shared = 3; +} + message WrapperMessage { enum Type { TYPE_CONNECTED = 1; @@ -95,6 +101,7 @@ message WrapperMessage { TYPE_BUDDY_TYPED = 20; TYPE_AUTH_REQUEST = 21; TYPE_ATTENTION = 22; + TYPE_STATS = 23; } required Type type = 1; optional bytes payload = 2;