mirror of
https://github.com/craigerl/aprsd.git
synced 2024-12-24 19:00:44 -05:00
Updated web stats index to show messages and ram usage
This patch updates the main index page to show both the graph of tx/rx messages as well as peak/current ram usage.
This commit is contained in:
parent
f211e5cabb
commit
c7d10f53a3
@ -5,6 +5,9 @@ APRSD
|
|||||||
.. image:: https://badge.fury.io/py/aprsd.svg
|
.. image:: https://badge.fury.io/py/aprsd.svg
|
||||||
:target: https://badge.fury.io/py/aprsd
|
:target: https://badge.fury.io/py/aprsd
|
||||||
|
|
||||||
|
.. image:: http://hits.dwyl.com/craigerl/aprsd.svg
|
||||||
|
:target: http://hits.dwyl.com/craigerl/aprsd
|
||||||
|
|
||||||
.. image:: https://github.com/craigerl/aprsd/workflows/python/badge.svg
|
.. image:: https://github.com/craigerl/aprsd/workflows/python/badge.svg
|
||||||
:target: https://github.com/craigerl/aprsd/actions
|
:target: https://github.com/craigerl/aprsd/actions
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
|
import datetime
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
|
import tracemalloc
|
||||||
|
|
||||||
import aprsd
|
import aprsd
|
||||||
from aprsd import messaging, plugin, stats
|
from aprsd import messaging, plugin, stats
|
||||||
@ -69,12 +71,17 @@ class APRSDFlask(flask_classful.FlaskView):
|
|||||||
def stats(self):
|
def stats(self):
|
||||||
stats_obj = stats.APRSDStats()
|
stats_obj = stats.APRSDStats()
|
||||||
track = messaging.MsgTrack()
|
track = messaging.MsgTrack()
|
||||||
|
now = datetime.datetime.now()
|
||||||
|
current, peak = tracemalloc.get_traced_memory()
|
||||||
|
|
||||||
result = {
|
result = {
|
||||||
"version": aprsd.__version__,
|
"version": aprsd.__version__,
|
||||||
"uptime": stats_obj.uptime,
|
"uptime": stats_obj.uptime,
|
||||||
"size_tracker": len(track),
|
"size_tracker": len(track),
|
||||||
"stats": stats_obj.stats(),
|
"stats": stats_obj.stats(),
|
||||||
|
"time": now.strftime("%m-%d-%Y %H:%M:%S"),
|
||||||
|
"memory_current": current,
|
||||||
|
"memory_peak": peak,
|
||||||
}
|
}
|
||||||
return json.dumps(result)
|
return json.dumps(result)
|
||||||
|
|
||||||
|
@ -26,6 +26,9 @@ class APRSDStats:
|
|||||||
_email_tx = 0
|
_email_tx = 0
|
||||||
_email_rx = 0
|
_email_rx = 0
|
||||||
|
|
||||||
|
_mem_current = 0
|
||||||
|
_mem_peak = 0
|
||||||
|
|
||||||
def __new__(cls, *args, **kwargs):
|
def __new__(cls, *args, **kwargs):
|
||||||
if cls._instance is None:
|
if cls._instance is None:
|
||||||
cls._instance = super().__new__(cls)
|
cls._instance = super().__new__(cls)
|
||||||
@ -43,6 +46,24 @@ class APRSDStats:
|
|||||||
with self.lock:
|
with self.lock:
|
||||||
return str(datetime.datetime.now() - self.start_time)
|
return str(datetime.datetime.now() - self.start_time)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def memory(self):
|
||||||
|
with self.lock:
|
||||||
|
return self._mem_current
|
||||||
|
|
||||||
|
def set_memory(self, memory):
|
||||||
|
with self.lock:
|
||||||
|
self._mem_curent = memory
|
||||||
|
|
||||||
|
@property
|
||||||
|
def memory_peak(self):
|
||||||
|
with self.lock:
|
||||||
|
return self._mem_peak
|
||||||
|
|
||||||
|
def set_memory_peak(self, memory):
|
||||||
|
with self.lock:
|
||||||
|
self._mem_peak = memory
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def msgs_tx(self):
|
def msgs_tx(self):
|
||||||
with self.lock:
|
with self.lock:
|
||||||
@ -126,6 +147,11 @@ class APRSDStats:
|
|||||||
|
|
||||||
def stats(self):
|
def stats(self):
|
||||||
now = datetime.datetime.now()
|
now = datetime.datetime.now()
|
||||||
|
if self._email_thread_last_time:
|
||||||
|
last_update = str(now - self._email_thread_last_time)
|
||||||
|
else:
|
||||||
|
last_update = "never"
|
||||||
|
|
||||||
stats = {
|
stats = {
|
||||||
"messages": {
|
"messages": {
|
||||||
"tracked": self.msgs_tracked,
|
"tracked": self.msgs_tracked,
|
||||||
@ -138,7 +164,7 @@ class APRSDStats:
|
|||||||
"email": {
|
"email": {
|
||||||
"sent": self._email_tx,
|
"sent": self._email_tx,
|
||||||
"recieved": self._email_rx,
|
"recieved": self._email_rx,
|
||||||
"thread_last_update": str(now - self._email_thread_last_time),
|
"thread_last_update": last_update,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return stats
|
return stats
|
||||||
|
@ -84,6 +84,8 @@ class KeepAliveThread(APRSDThread):
|
|||||||
email_thread_time = "N/A"
|
email_thread_time = "N/A"
|
||||||
|
|
||||||
current, peak = tracemalloc.get_traced_memory()
|
current, peak = tracemalloc.get_traced_memory()
|
||||||
|
stats_obj.set_memory(current)
|
||||||
|
stats_obj.set_memory_peak(peak)
|
||||||
LOG.debug(
|
LOG.debug(
|
||||||
"Uptime ({}) Tracker({}) "
|
"Uptime ({}) Tracker({}) "
|
||||||
"Msgs: TX:{} RX:{} EmailThread: {} RAM: Current:{} Peak:{}".format(
|
"Msgs: TX:{} RX:{} EmailThread: {} RAM: Current:{} Peak:{}".format(
|
||||||
|
@ -1,14 +1,133 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
||||||
|
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css">
|
||||||
|
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
|
||||||
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.23.0/prism.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.23.0/prism.min.js"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.23.0/components/prism-json.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.23.0/components/prism-json.js"></script>
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs@1.23.0/themes/prism-tomorrow.css">
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs@1.23.0/themes/prism-tomorrow.css">
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.4/dist/Chart.bundle.js"></script>
|
||||||
|
|
||||||
|
|
||||||
<script type="text/javascript"">
|
<script type="text/javascript"">
|
||||||
|
|
||||||
|
var memory_chart = null
|
||||||
|
var message_chart = null
|
||||||
|
var color = Chart.helpers.color;
|
||||||
|
|
||||||
|
window.chartColors = {
|
||||||
|
red: 'rgb(255, 99, 132)',
|
||||||
|
orange: 'rgb(255, 159, 64)',
|
||||||
|
yellow: 'rgb(255, 205, 86)',
|
||||||
|
green: 'rgb(26, 181, 77)',
|
||||||
|
blue: 'rgb(54, 162, 235)',
|
||||||
|
purple: 'rgb(153, 102, 255)',
|
||||||
|
grey: 'rgb(201, 203, 207)'
|
||||||
|
};
|
||||||
|
|
||||||
|
function start_charts() {
|
||||||
|
memory_chart = new Chart($("#memChart"), {
|
||||||
|
label: 'Memory Usage',
|
||||||
|
type: 'line',
|
||||||
|
data: {
|
||||||
|
labels: [],
|
||||||
|
datasets: [{
|
||||||
|
label: 'Peak Ram usage',
|
||||||
|
borderColor: window.chartColors.red,
|
||||||
|
data: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Current Ram usage',
|
||||||
|
borderColor: window.chartColors.blue,
|
||||||
|
data: [],
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
responsive: true,
|
||||||
|
maintainAspectRation: false,
|
||||||
|
scales: {
|
||||||
|
x: {
|
||||||
|
type: 'timeseries',
|
||||||
|
offset: true,
|
||||||
|
ticks: {
|
||||||
|
major: { enabled: true },
|
||||||
|
fontStyle: context => context.tick.major ? 'bold' : undefined,
|
||||||
|
source: 'data',
|
||||||
|
maxRotation: 0,
|
||||||
|
autoSkip: true,
|
||||||
|
autoSkipPadding: 75,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
message_chart = new Chart($("#messageChart"), {
|
||||||
|
label: 'Messages',
|
||||||
|
type: 'line',
|
||||||
|
data: {
|
||||||
|
labels: [],
|
||||||
|
datasets: [{
|
||||||
|
label: 'Messages Sent',
|
||||||
|
borderColor: window.chartColors.green,
|
||||||
|
data: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Messages Recieved',
|
||||||
|
borderColor: window.chartColors.yellow,
|
||||||
|
data: [],
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
responsive: true,
|
||||||
|
maintainAspectRation: false,
|
||||||
|
scales: {
|
||||||
|
x: {
|
||||||
|
type: 'timeseries',
|
||||||
|
offset: true,
|
||||||
|
ticks: {
|
||||||
|
major: { enabled: true },
|
||||||
|
fontStyle: context => context.tick.major ? 'bold' : undefined,
|
||||||
|
source: 'data',
|
||||||
|
maxRotation: 0,
|
||||||
|
autoSkip: true,
|
||||||
|
autoSkipPadding: 75,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function addData(chart, label, newdata) {
|
||||||
|
chart.data.labels.push(label);
|
||||||
|
chart.data.datasets.forEach((dataset) => {
|
||||||
|
dataset.data.push(newdata);
|
||||||
|
});
|
||||||
|
chart.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateDualData(chart, label, first, second) {
|
||||||
|
chart.data.labels.push(label);
|
||||||
|
chart.data.datasets[0].data.push(first);
|
||||||
|
chart.data.datasets[1].data.push(second);
|
||||||
|
chart.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
function update_stats( data ) {
|
||||||
|
$("#version").text( data["version"] );
|
||||||
|
$("#uptime").text( "uptime: " + data["uptime"] );
|
||||||
|
const html_pretty = Prism.highlight(JSON.stringify(data, null, '\t'), Prism.languages.json, 'json');
|
||||||
|
$("#jsonstats").html(html_pretty);
|
||||||
|
//$("#jsonstats").effect("highlight", {color: "#333333"}, 800);
|
||||||
|
//console.log(data);
|
||||||
|
updateDualData(memory_chart, data["time"], data["memory_peak"], data["memory_current"]);
|
||||||
|
updateDualData(message_chart, data["time"], data["stats"]["messages"]["sent"], data["stats"]["messages"]["recieved"]);
|
||||||
|
}
|
||||||
|
|
||||||
function start_update() {
|
function start_update() {
|
||||||
|
|
||||||
(function statsworker() {
|
(function statsworker() {
|
||||||
@ -17,12 +136,10 @@
|
|||||||
type: 'GET',
|
type: 'GET',
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
//data = JSON.parse(response)
|
update_stats(data);
|
||||||
const html_pretty = Prism.highlight(JSON.stringify(data, null, '\t'), Prism.languages.json, 'json');
|
|
||||||
$("#app").html(html_pretty)
|
|
||||||
},
|
},
|
||||||
complete: function() {
|
complete: function() {
|
||||||
setTimeout(statsworker, 60000);
|
setTimeout(statsworker, 10000);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
@ -30,15 +147,106 @@
|
|||||||
|
|
||||||
|
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
$("#app").text("Starting PEEPIS")
|
|
||||||
start_update();
|
start_update();
|
||||||
|
start_charts();
|
||||||
|
|
||||||
|
$("#toggleStats").click(function() {
|
||||||
|
$("#jsonstats").fadeToggle(1000);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
display: grid;
|
||||||
|
grid-template-rows: auto 1fr auto;
|
||||||
|
background: #eeeeee;
|
||||||
|
margin: 2em;
|
||||||
|
padding: 0;
|
||||||
|
text-align: center;
|
||||||
|
font-family: system-ui, sans-serif;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
header {
|
||||||
|
padding: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer, .push {
|
||||||
|
padding: 2rem;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#messageChart {
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
background: #ddd;
|
||||||
|
height: 10vh;
|
||||||
|
}
|
||||||
|
#memChart {
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
background: #ddd;
|
||||||
|
height: 10vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
#graphs {
|
||||||
|
display: grid;
|
||||||
|
width: 100%;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
}
|
||||||
|
#left {
|
||||||
|
border: 1px solid black;
|
||||||
|
margin: 2px;
|
||||||
|
}
|
||||||
|
#right {
|
||||||
|
border: 1px solid black;
|
||||||
|
margin: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#stats {
|
||||||
|
margin: auto;
|
||||||
|
width: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#jsonstats {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#title {
|
||||||
|
font-size: 4em;
|
||||||
|
}
|
||||||
|
#uptime: {
|
||||||
|
font-size: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<pre id="app" class="language-json">{{ stats }}</pre>
|
<header>
|
||||||
<canvas id="messsageChart"></canvas>
|
<div id="title">APRSD version <span id="version"></div></div>
|
||||||
|
<div id="uptime"></div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<div id="graphs">
|
||||||
|
<div id="left"><canvas id="messageChart"></canvas></div>
|
||||||
|
<div id="right"><canvas class="right" id="memChart"></canvas></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="stats">
|
||||||
|
<button id="toggleStats">Toggle raw json</button>
|
||||||
|
<pre id="jsonstats" class="language-json">{{ stats }}</pre>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<footer>
|
||||||
|
<a href="https://badge.fury.io/py/aprsd"><img src="https://badge.fury.io/py/aprsd.svg" alt="PyPI version" height="18"></a>
|
||||||
|
<a href="https://github.com/craigerl/aprsd"><img src="https://img.shields.io/badge/Made%20with-Python-1f425f.svg" height="18"></a>
|
||||||
|
</footer>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
Loading…
Reference in New Issue
Block a user