mirror of
https://github.com/LibreOffice/online.git
synced 2025-07-29 12:01:08 +00:00
tdf#106451 admin: graph to monitor network activity
Change-Id: Id71ef4e2a9d16e72f4df442fbf646a39213b61d5 Reviewed-on: https://gerrit.libreoffice.org/38621 Reviewed-by: pranavk <pranavk@collabora.co.uk> Tested-by: pranavk <pranavk@collabora.co.uk>
This commit is contained in:
@ -27,6 +27,7 @@ l10nstrings.strKill = _('Kill');
|
||||
l10nstrings.strGraphs = _('Graphs');
|
||||
l10nstrings.strMemoryGraph = _('Memory Graph');
|
||||
l10nstrings.strCpuGraph = _('CPU Graph');
|
||||
l10nstrings.strNetGraph = _('Network Graph');
|
||||
l10nstrings.strSave = _('Save');
|
||||
l10nstrings.strMemoryStatsCachesize = _('Cache size of memory statistics');
|
||||
l10nstrings.strMemoryStatsInterval = _('Time interval of memory statistics (in ms)');
|
||||
|
12
loleaflet/dist/admin/adminAnalytics.html
vendored
12
loleaflet/dist/admin/adminAnalytics.html
vendored
@ -73,6 +73,11 @@
|
||||
<h4><script>document.write(l10nstrings.strCpuGraph)</script></h3>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#networkview" data-toggle="tab">
|
||||
<h4><script>document.write(l10nstrings.strNetGraph)</script></h3>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab-content graph-content">
|
||||
<div id="memview" class="active tab-pane">
|
||||
@ -89,6 +94,13 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="networkview" class="tab-pane">
|
||||
<div class="graph-container">
|
||||
<div>
|
||||
<svg id="NetVisualisation" width="1010" height="510"></svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -12,6 +12,10 @@ var AdminSocketAnalytics = AdminSocketBase.extend({
|
||||
|
||||
_memStatsData: [],
|
||||
_cpuStatsData: [],
|
||||
_sentStatsData: [],
|
||||
_sentAvgStats: [],
|
||||
_recvStatsData: [],
|
||||
_recvAvgStats: [],
|
||||
|
||||
_memStatsSize: 0,
|
||||
_memStatsInterval: 0,
|
||||
@ -19,6 +23,10 @@ var AdminSocketAnalytics = AdminSocketBase.extend({
|
||||
_cpuStatsSize: 0,
|
||||
_cpuStatsInterval: 0,
|
||||
|
||||
_netAvgSize: 10,
|
||||
_netStatsSize: 0,
|
||||
_netStatsInterval: 0,
|
||||
|
||||
_initStatsData: function(option, size, interval, reset) {
|
||||
var actualData;
|
||||
|
||||
@ -36,14 +44,24 @@ var AdminSocketAnalytics = AdminSocketBase.extend({
|
||||
this._memStatsData = actualData;
|
||||
else if (option === 'cpu')
|
||||
this._cpuStatsData = actualData;
|
||||
else if (option === 'sent')
|
||||
this._sentStatsData = actualData;
|
||||
else if (option === 'recv')
|
||||
this._recvStatsData = actualData;
|
||||
else if (option === 'sent_avg')
|
||||
this._sentAvgStats = actualData;
|
||||
else if (option === 'recv_avg')
|
||||
this._recvAvgStats = actualData;
|
||||
},
|
||||
|
||||
onSocketOpen: function() {
|
||||
// Base class' onSocketOpen handles authentication
|
||||
this.base.call(this);
|
||||
|
||||
this.socket.send('subscribe mem_stats cpu_stats settings');
|
||||
this.socket.send('subscribe mem_stats cpu_stats sent_activity recv_activity settings');
|
||||
this.socket.send('settings');
|
||||
this.socket.send('sent_activity');
|
||||
this.socket.send('recv_activity');
|
||||
this.socket.send('mem_stats');
|
||||
this.socket.send('cpu_stats');
|
||||
},
|
||||
@ -60,6 +78,13 @@ var AdminSocketAnalytics = AdminSocketBase.extend({
|
||||
_xCpuScale: null,
|
||||
_yCpuScale: null,
|
||||
|
||||
_d3NetXAxis: null,
|
||||
_d3NetYAxis: null,
|
||||
_d3NetSentLine: null,
|
||||
_d3NetRecvLine: null,
|
||||
_xNetScale: null,
|
||||
_yNetScale: null,
|
||||
|
||||
_graphWidth: 1000,
|
||||
_graphHeight: 500,
|
||||
_graphMargins: {
|
||||
@ -70,11 +95,14 @@ var AdminSocketAnalytics = AdminSocketBase.extend({
|
||||
},
|
||||
|
||||
_setUpAxis: function(option) {
|
||||
var data, xScale, yScale, d3XAxis, d3Line;
|
||||
|
||||
if (option === 'mem')
|
||||
data = this._memStatsData;
|
||||
else if (option === 'cpu')
|
||||
data = this._cpuStatsData;
|
||||
else if (option === 'net')
|
||||
data = this._sentAvgStats.concat(this._recvAvgStats);
|
||||
|
||||
xScale = d3.scale.linear().range([this._graphMargins.left, this._graphWidth - this._graphMargins.right]).domain([d3.min(data, function(d) {
|
||||
return d.time;
|
||||
@ -133,11 +161,27 @@ var AdminSocketAnalytics = AdminSocketBase.extend({
|
||||
.orient('left');
|
||||
this._d3CpuLine = d3Line;
|
||||
}
|
||||
else if (option === 'net') {
|
||||
this._xNetScale = xScale;
|
||||
this._yNetScale = yScale;
|
||||
this._d3NetXAxis = d3XAxis;
|
||||
this._d3NetYAxis = d3.svg.axis()
|
||||
.scale(this._yNetScale)
|
||||
.tickFormat(function (d) {
|
||||
return Util.humanizeMem(d) + '/sec';
|
||||
})
|
||||
.orient('left');
|
||||
this._d3NetSentLine = d3Line;
|
||||
this._d3NetRecvLine = d3Line;
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
_createGraph: function(option) {
|
||||
var vis, xAxis, yAxis, line, data;
|
||||
|
||||
if (option === 'mem') {
|
||||
var vis = d3.select('#MemVisualisation');
|
||||
vis = d3.select('#MemVisualisation');
|
||||
this._setUpAxis('mem');
|
||||
xAxis = this._d3MemXAxis;
|
||||
yAxis = this._d3MemYAxis;
|
||||
@ -145,13 +189,51 @@ var AdminSocketAnalytics = AdminSocketBase.extend({
|
||||
data = this._memStatsData;
|
||||
}
|
||||
else if (option === 'cpu') {
|
||||
var vis = d3.select('#CpuVisualisation');
|
||||
vis = d3.select('#CpuVisualisation');
|
||||
this._setUpAxis('cpu');
|
||||
xAxis = this._d3CpuXAxis;
|
||||
yAxis = this._d3CpuYAxis;
|
||||
line = this._d3CpuLine;
|
||||
data = this._cpuStatsData;
|
||||
}
|
||||
else if (option === 'net') {
|
||||
vis = d3.select('#NetVisualisation');
|
||||
this._setUpAxis('net');
|
||||
xAxis = this._d3NetXAxis;
|
||||
yAxis = this._d3NetYAxis;
|
||||
|
||||
var legend = vis.append('g')
|
||||
.attr('x', this._graphWidth - 70)
|
||||
.attr('y', 50)
|
||||
.style('font-size', '17px');
|
||||
|
||||
var legendData = [
|
||||
{
|
||||
text: 'Recieved',
|
||||
color: 'red'
|
||||
},
|
||||
{
|
||||
text: 'Sent',
|
||||
color: 'green'
|
||||
}
|
||||
];
|
||||
var legendSpacing = 20;
|
||||
|
||||
for (var i = legendData.length - 1; i >= 0; i--) {
|
||||
|
||||
legend.append('text')
|
||||
.attr('x', this._graphWidth - 70)
|
||||
.attr('y', 80 + i * legendSpacing)
|
||||
.text(legendData[i].text);
|
||||
legend.append('rect')
|
||||
.attr('x', this._graphWidth - 90)
|
||||
.attr('y', 67 + i * legendSpacing)
|
||||
.attr('width', 15)
|
||||
.attr('height', 15)
|
||||
.style('fill', legendData[i].color)
|
||||
.style('stroke', 'black');
|
||||
}
|
||||
}
|
||||
|
||||
vis.append('svg:g')
|
||||
.attr('class', 'x-axis')
|
||||
@ -163,15 +245,45 @@ var AdminSocketAnalytics = AdminSocketBase.extend({
|
||||
.attr('transform', 'translate(' + this._graphMargins.left + ',0)')
|
||||
.call(yAxis);
|
||||
|
||||
vis.append('svg:path')
|
||||
.attr('d', line(data))
|
||||
.attr('class', 'line')
|
||||
.attr('stroke', 'blue')
|
||||
.attr('stroke-width', 2)
|
||||
.attr('fill', 'none');
|
||||
if (option === 'cpu' || option === 'mem') {
|
||||
|
||||
vis.append('svg:path')
|
||||
.attr('d', line(data))
|
||||
.attr('class', 'line')
|
||||
.attr('stroke', 'blue')
|
||||
.attr('stroke-width', 2)
|
||||
.attr('fill', 'none');
|
||||
}
|
||||
else if (option === 'net') {
|
||||
|
||||
vis.append('svg:path')
|
||||
.attr('d', this._d3NetSentLine(this._sentAvgStats))
|
||||
.attr('class', 'lineSent')
|
||||
.attr('stroke', 'red')
|
||||
.attr('stroke-width', 2)
|
||||
.attr('fill', 'none');
|
||||
|
||||
vis.append('svg:path')
|
||||
.attr('d', this._d3NetRecvLine(this._recvAvgStats))
|
||||
.attr('class', 'lineRecv')
|
||||
.attr('stroke', 'green')
|
||||
.attr('stroke-width', 2)
|
||||
.attr('fill', 'none');
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
_addNewData: function(oldData, newData) {
|
||||
_addNewData: function(oldData, newData, option) {
|
||||
var size;
|
||||
if (option === 'mem')
|
||||
size = this._memStatsSize;
|
||||
else if (option === 'cpu')
|
||||
size = this._cpuStatsSize;
|
||||
else if (option === 'sent' || option === 'recv')
|
||||
size = this._netStatsSize;
|
||||
else if (option === 'sent_avg' || option === 'recv_avg')
|
||||
size = this._netStatsSize - this._netAvgSize + 1;
|
||||
|
||||
// make a space for new data
|
||||
for (var i = oldData.length - 1; i > 0; i--) {
|
||||
oldData[i].time = oldData[i - 1].time;
|
||||
@ -181,13 +293,13 @@ var AdminSocketAnalytics = AdminSocketBase.extend({
|
||||
oldData.push({time: 0, value: parseInt(newData)});
|
||||
|
||||
// remove extra items
|
||||
if (oldData.length > this._memStatsSize) {
|
||||
if (oldData.length > size) {
|
||||
oldData.shift();
|
||||
}
|
||||
},
|
||||
|
||||
_updateMemGraph: function() {
|
||||
svg = d3.select('#MemVisualisation');
|
||||
var svg = d3.select('#MemVisualisation');
|
||||
|
||||
this._setUpAxis('mem');
|
||||
|
||||
@ -202,7 +314,7 @@ var AdminSocketAnalytics = AdminSocketBase.extend({
|
||||
},
|
||||
|
||||
_updateCpuGraph: function() {
|
||||
svg = d3.select('#CpuVisualisation');
|
||||
var svg = d3.select('#CpuVisualisation');
|
||||
|
||||
this._setUpAxis('cpu');
|
||||
|
||||
@ -216,6 +328,51 @@ var AdminSocketAnalytics = AdminSocketBase.extend({
|
||||
.call(this._d3CpuYAxis);
|
||||
},
|
||||
|
||||
_updateNetGraph: function() {
|
||||
var svg = d3.select('#NetVisualisation');
|
||||
|
||||
this._setUpAxis('net');
|
||||
|
||||
svg.select('.lineSent')
|
||||
.attr('d', this._d3NetSentLine(this._sentAvgStats));
|
||||
svg.select('.lineRecv')
|
||||
.attr('d', this._d3NetRecvLine(this._recvAvgStats));
|
||||
|
||||
svg.select('.x-axis')
|
||||
.call(this._d3NetXAxis);
|
||||
|
||||
svg.select('.y-axis')
|
||||
.call(this._d3NetYAxis);
|
||||
},
|
||||
|
||||
_updateAverage: function(option, reset) {
|
||||
var data, res, tempSum;
|
||||
if (option === 'sent') {
|
||||
data = this._sentStatsData;
|
||||
res = this._sentAvgStats;
|
||||
}
|
||||
else if (option === 'recv') {
|
||||
data = this._recvStatsData;
|
||||
res = this._recvAvgStats;
|
||||
}
|
||||
|
||||
if (reset) {
|
||||
for (i = 0; i <= this._netStatsSize - this._netAvgSize; i++) {
|
||||
tempSum = 0;
|
||||
for (j = 0; j < this._netAvgSize; j++) {
|
||||
tempSum += data[i + j].value;
|
||||
}
|
||||
tempSum /= this._netAvgSize;
|
||||
res[i].value = tempSum;
|
||||
}
|
||||
}
|
||||
else {
|
||||
tempSum = res[res.length - 1].value + (data[data.length - 1].value - data[data.length - 1 - this._netAvgSize].value) / this._netAvgSize;
|
||||
|
||||
this._addNewData(res, tempSum, 'sent_avg');
|
||||
}
|
||||
},
|
||||
|
||||
onSocketMessage: function(e) {
|
||||
var textMsg;
|
||||
if (typeof e.data === 'string') {
|
||||
@ -249,6 +406,12 @@ var AdminSocketAnalytics = AdminSocketBase.extend({
|
||||
else if (setting[0] === 'cpu_stats_interval') {
|
||||
cpuStatsInterval = parseInt(setting[1]);
|
||||
}
|
||||
else if (setting[0] === 'net_stats_size') {
|
||||
this._netStatsSize = parseInt(setting[1]);
|
||||
}
|
||||
else if (setting[0] === 'net_stats_interval') {
|
||||
this._netStatsInterval = parseInt(setting[1]);
|
||||
}
|
||||
}
|
||||
|
||||
// Fix the axes according to changed data
|
||||
@ -284,6 +447,12 @@ var AdminSocketAnalytics = AdminSocketBase.extend({
|
||||
|
||||
this._cpuStatsSize = cpuStatsSize;
|
||||
this._cpuStatsInterval = cpuStatsInterval;
|
||||
|
||||
this._initStatsData('sent', this._netStatsSize, this._netStatsInterval, true);
|
||||
this._initStatsData('recv', this._netStatsSize, this._netStatsInterval, true);
|
||||
this._initStatsData('sent_avg', this._netStatsSize - this._netAvgSize + 1, this._netStatsInterval, true);
|
||||
this._initStatsData('recv_avg', this._netStatsSize - this._netAvgSize + 1, this._netStatsInterval, true);
|
||||
|
||||
}
|
||||
else if (textMsg.startsWith('mem_stats')) {
|
||||
textMsg = textMsg.split(' ')[1];
|
||||
@ -299,7 +468,7 @@ var AdminSocketAnalytics = AdminSocketBase.extend({
|
||||
else {
|
||||
// this is a notification data; append to _memStatsData
|
||||
data = textMsg.trim();
|
||||
this._addNewData(this._memStatsData, data);
|
||||
this._addNewData(this._memStatsData, data, 'mem');
|
||||
this._updateMemGraph();
|
||||
}
|
||||
}
|
||||
@ -318,10 +487,54 @@ var AdminSocketAnalytics = AdminSocketBase.extend({
|
||||
else {
|
||||
// this is a notification data; append to _cpuStatsData
|
||||
data = textMsg.trim();
|
||||
this._addNewData(this._cpuStatsData, data);
|
||||
this._addNewData(this._cpuStatsData, data, 'cpu');
|
||||
this._updateCpuGraph();
|
||||
}
|
||||
}
|
||||
else if (textMsg.startsWith('sent_activity')) {
|
||||
textMsg = textMsg.split(' ')[1];
|
||||
if (textMsg.endsWith(',')) {
|
||||
// This is the result of query, not notification
|
||||
data = textMsg.substring(0, textMsg.length - 1).split(',');
|
||||
|
||||
for (i = this._sentStatsData.length - 1, j = data.length - 1; i >= 0 && j >= 0; i--, j--) {
|
||||
this._sentStatsData[i].value = parseInt(data[j]) / this._netStatsInterval;
|
||||
}
|
||||
this._updateAverage('sent', true);
|
||||
|
||||
if ($('#NetVisualisation').html() === '')
|
||||
this._createGraph('net');
|
||||
}
|
||||
else {
|
||||
// this is a notification data; append to _sentStatsData
|
||||
data = textMsg.trim();
|
||||
this._addNewData(this._sentStatsData, parseInt(data) / this._netStatsInterval, 'sent');
|
||||
this._updateAverage('sent', false);
|
||||
this._updateNetGraph();
|
||||
}
|
||||
}
|
||||
else if (textMsg.startsWith('recv_activity')) {
|
||||
textMsg = textMsg.split(' ')[1];
|
||||
if (textMsg.endsWith(',')) {
|
||||
// This is the result of query, not notification
|
||||
data = textMsg.substring(0, textMsg.length - 1).split(',');
|
||||
|
||||
for (i = this._recvStatsData.length - 1, j = data.length - 1; i >= 0 && j >= 0; i--, j--) {
|
||||
this._recvStatsData[i].value = parseInt(data[j]) / this._netStatsInterval;
|
||||
}
|
||||
this._updateAverage('recv', true);
|
||||
|
||||
if ($('#NetVisualisation').html() === '')
|
||||
this._createGraph('net');
|
||||
}
|
||||
else {
|
||||
// this is a notification data; append to _recvStatsData
|
||||
data = textMsg.trim();
|
||||
this._addNewData(this._recvStatsData, parseInt(data) / this._netStatsInterval, 'recv');
|
||||
this._updateAverage('recv', false);
|
||||
this._updateNetGraph();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
onSocketClose: function() {
|
||||
@ -331,4 +544,4 @@ var AdminSocketAnalytics = AdminSocketBase.extend({
|
||||
|
||||
Admin.Analytics = function(host) {
|
||||
return new AdminSocketAnalytics(host);
|
||||
};
|
||||
};
|
@ -104,7 +104,9 @@ void AdminSocketHandler::handleMessage(bool /* fin */, WSOpCode /* code */,
|
||||
tokens[0] == "active_users_count" ||
|
||||
tokens[0] == "active_docs_count" ||
|
||||
tokens[0] == "mem_stats" ||
|
||||
tokens[0] == "cpu_stats")
|
||||
tokens[0] == "cpu_stats" ||
|
||||
tokens[0] == "sent_activity" ||
|
||||
tokens[0] == "recv_activity")
|
||||
{
|
||||
const std::string result = model.query(tokens[0]);
|
||||
if (!result.empty())
|
||||
@ -170,7 +172,9 @@ void AdminSocketHandler::handleMessage(bool /* fin */, WSOpCode /* code */,
|
||||
<< "mem_stats_size=" << model.query("mem_stats_size") << ' '
|
||||
<< "mem_stats_interval=" << std::to_string(_admin->getMemStatsInterval()) << ' '
|
||||
<< "cpu_stats_size=" << model.query("cpu_stats_size") << ' '
|
||||
<< "cpu_stats_interval=" << std::to_string(_admin->getCpuStatsInterval()) << ' ';
|
||||
<< "cpu_stats_interval=" << std::to_string(_admin->getCpuStatsInterval()) << ' '
|
||||
<< "net_stats_size=" << model.query("net_stats_size") << ' '
|
||||
<< "net_stats_interval=" << std::to_string(_admin->getNetStatsInterval()) << ' ';
|
||||
|
||||
const DocProcSettings& docProcSettings = _admin->getDefDocProcSettings();
|
||||
oss << "limit_virt_mem_mb=" << docProcSettings.LimitVirtMemMb << ' '
|
||||
@ -321,8 +325,11 @@ Admin::Admin() :
|
||||
_forKitWritePipe(-1),
|
||||
_lastTotalMemory(0),
|
||||
_lastJiffies(0),
|
||||
_lastSentCount(0),
|
||||
_lastRecvCount(0),
|
||||
_memStatsTaskIntervalMs(5000),
|
||||
_cpuStatsTaskIntervalMs(2000)
|
||||
_cpuStatsTaskIntervalMs(2000),
|
||||
_networkStatsIntervalMs(5000)
|
||||
{
|
||||
LOG_INF("Admin ctor.");
|
||||
|
||||
@ -338,28 +345,30 @@ Admin::~Admin()
|
||||
|
||||
void Admin::pollingThread()
|
||||
{
|
||||
std::chrono::steady_clock::time_point lastCPU, lastMem;
|
||||
std::chrono::steady_clock::time_point lastCPU, lastMem, lastNet;
|
||||
|
||||
_model.setThreadOwner(std::this_thread::get_id());
|
||||
|
||||
lastCPU = std::chrono::steady_clock::now();
|
||||
lastMem = lastCPU;
|
||||
lastNet = lastCPU;
|
||||
|
||||
while (!_stop && !TerminationFlag && !ShutdownRequestFlag)
|
||||
{
|
||||
std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
|
||||
|
||||
int cpuWait = _cpuStatsTaskIntervalMs -
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(now - lastCPU).count();
|
||||
|
||||
size_t currentJiffies = getTotalCpuUsage();
|
||||
if (cpuWait <= 0)
|
||||
{
|
||||
size_t currentJiffies = getTotalCpuUsage();
|
||||
auto cpuPercent = 100 * 1000 * currentJiffies / (sysconf (_SC_CLK_TCK) * _cpuStatsTaskIntervalMs);
|
||||
_model.addCpuStats(cpuPercent);
|
||||
|
||||
lastCPU = now;
|
||||
cpuWait += _cpuStatsTaskIntervalMs;
|
||||
}
|
||||
|
||||
int memWait = _memStatsTaskIntervalMs -
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(now - lastMem).count();
|
||||
if (memWait <= 0)
|
||||
@ -377,8 +386,25 @@ void Admin::pollingThread()
|
||||
memWait += _memStatsTaskIntervalMs;
|
||||
}
|
||||
|
||||
int netWait = _networkStatsIntervalMs -
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(now - lastNet).count();
|
||||
if(netWait <= 0)
|
||||
{
|
||||
uint64_t sentCount = _model.getSentBytesTotal();
|
||||
uint64_t recvCount = _model.getRecvBytesTotal();
|
||||
|
||||
_model.addSentStats(sentCount - _lastSentCount);
|
||||
_model.addRecvStats(recvCount - _lastRecvCount);
|
||||
|
||||
LOG_TRC("Total Data sent: " << sentCount << ", recv: " << recvCount);
|
||||
_lastRecvCount = recvCount;
|
||||
_lastSentCount = sentCount;
|
||||
|
||||
lastNet = now;
|
||||
netWait += _networkStatsIntervalMs;
|
||||
}
|
||||
// Handle websockets & other work.
|
||||
int timeout = std::min(cpuWait, memWait);
|
||||
int timeout = std::min(std::min(cpuWait, memWait), netWait);
|
||||
LOG_TRC("Admin poll for " << timeout << "ms");
|
||||
poll(timeout);
|
||||
}
|
||||
@ -463,6 +489,11 @@ unsigned Admin::getCpuStatsInterval()
|
||||
return _cpuStatsTaskIntervalMs;
|
||||
}
|
||||
|
||||
unsigned Admin::getNetStatsInterval()
|
||||
{
|
||||
return _networkStatsIntervalMs;
|
||||
}
|
||||
|
||||
AdminModel& Admin::getModel()
|
||||
{
|
||||
return _model;
|
||||
|
@ -95,6 +95,8 @@ public:
|
||||
|
||||
unsigned getCpuStatsInterval();
|
||||
|
||||
unsigned getNetStatsInterval();
|
||||
|
||||
void rescheduleMemTimer(unsigned interval);
|
||||
|
||||
void rescheduleCpuTimer(unsigned interval);
|
||||
@ -124,11 +126,13 @@ private:
|
||||
int _forKitWritePipe;
|
||||
size_t _lastTotalMemory;
|
||||
size_t _lastJiffies;
|
||||
uint64_t _lastSentCount;
|
||||
uint64_t _lastRecvCount;
|
||||
|
||||
std::atomic<int> _memStatsTaskIntervalMs;
|
||||
std::atomic<int> _cpuStatsTaskIntervalMs;
|
||||
|
||||
DocProcSettings _defDocProcSettings;
|
||||
std::atomic<int> _networkStatsIntervalMs;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -238,6 +238,18 @@ std::string AdminModel::query(const std::string& command)
|
||||
{
|
||||
return std::to_string(_cpuStatsSize);
|
||||
}
|
||||
else if (token == "sent_activity")
|
||||
{
|
||||
return getSentActivity();
|
||||
}
|
||||
else if (token == "recv_activity")
|
||||
{
|
||||
return getRecvActivity();
|
||||
}
|
||||
else if (token == "net_stats_size")
|
||||
{
|
||||
return std::to_string(std::max(_sentStatsSize, _recvStatsSize));
|
||||
}
|
||||
|
||||
return std::string("");
|
||||
}
|
||||
@ -349,6 +361,28 @@ void AdminModel::addCpuStats(unsigned cpuUsage)
|
||||
notify("cpu_stats " + std::to_string(cpuUsage));
|
||||
}
|
||||
|
||||
void AdminModel::addSentStats(uint64_t sent)
|
||||
{
|
||||
assertCorrectThread();
|
||||
|
||||
_sentStats.push_back(sent);
|
||||
if (_sentStats.size() > _sentStatsSize)
|
||||
_sentStats.pop_front();
|
||||
|
||||
notify("sent_activity " + std::to_string(sent));
|
||||
}
|
||||
|
||||
void AdminModel::addRecvStats(uint64_t recv)
|
||||
{
|
||||
assertCorrectThread();
|
||||
|
||||
_recvStats.push_back(recv);
|
||||
if (_recvStats.size() > _recvStatsSize)
|
||||
_recvStats.pop_front();
|
||||
|
||||
notify("recv_activity " + std::to_string(recv));
|
||||
}
|
||||
|
||||
void AdminModel::setCpuStatsSize(unsigned size)
|
||||
{
|
||||
assertCorrectThread();
|
||||
@ -550,6 +584,32 @@ std::string AdminModel::getCpuStats()
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string AdminModel::getSentActivity()
|
||||
{
|
||||
assertCorrectThread();
|
||||
|
||||
std::ostringstream oss;
|
||||
for (const auto& i: _sentStats)
|
||||
{
|
||||
oss << i << ',';
|
||||
}
|
||||
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string AdminModel::getRecvActivity()
|
||||
{
|
||||
assertCorrectThread();
|
||||
|
||||
std::ostringstream oss;
|
||||
for (const auto& i: _recvStats)
|
||||
{
|
||||
oss << i << ',';
|
||||
}
|
||||
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
unsigned AdminModel::getTotalActiveViews()
|
||||
{
|
||||
assertCorrectThread();
|
||||
|
@ -221,6 +221,10 @@ public:
|
||||
|
||||
void addCpuStats(unsigned cpuUsage);
|
||||
|
||||
void addSentStats(uint64_t sent);
|
||||
|
||||
void addRecvStats(uint64_t recv);
|
||||
|
||||
void setCpuStatsSize(unsigned size);
|
||||
|
||||
void setMemStatsSize(unsigned size);
|
||||
@ -243,6 +247,10 @@ public:
|
||||
private:
|
||||
std::string getMemStats();
|
||||
|
||||
std::string getSentActivity();
|
||||
|
||||
std::string getRecvActivity();
|
||||
|
||||
std::string getCpuStats();
|
||||
|
||||
unsigned getTotalActiveViews();
|
||||
@ -261,6 +269,12 @@ private:
|
||||
std::list<unsigned> _cpuStats;
|
||||
unsigned _cpuStatsSize = 100;
|
||||
|
||||
std::list<unsigned> _sentStats;
|
||||
unsigned _sentStatsSize = 100;
|
||||
|
||||
std::list<unsigned> _recvStats;
|
||||
unsigned _recvStatsSize = 100;
|
||||
|
||||
uint64_t _sentBytesTotal;
|
||||
uint64_t _recvBytesTotal;
|
||||
|
||||
|
@ -249,8 +249,8 @@ void DocumentBroker::pollThread()
|
||||
// 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)));
|
||||
(sent > adminSent ? (sent - adminSent): uint64_t(0)),
|
||||
(recv > adminRecv ? (recv - adminRecv): uint64_t(0)));
|
||||
LOG_INF("Doc [" << _docKey << "] added sent: " << sent << " recv: " << recv << " bytes to totals");
|
||||
adminSent = sent;
|
||||
adminRecv = recv;
|
||||
|
Reference in New Issue
Block a user