mirror of https://github.com/craigerl/aprsd.git
Updated the charts Added the packets chart
This patch adds the APRS Packets chart to the charts admin ui. Also moves the raw json as it's own tab
This commit is contained in:
parent
be8179415a
commit
6740ff80be
|
@ -121,6 +121,13 @@ class APRSDFlask(flask_classful.FlaskView):
|
||||||
}
|
}
|
||||||
|
|
||||||
stats_dict["aprsd"]["watch_list"] = new_list
|
stats_dict["aprsd"]["watch_list"] = new_list
|
||||||
|
packet_list = packets.PacketList()
|
||||||
|
rx = packet_list.total_received()
|
||||||
|
tx = packet_list.total_sent()
|
||||||
|
stats_dict["packets"] = {
|
||||||
|
"sent": tx,
|
||||||
|
"received": rx,
|
||||||
|
}
|
||||||
|
|
||||||
result = {
|
result = {
|
||||||
"time": now.strftime(time_format),
|
"time": now.strftime(time_format),
|
||||||
|
|
|
@ -32,7 +32,18 @@ import time
|
||||||
|
|
||||||
# local imports here
|
# local imports here
|
||||||
import aprsd
|
import aprsd
|
||||||
from aprsd import client, email, flask, messaging, plugin, stats, threads, trace, utils
|
from aprsd import (
|
||||||
|
client,
|
||||||
|
email,
|
||||||
|
flask,
|
||||||
|
messaging,
|
||||||
|
packets,
|
||||||
|
plugin,
|
||||||
|
stats,
|
||||||
|
threads,
|
||||||
|
trace,
|
||||||
|
utils,
|
||||||
|
)
|
||||||
import aprslib
|
import aprslib
|
||||||
from aprslib.exceptions import LoginError
|
from aprslib.exceptions import LoginError
|
||||||
import click
|
import click
|
||||||
|
@ -519,6 +530,7 @@ def server(
|
||||||
"enabled",
|
"enabled",
|
||||||
True,
|
True,
|
||||||
):
|
):
|
||||||
|
packets.PacketList(config)
|
||||||
notify_thread = threads.APRSDNotifyThread(
|
notify_thread = threads.APRSDNotifyThread(
|
||||||
msg_queues=msg_queues,
|
msg_queues=msg_queues,
|
||||||
config=config,
|
config=config,
|
||||||
|
|
|
@ -16,9 +16,13 @@ class PacketList:
|
||||||
"""Class to track all of the packets rx'd and tx'd by aprsd."""
|
"""Class to track all of the packets rx'd and tx'd by aprsd."""
|
||||||
|
|
||||||
_instance = None
|
_instance = None
|
||||||
|
config = None
|
||||||
|
|
||||||
packet_list = {}
|
packet_list = {}
|
||||||
|
|
||||||
|
total_recv = 0
|
||||||
|
total_tx = 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)
|
||||||
|
@ -26,6 +30,10 @@ class PacketList:
|
||||||
cls._instance.lock = threading.Lock()
|
cls._instance.lock = threading.Lock()
|
||||||
return cls._instance
|
return cls._instance
|
||||||
|
|
||||||
|
def __init__(self, config=None):
|
||||||
|
if config:
|
||||||
|
self.config = config
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
with self.lock:
|
with self.lock:
|
||||||
return iter(self.packet_list)
|
return iter(self.packet_list)
|
||||||
|
@ -33,12 +41,22 @@ class PacketList:
|
||||||
def add(self, packet):
|
def add(self, packet):
|
||||||
with self.lock:
|
with self.lock:
|
||||||
packet["ts"] = time.time()
|
packet["ts"] = time.time()
|
||||||
|
if "from" in packet and packet["from"] == self.config["aprs"]["login"]:
|
||||||
|
self.total_tx += 1
|
||||||
|
else:
|
||||||
|
self.total_recv += 1
|
||||||
self.packet_list.append(packet)
|
self.packet_list.append(packet)
|
||||||
|
|
||||||
def get(self):
|
def get(self):
|
||||||
with self.lock:
|
with self.lock:
|
||||||
return self.packet_list.get()
|
return self.packet_list.get()
|
||||||
|
|
||||||
|
def total_received(self):
|
||||||
|
return self.total_recv
|
||||||
|
|
||||||
|
def total_sent(self):
|
||||||
|
return self.total_tx
|
||||||
|
|
||||||
|
|
||||||
class WatchList:
|
class WatchList:
|
||||||
"""Global watch list and info for callsigns."""
|
"""Global watch list and info for callsigns."""
|
||||||
|
|
|
@ -38,7 +38,7 @@ footer {
|
||||||
#center {
|
#center {
|
||||||
height: 300px;
|
height: 300px;
|
||||||
}
|
}
|
||||||
#messageChart, #emailChart, #memChart {
|
#packetsChart, #messageChart, #emailChart, #memChart {
|
||||||
border: 1px solid #ccc;
|
border: 1px solid #ccc;
|
||||||
background: #ddd;
|
background: #ddd;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,10 @@ window.chartColors = {
|
||||||
blue: 'rgb(54, 162, 235)',
|
blue: 'rgb(54, 162, 235)',
|
||||||
purple: 'rgb(153, 102, 255)',
|
purple: 'rgb(153, 102, 255)',
|
||||||
grey: 'rgb(201, 203, 207)',
|
grey: 'rgb(201, 203, 207)',
|
||||||
black: 'rgb(0, 0, 0)'
|
black: 'rgb(0, 0, 0)',
|
||||||
|
lightcoral: 'rgb(240,128,128)',
|
||||||
|
darkseagreen: 'rgb(143, 188,143)'
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function size_dict(d){c=0; for (i in d) ++c; return c}
|
function size_dict(d){c=0; for (i in d) ++c; return c}
|
||||||
|
@ -20,28 +23,28 @@ function start_charts() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
memory_chart = new Chart($("#memChart"), {
|
packets_chart = new Chart($("#packetsChart"), {
|
||||||
label: 'Memory Usage',
|
label: 'APRS Packets',
|
||||||
type: 'line',
|
type: 'line',
|
||||||
data: {
|
data: {
|
||||||
labels: [],
|
labels: [],
|
||||||
datasets: [{
|
datasets: [{
|
||||||
label: 'Peak Ram usage',
|
label: 'Packets Sent',
|
||||||
borderColor: window.chartColors.red,
|
borderColor: window.chartColors.lightcoral,
|
||||||
data: [],
|
data: [],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Current Ram usage',
|
label: 'Packets Recieved',
|
||||||
borderColor: window.chartColors.blue,
|
borderColor: window.chartColors.darkseagreen,
|
||||||
data: [],
|
data: [],
|
||||||
}],
|
}]
|
||||||
},
|
},
|
||||||
options: {
|
options: {
|
||||||
responsive: true,
|
responsive: true,
|
||||||
maintainAspectRatio: false,
|
maintainAspectRatio: false,
|
||||||
title: {
|
title: {
|
||||||
display: true,
|
display: true,
|
||||||
text: 'Memory Usage',
|
text: 'APRS Packets',
|
||||||
},
|
},
|
||||||
scales: {
|
scales: {
|
||||||
x: {
|
x: {
|
||||||
|
@ -67,12 +70,12 @@ function start_charts() {
|
||||||
labels: [],
|
labels: [],
|
||||||
datasets: [{
|
datasets: [{
|
||||||
label: 'Messages Sent',
|
label: 'Messages Sent',
|
||||||
borderColor: window.chartColors.green,
|
borderColor: window.chartColors.lightcoral,
|
||||||
data: [],
|
data: [],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Messages Recieved',
|
label: 'Messages Recieved',
|
||||||
borderColor: window.chartColors.yellow,
|
borderColor: window.chartColors.darkseagreen,
|
||||||
data: [],
|
data: [],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -117,12 +120,12 @@ function start_charts() {
|
||||||
labels: [],
|
labels: [],
|
||||||
datasets: [{
|
datasets: [{
|
||||||
label: 'Sent',
|
label: 'Sent',
|
||||||
borderColor: window.chartColors.green,
|
borderColor: window.chartColors.lightcoral,
|
||||||
data: [],
|
data: [],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Recieved',
|
label: 'Recieved',
|
||||||
borderColor: window.chartColors.yellow,
|
borderColor: window.chartColors.darkseagreen,
|
||||||
data: [],
|
data: [],
|
||||||
}],
|
}],
|
||||||
},
|
},
|
||||||
|
@ -149,6 +152,46 @@ 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,
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
title: {
|
||||||
|
display: true,
|
||||||
|
text: 'Memory Usage',
|
||||||
|
},
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -182,6 +225,7 @@ function update_stats( data ) {
|
||||||
const html_pretty = Prism.highlight(JSON.stringify(data, null, '\t'), Prism.languages.json, 'json');
|
const html_pretty = Prism.highlight(JSON.stringify(data, null, '\t'), Prism.languages.json, 'json');
|
||||||
$("#jsonstats").html(html_pretty);
|
$("#jsonstats").html(html_pretty);
|
||||||
short_time = data["time"].split(/\s(.+)/)[1];
|
short_time = data["time"].split(/\s(.+)/)[1];
|
||||||
|
updateDualData(packets_chart, short_time, data["stats"]["packets"]["sent"], data["stats"]["packets"]["received"]);
|
||||||
updateQuadData(message_chart, short_time, data["stats"]["messages"]["sent"], data["stats"]["messages"]["recieved"], data["stats"]["messages"]["ack_sent"], data["stats"]["messages"]["ack_recieved"]);
|
updateQuadData(message_chart, short_time, data["stats"]["messages"]["sent"], data["stats"]["messages"]["recieved"], data["stats"]["messages"]["ack_sent"], data["stats"]["messages"]["ack_recieved"]);
|
||||||
updateDualData(email_chart, short_time, data["stats"]["email"]["sent"], data["stats"]["email"]["recieved"]);
|
updateDualData(email_chart, short_time, data["stats"]["email"]["sent"], data["stats"]["email"]["recieved"]);
|
||||||
updateDualData(memory_chart, short_time, data["stats"]["aprsd"]["memory_peak"], data["stats"]["aprsd"]["memory_current"]);
|
updateDualData(memory_chart, short_time, data["stats"]["aprsd"]["memory_peak"], data["stats"]["aprsd"]["memory_current"]);
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
var cfg_pretty = JSON.stringify(cfg_json, null, '\t');
|
var cfg_pretty = JSON.stringify(cfg_json, null, '\t');
|
||||||
const html_pretty = Prism.highlight( cfg_pretty, Prism.languages.json, 'json');
|
const html_pretty = Prism.highlight( cfg_pretty, Prism.languages.json, 'json');
|
||||||
$("#configjson").html(html_pretty);
|
$("#configjson").html(html_pretty);
|
||||||
|
$("#jsonstats").fadeToggle(1000);
|
||||||
|
|
||||||
$('.ui.accordion').accordion({exclusive: false});
|
$('.ui.accordion').accordion({exclusive: false});
|
||||||
$('.menu .item').tab('change tab', 'charts-tab');
|
$('.menu .item').tab('change tab', 'charts-tab');
|
||||||
|
@ -71,22 +72,45 @@
|
||||||
<div class="item" data-tab="msgs-tab">Messages</div>
|
<div class="item" data-tab="msgs-tab">Messages</div>
|
||||||
<div class="item" data-tab="watch-tab">Watch List</div>
|
<div class="item" data-tab="watch-tab">Watch List</div>
|
||||||
<div class="item" data-tab="config-tab">Config</div>
|
<div class="item" data-tab="config-tab">Config</div>
|
||||||
|
<div class="item" data-tab="raw-tab">Raw JSON</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Tab content -->
|
<!-- Tab content -->
|
||||||
<div class="ui bottom attached active tab segment" data-tab="charts-tab">
|
<div class="ui bottom attached active tab segment" data-tab="charts-tab">
|
||||||
<h3 class="ui dividing header">Charts</h3>
|
<h3 class="ui dividing header">Charts</h3>
|
||||||
<div id="graphs">
|
<div class="ui equal width relaxed grid">
|
||||||
<div id="left"><canvas id="messageChart"></canvas></div>
|
<div class="row">
|
||||||
<div id="right"><canvas class="right" id="emailChart"></canvas></div>
|
<div class="column">
|
||||||
</div>
|
<div class="ui segment" style="height: 300px">
|
||||||
<div id="graphs_center">
|
<canvas id="packetsChart"></canvas>
|
||||||
<div id="center"><canvas id="memChart"></canvas></div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="stats">
|
<div class="column">
|
||||||
<button class="ui button" id="toggleStats">Toggle raw json</button>
|
<div class="ui segment" style="height: 300px">
|
||||||
<pre id="jsonstats" class="language-json">{{ stats }}</pre>
|
<canvas id="messageChart"></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="column">
|
||||||
|
<div class="ui segment" style="height: 300px">
|
||||||
|
<canvas id="emailChart"></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="column">
|
||||||
|
<div class="ui segment" style="height: 300px">
|
||||||
|
<canvas id="memChart"></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- <div class="row">
|
||||||
|
<div id="stats" class="two column">
|
||||||
|
<button class="ui button" id="toggleStats">Toggle raw json</button>
|
||||||
|
<pre id="jsonstats" class="language-json">{{ stats }}</pre>
|
||||||
|
</div> --!>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="ui bottom attached tab segment" data-tab="msgs-tab">
|
<div class="ui bottom attached tab segment" data-tab="msgs-tab">
|
||||||
|
@ -110,6 +134,11 @@
|
||||||
<pre id="configjson" class="language-json">{{ config_json|safe }}</pre>
|
<pre id="configjson" class="language-json">{{ config_json|safe }}</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="ui bottom attached tab segment" data-tab="raw-tab">
|
||||||
|
<h3 class="ui dividing header">Raw JSON</h3>
|
||||||
|
<pre id="jsonstats" class="language-json">{{ stats|safe }}</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="ui text container">
|
<div class="ui text container">
|
||||||
<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://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>
|
<a href="https://github.com/craigerl/aprsd"><img src="https://img.shields.io/badge/Made%20with-Python-1f425f.svg" height="18"></a>
|
||||||
|
|
Loading…
Reference in New Issue