[Libreoffice-commits] online.git: loleaflet/admin.strings.js loleaflet/dist loleaflet/src wsd/Admin.cpp wsd/Admin.hpp wsd/AdminModel.cpp wsd/AdminModel.hpp wsd/DocumentBroker.cpp wsd/DocumentBroker.hpp wsd/protocol.txt
Michael Meeks
michael.meeks at collabora.com
Sat Jun 3 21:56:37 UTC 2017
loleaflet/admin.strings.js | 2 ++
loleaflet/dist/admin/admin.html | 14 +++++++++++---
loleaflet/dist/admin/dashboard.css | 2 +-
loleaflet/src/admin/AdminSocketOverview.js | 10 ++++++++--
wsd/Admin.cpp | 23 ++++++++++++++++++-----
wsd/Admin.hpp | 5 +++--
wsd/AdminModel.cpp | 12 ++++++++++++
wsd/AdminModel.hpp | 21 ++++++++++++++++++++-
wsd/DocumentBroker.cpp | 24 +++++++++++++++++++++++-
wsd/DocumentBroker.hpp | 1 +
wsd/protocol.txt | 11 ++++++++---
11 files changed, 107 insertions(+), 18 deletions(-)
New commits:
commit eeaf436d5353cac3846e7cd69dc3a012eedf6cb0
Author: Michael Meeks <michael.meeks at collabora.com>
Date: Sat Jun 3 22:53:57 2017 +0100
Admin: show cumulative bandwidth sent / recv'd over all time.
Change-Id: I3f9f398d1de19d54e0aa4c51bc44c597019dc839
diff --git a/loleaflet/admin.strings.js b/loleaflet/admin.strings.js
index 5d21e7aa..a38f9a0e 100644
--- a/loleaflet/admin.strings.js
+++ b/loleaflet/admin.strings.js
@@ -15,6 +15,8 @@ l10nstrings.strUserName = _('Users Name');
l10nstrings.strDocumentsOpened = _('Documents opened');
l10nstrings.strDocumentNumber = _('Number of Documents');
l10nstrings.strMemoryConsumed = _('Memory consumed');
+l10nstrings.strSentBytes = _('Bytes sent');
+l10nstrings.strRecvBytes = _('Bytes received');
l10nstrings.strPid = _('PID');
l10nstrings.strDocument = _('Document');
l10nstrings.strNumberOfViews = _('Number of views');
diff --git a/loleaflet/dist/admin/admin.html b/loleaflet/dist/admin/admin.html
index 72308e88..4bbc063f 100644
--- a/loleaflet/dist/admin/admin.html
+++ b/loleaflet/dist/admin/admin.html
@@ -65,18 +65,26 @@
<h1 class="page-header"><script>document.write(l10nstrings.strDashboard)</script></h1>
<div class="row placeholders">
- <div class="col-xs-6 col-sm-3 placeholder">
+ <div class="col-xs-6 col-sm-2 placeholder">
<div class="main-data" id="active_users_count">0</div>
<h4><script>document.write(l10nstrings.strUsersOnline)</script></h4>
</div>
- <div class="col-xs-6 col-sm-3 placeholder">
+ <div class="col-xs-6 col-sm-2 placeholder">
<div class="main-data" id="active_docs_count">0</div>
<h4><script>document.write(l10nstrings.strDocumentsOpened)</script></h4>
</div>
- <div class="col-xs-6 col-sm-3 placeholder">
+ <div class="col-xs-6 col-sm-2 placeholder">
<div class="main-data" id="total_mem">0</div>
<h4><script>document.write(l10nstrings.strMemoryConsumed)</script></h4>
</div>
+ <div class="col-xs-6 col-sm-2 placeholder">
+ <div class="main-data" id="sent_bytes">0</div>
+ <h4><script>document.write(l10nstrings.strSentBytes)</script></h4>
+ </div>
+ <div class="col-xs-6 col-sm-2 placeholder">
+ <div class="main-data" id="recv_bytes">0</div>
+ <h4><script>document.write(l10nstrings.strRecvBytes)</script></h4>
+ </div>
</div>
<div class="container">
<ul class="nav nav-tabs">
diff --git a/loleaflet/dist/admin/dashboard.css b/loleaflet/dist/admin/dashboard.css
index 0535a2fd..d443ecfe 100644
--- a/loleaflet/dist/admin/dashboard.css
+++ b/loleaflet/dist/admin/dashboard.css
@@ -102,7 +102,7 @@ body {
.placeholder .main-data {
display: inline-block;
border-radius: 50%;
- font-size: 60px;
+ font-size: 45px;
}
/*
diff --git a/loleaflet/src/admin/AdminSocketOverview.js b/loleaflet/src/admin/AdminSocketOverview.js
index dfb92b64..a0726e60 100644
--- a/loleaflet/src/admin/AdminSocketOverview.js
+++ b/loleaflet/src/admin/AdminSocketOverview.js
@@ -16,6 +16,8 @@ var AdminSocketOverview = AdminSocketBase.extend({
this.socket.send('total_mem');
this.socket.send('active_docs_count');
this.socket.send('active_users_count');
+ this.socket.send('sent_bytes');
+ this.socket.send('recv_bytes');
},
onSocketOpen: function() {
@@ -341,13 +343,17 @@ var AdminSocketOverview = AdminSocketBase.extend({
}
else if (textMsg.startsWith('total_mem') ||
textMsg.startsWith('active_docs_count') ||
- textMsg.startsWith('active_users_count'))
+ textMsg.startsWith('active_users_count') ||
+ textMsg.startsWith('sent_bytes') ||
+ textMsg.startsWith('recv_bytes'))
{
textMsg = textMsg.split(' ');
var sCommand = textMsg[0];
var nData = parseInt(textMsg[1]);
- if (sCommand === 'total_mem') {
+ if (sCommand === 'total_mem' ||
+ sCommand === 'sent_bytes' ||
+ sCommand === 'recv_bytes') {
nData = Util.humanizeMem(nData);
}
$(document.getElementById(sCommand)).text(nData);
diff --git a/wsd/Admin.cpp b/wsd/Admin.cpp
index fdea3f9a..1c15aa1d 100644
--- a/wsd/Admin.cpp
+++ b/wsd/Admin.cpp
@@ -140,10 +140,14 @@ void AdminSocketHandler::handleMessage(bool /* fin */, WSOpCode /* code */,
}
}
else if (tokens[0] == "total_mem")
- {
- const auto totalMem = _admin->getTotalMemoryUsage();
- sendTextFrame("total_mem " + std::to_string(totalMem));
- }
+ sendTextFrame("total_mem " + std::to_string(_admin->getTotalMemoryUsage()));
+
+ else if (tokens[0] == "sent_bytes")
+ sendTextFrame("sent_bytes " + std::to_string(model.getSentBytesTotal() / 1024));
+
+ else if (tokens[0] == "recv_bytes")
+ sendTextFrame("recv_bytes " + std::to_string(model.getRecvBytesTotal() / 1024));
+
else if (tokens[0] == "kill" && tokens.count() == 2)
{
try
@@ -244,7 +248,10 @@ void AdminSocketHandler::sendTextFrame(const std::string& message)
{
UnitWSD::get().onAdminQueryMessage(message);
if (_isAuthenticated)
+ {
+ LOG_TRC("send admin text frame '" << message << "'");
sendMessage(message);
+ }
else
LOG_TRC("Skip sending message to non-authenticated client: '" << message << "'");
}
@@ -387,7 +394,7 @@ void Admin::rescheduleCpuTimer(unsigned interval)
wakeup();
}
-unsigned Admin::getTotalMemoryUsage()
+size_t Admin::getTotalMemoryUsage()
{
// To simplify and clarify this; since load, link and pre-init all
// inside the forkit - we should account all of our fixed cost of
@@ -427,6 +434,12 @@ void Admin::updateMemoryDirty(const std::string& docKey, int dirty)
{ _model.updateMemoryDirty(docKey, dirty); });
}
+void Admin::addBytes(const std::string& docKey, uint64_t sent, uint64_t recv)
+{
+ addCallback([this, docKey, sent, recv]
+ { _model.addBytes(docKey, sent, recv); });
+}
+
void Admin::dumpState(std::ostream& os)
{
// FIXME: be more helpful ...
diff --git a/wsd/Admin.hpp b/wsd/Admin.hpp
index f9d8bb6a..2c77e391 100644
--- a/wsd/Admin.hpp
+++ b/wsd/Admin.hpp
@@ -69,7 +69,7 @@ public:
/// Custom poll thread function
void pollingThread() override;
- unsigned getTotalMemoryUsage();
+ size_t getTotalMemoryUsage();
void modificationAlert(const std::string& dockey, Poco::Process::PID pid, bool value);
/// Update the Admin Model.
@@ -99,6 +99,7 @@ public:
void updateLastActivityTime(const std::string& docKey);
void updateMemoryDirty(const std::string& docKey, int dirty);
+ void addBytes(const std::string& docKey, uint64_t sent, uint64_t recv);
void dumpState(std::ostream& os) override;
@@ -107,7 +108,7 @@ private:
/// the Admin Poll thread.
AdminModel _model;
int _forKitPid;
- long _lastTotalMemory;
+ size_t _lastTotalMemory;
std::atomic<int> _memStatsTaskIntervalMs;
std::atomic<int> _cpuStatsTaskIntervalMs;
diff --git a/wsd/AdminModel.cpp b/wsd/AdminModel.cpp
index 51b314ef..1ee088eb 100644
--- a/wsd/AdminModel.cpp
+++ b/wsd/AdminModel.cpp
@@ -373,6 +373,18 @@ void AdminModel::notify(const std::string& message)
}
}
+void AdminModel::addBytes(const std::string& docKey, uint64_t sent, uint64_t recv)
+{
+ assertCorrectThread();
+
+ auto doc = _documents.find(docKey);
+ if(doc != _documents.end())
+ doc->second.addBytes(sent, recv);
+
+ _sentBytesTotal += sent;
+ _recvBytesTotal += recv;
+}
+
void AdminModel::modificationAlert(const std::string& docKey, Poco::Process::PID pid, bool value)
{
assertCorrectThread();
diff --git a/wsd/AdminModel.hpp b/wsd/AdminModel.hpp
index 1d86e827..ed83d8cd 100644
--- a/wsd/AdminModel.hpp
+++ b/wsd/AdminModel.hpp
@@ -55,7 +55,9 @@ public:
_filename(filename),
_memoryDirty(0),
_start(std::time(nullptr)),
- _lastActivity(_start)
+ _lastActivity(_start),
+ _sentBytes(0),
+ _recvBytes(0)
{
}
@@ -88,6 +90,12 @@ public:
void setModified(bool value) { _isModified = value; }
bool getModifiedStatus() const { return _isModified; }
+ void addBytes(uint64_t sent, uint64_t recv)
+ {
+ _sentBytes += sent;
+ _recvBytes += recv;
+ }
+
std::string to_string() const;
private:
@@ -107,6 +115,9 @@ private:
std::time_t _lastActivity;
std::time_t _end = 0;
std::map<std::time_t,std::string> _snapshots;
+
+ /// Total bytes sent and recv'd by this document.
+ uint64_t _sentBytes, _recvBytes;
};
/// An Admin session subscriber.
@@ -203,6 +214,11 @@ public:
void updateLastActivityTime(const std::string& docKey);
void updateMemoryDirty(const std::string& docKey, int dirty);
+ void addBytes(const std::string& docKey, uint64_t sent, uint64_t recv);
+
+ uint64_t getSentBytesTotal() { return _sentBytesTotal; }
+ uint64_t getRecvBytesTotal() { return _recvBytesTotal; }
+
private:
std::string getMemStats();
@@ -224,6 +240,9 @@ private:
std::list<unsigned> _cpuStats;
unsigned _cpuStatsSize = 100;
+ uint64_t _sentBytesTotal;
+ uint64_t _recvBytesTotal;
+
/// We check the owner even in the release builds, needs to be always correct.
std::thread::id _owner;
};
diff --git a/wsd/DocumentBroker.cpp b/wsd/DocumentBroker.cpp
index ac7db55f..a80b9395 100644
--- a/wsd/DocumentBroker.cpp
+++ b/wsd/DocumentBroker.cpp
@@ -228,12 +228,34 @@ void DocumentBroker::pollThread()
"per_document.idle_timeout_secs", 3600);
std::string closeReason = "stopped";
+ // Used to accumulate B/W deltas.
+ uint64_t adminSent = 0;
+ uint64_t adminRecv = 0;
+ auto lastBWUpdateTime = std::chrono::steady_clock::now();
+
// Main polling loop goodness.
while (!_stop && _poll->continuePolling() && !TerminationFlag)
{
_poll->poll(SocketPoll::DefaultPollTimeoutMs);
const auto now = std::chrono::steady_clock::now();
+
+ if (std::chrono::duration_cast<std::chrono::milliseconds>
+ (now - lastBWUpdateTime).count() >= 5 * 1000)
+ {
+ lastBWUpdateTime = now;
+ uint64_t sent, recv;
+ getIOStats(sent, recv);
+ // send change since last notification.
+ Admin::instance().addBytes(getDocKey(),
+ // connection drop transiently reduces this.
+ std::max(sent - adminSent, uint64_t(0)),
+ std::max(recv - adminRecv, uint64_t(0)));
+ LOG_INF("Doc [" << _docKey << "] added sent: " << sent << " recv: " << recv << " bytes to totals");
+ adminSent = sent;
+ adminRecv = recv;
+ }
+
if (_lastSaveTime < _lastSaveRequestTime &&
std::chrono::duration_cast<std::chrono::milliseconds>
(now - _lastSaveRequestTime).count() <= COMMAND_TIMEOUT_MS)
@@ -1461,7 +1483,7 @@ void DocumentBroker::dumpState(std::ostream& os)
else
os << "\n still loading...";
os << "\n sent: " << sent;
- os << "\n recv?: " << recv;
+ os << "\n recv: " << recv;
os << "\n modified?: " << _isModified;
os << "\n jail id: " << _jailId;
os << "\n filename: " << _filename;
diff --git a/wsd/DocumentBroker.hpp b/wsd/DocumentBroker.hpp
index 2c244fe1..6069b9c0 100644
--- a/wsd/DocumentBroker.hpp
+++ b/wsd/DocumentBroker.hpp
@@ -367,6 +367,7 @@ private:
/// associated with this document.
void pollThread();
+ /// Sum the I/O stats from all connected sessions
void getIOStats(uint64_t &sent, uint64_t &recv);
private:
diff --git a/wsd/protocol.txt b/wsd/protocol.txt
index 7f43e472..4ecd8378 100644
--- a/wsd/protocol.txt
+++ b/wsd/protocol.txt
@@ -554,10 +554,13 @@ history
}
total_mem
+sent_bytes
+recv_bytes
- Queries for total memory being consumed by the server in kilobytes.
- This includes processes - loolwsd, loolforkit, and child processes
- hosting various documents
+ Queries for total memory or bandwidth being consumed by the server
+ in kilobytes. For total_mem this includes processes - loolwsd,
+ loolforkit, and child processes hosting various documents. For
+ sent/recv_bytes this includes only external traffic.
active_docs_count
@@ -651,6 +654,8 @@ documents <pid> <filename> <number of views> <memory consumed> <elapsed time> <i
Each set document attributes is separated by a newline.
total_mem <memory>
+sent_bytes <memory>
+recv_bytes <memory>
<memory> in kilobytes
More information about the Libreoffice-commits
mailing list