loolwsd/Admin.cpp | 31 ++++++++++++++++-- loolwsd/Admin.hpp | 5 +- loolwsd/AdminModel.hpp | 82 ++++++++++++++++++++++++++----------------------- loolwsd/LOOLWSD.cpp | 2 - loolwsd/Util.cpp | 31 ++++++++++++++++++ loolwsd/Util.hpp | 2 + 6 files changed, 109 insertions(+), 44 deletions(-)
New commits: commit 76542d8d528953fdfcf38b55b6eb4a96fcbbd99b Author: Pranav Kant <pran...@collabora.com> Date: Sat Mar 5 00:19:01 2016 +0530 loolwsd: Add total memory, total active docs, total active users Further changes/refactoring to make it possible: * Add broker pid to Admin class * Move getMemoryUsage for process to Util * Change variable name to accurately reflect *active* items _nViews -> _nActiveViews, etc. Change-Id: I4c9206c49ab829b73ebfe226874bfbbcc8f95342 Reviewed-on: https://gerrit.libreoffice.org/22989 Reviewed-by: Tor Lillqvist <t...@collabora.com> Tested-by: Tor Lillqvist <t...@collabora.com> diff --git a/loolwsd/Admin.cpp b/loolwsd/Admin.cpp index c8bcdd6..c4a6d33 100644 --- a/loolwsd/Admin.cpp +++ b/loolwsd/Admin.cpp @@ -112,7 +112,10 @@ public: break; } - if (tokens.count() == 1 && tokens[0] == "stats") + if (tokens.count() < 1) + continue; + + if (tokens[0] == "stats") { //TODO: Collect stats and reply back to admin. // We need to ask Broker to give us some numbers on docs/clients/etc. @@ -140,12 +143,32 @@ public: ws->sendFrame(statsResponse.data(), statsResponse.size()); } - else if (tokens.count() == 1 && tokens[0] == "documents") + else if (tokens[0] == "documents") { std::string responseString = "documents " + model.query("documents"); ws->sendFrame(responseString.data(), responseString.size()); } + else if (tokens[0] == "total_mem") + { + Poco::Process::PID nBrokerPid = _admin->getBrokerPid(); + unsigned totalMem = Util::getMemoryUsage(nBrokerPid); + totalMem += model.getTotalMemoryUsage(); + totalMem += Util::getMemoryUsage(Poco::Process::id()); + + std::string response = "total_mem " + std::to_string(totalMem); + ws->sendFrame(response.data(), response.size()); + } + else if (tokens[0] == "active_users_count") + { + std::string response = tokens[0] + " " + model.query(tokens[0]); + ws->sendFrame(response.data(), response.size()); + } + else if (tokens[0] == "active_docs_count") + { + std::string response = tokens[0] + " " + model.query(tokens[0]); + ws->sendFrame(response.data(), response.size()); + } else if (tokens[0] == "kill" && tokens.count() == 2) { try @@ -226,10 +249,11 @@ private: }; /// An admin command processor. -Admin::Admin(const int brokerPipe, const int notifyPipe) : +Admin::Admin(const Poco::Process::PID brokerPid, const int brokerPipe, const int notifyPipe) : _srv(new AdminRequestHandlerFactory(this), ServerSocket(ADMIN_PORT_NUMBER), new HTTPServerParams), _model(AdminModel()) { + Admin::BrokerPid = brokerPid; Admin::BrokerPipe = brokerPipe; Admin::NotifyPipe = notifyPipe; } @@ -278,6 +302,7 @@ AdminModel& Admin::getModel() } //TODO: Clean up with something more elegant. +Poco::Process::PID Admin::BrokerPid; int Admin::BrokerPipe; int Admin::NotifyPipe; diff --git a/loolwsd/Admin.hpp b/loolwsd/Admin.hpp index 839544e..c02f824 100644 --- a/loolwsd/Admin.hpp +++ b/loolwsd/Admin.hpp @@ -22,11 +22,11 @@ const std::string FIFO_NOTIFY = "loolnotify.fifo"; class Admin : public Poco::Runnable { public: - Admin(const int brokerPipe, const int notifyPipe); + Admin(const Poco::Process::PID brokerPid, const int brokerPipe, const int notifyPipe); ~Admin(); - static int getBrokerPid() { return Admin::BrokerPipe; } + static int getBrokerPid() { return Admin::BrokerPid; } static int getBrokerPipe() { return Admin::BrokerPipe; } @@ -41,6 +41,7 @@ private: Poco::Net::HTTPServer _srv; AdminModel _model; + static Poco::Process::PID BrokerPid; static int BrokerPipe; static int NotifyPipe; }; diff --git a/loolwsd/AdminModel.hpp b/loolwsd/AdminModel.hpp index 4e00446..755a6aa 100644 --- a/loolwsd/AdminModel.hpp +++ b/loolwsd/AdminModel.hpp @@ -35,7 +35,7 @@ public: bool isExpired() { - return _end != 0 && std::time(nullptr) > _end; + return _end != 0 && std::time(nullptr) >= _end; } private: @@ -78,7 +78,7 @@ public: bool isExpired() const { - return _end != 0 && std::time(nullptr) > _end; + return _end != 0 && std::time(nullptr) >= _end; } void addView(int nSessionId) @@ -91,7 +91,7 @@ public: } else { - _nViews++; + _nActiveViews++; } } @@ -101,13 +101,13 @@ public: if (it != _views.end()) { it->second.expire(); - _nViews--; + _nActiveViews--; } } - unsigned getTotalViews() const + unsigned getActiveViews() const { - return _nViews; + return _nActiveViews; } private: @@ -115,7 +115,7 @@ private: /// SessionId mapping to View object std::map<int, View> _views; /// Total number of active views - unsigned _nViews = 0; + unsigned _nActiveViews = 0; /// Hosted URL std::string _sUrl; @@ -183,7 +183,7 @@ public: if (tokens[0] == "document") { addDocument(std::stoi(tokens[1]), tokens[2]); - unsigned mem = getMemoryUsage(std::stoi(tokens[1])); + unsigned mem = Util::getMemoryUsage(std::stoi(tokens[1])); std::string response = data + std::to_string(mem); notify(response); return; @@ -222,39 +222,31 @@ public: { return getDocuments(); } + else if (tokens[0] == "active_users_count") + { + return std::to_string(getTotalActiveViews()); + } + else if (tokens[0] == "active_docs_count") + { + return std::to_string(_nActiveDocuments); + } return std::string(""); } - unsigned getMemoryUsage(Poco::Process::PID nPid) + /// Returns memory consumed by all active loolkit processes + unsigned getTotalMemoryUsage() { - //TODO: Instead of RSS, show PSS - std::string sResponse; - const auto cmd = "ps o rss= -p " + std::to_string(nPid); - FILE* fp = popen(cmd.c_str(), "r"); - if (fp == nullptr) - { - return 0; - } - - char cmdBuffer[1024]; - while (fgets(cmdBuffer, sizeof(cmdBuffer) - 1, fp) != nullptr) + unsigned totalMem = 0; + for (auto& it: _documents) { - sResponse += cmdBuffer; - } - pclose(fp); + if (it.second.isExpired()) + continue; - unsigned nMem = 0; - try - { - nMem = std::stoi(sResponse); - } - catch(std::exception& e) - { - Log::warn() << "Trying to find memory of invalid/dead PID" << Log::end; + totalMem += Util::getMemoryUsage(it.second.getPid()); } - return nMem; + return totalMem; } void subscribe(std::shared_ptr<Poco::Net::WebSocket>& ws) @@ -275,17 +267,17 @@ private: } else { - _nDocuments++; + _nActiveDocuments++; } } void removeDocument(Poco::Process::PID pid) { auto it = _documents.find(pid); - if (it != _documents.end()) + if (it != _documents.end() && !it->second.isExpired()) { it->second.expire(); - _nDocuments--; + _nActiveDocuments--; } } @@ -305,6 +297,20 @@ private: } } + unsigned getTotalActiveViews() + { + unsigned nTotalViews = 0; + for (auto& it: _documents) + { + if (it.second.isExpired()) + continue; + + nTotalViews += it.second.getActiveViews(); + } + + return nTotalViews; + } + std::string getDocuments() { std::ostringstream oss; @@ -315,8 +321,8 @@ private: std::string sPid = std::to_string(it.second.getPid()); std::string sUrl = it.second.getUrl(); - std::string sViews = std::to_string(it.second.getTotalViews()); - std::string sMem = std::to_string(getMemoryUsage(it.second.getPid())); + std::string sViews = std::to_string(it.second.getActiveViews()); + std::string sMem = std::to_string(Util::getMemoryUsage(it.second.getPid())); oss << sPid << " " << sUrl << " " @@ -332,7 +338,7 @@ private: std::map<Poco::Process::PID, Document> _documents; /// Number of active documents - unsigned _nDocuments; + unsigned _nActiveDocuments = 0; }; #endif diff --git a/loolwsd/LOOLWSD.cpp b/loolwsd/LOOLWSD.cpp index 019d916..dee237c 100644 --- a/loolwsd/LOOLWSD.cpp +++ b/loolwsd/LOOLWSD.cpp @@ -1033,7 +1033,7 @@ int LOOLWSD::main(const std::vector<std::string>& /*args*/) } // Start the Admin manager. - Admin admin(BrokerWritePipe, notifyPipe); + Admin admin(brokerPid, BrokerWritePipe, notifyPipe); threadPool.start(admin); TestInput input(*this, svs, srv); diff --git a/loolwsd/Util.cpp b/loolwsd/Util.cpp index dc419c8..e4d1352 100644 --- a/loolwsd/Util.cpp +++ b/loolwsd/Util.cpp @@ -598,6 +598,37 @@ namespace Util } } } + + unsigned getMemoryUsage(Poco::Process::PID nPid) + { + //TODO: Instead of RSS, return PSS + std::string sResponse; + const auto cmd = "ps o rss= -p " + std::to_string(nPid); + FILE* fp = popen(cmd.c_str(), "r"); + if (fp == nullptr) + { + return 0; + } + + char cmdBuffer[1024]; + while (fgets(cmdBuffer, sizeof(cmdBuffer) - 1, fp) != nullptr) + { + sResponse += cmdBuffer; + } + pclose(fp); + + unsigned nMem = 0; + try + { + nMem = std::stoi(sResponse); + } + catch(std::exception& e) + { + Log::warn() << "Trying to find memory of invalid/dead PID" << Log::end; + } + + return nMem; + } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/loolwsd/Util.hpp b/loolwsd/Util.hpp index b4d8251..1e6e515 100644 --- a/loolwsd/Util.hpp +++ b/loolwsd/Util.hpp @@ -126,6 +126,8 @@ namespace Util void pollPipeForReading(pollfd& pollPipe, const std::string& targetPipeName , const int& targetPipe, std::function<void(std::string& message)> handler); + + unsigned getMemoryUsage(Poco::Process::PID nPid); }; //TODO: Move to own file. _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits