aprsd 3.3.3__py2.py3-none-any.whl → 3.4.0__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aprsd/client.py +133 -20
- aprsd/clients/aprsis.py +6 -3
- aprsd/clients/fake.py +1 -1
- aprsd/clients/kiss.py +1 -1
- aprsd/cmds/completion.py +13 -27
- aprsd/cmds/fetch_stats.py +53 -57
- aprsd/cmds/healthcheck.py +32 -30
- aprsd/cmds/list_plugins.py +2 -2
- aprsd/cmds/listen.py +33 -17
- aprsd/cmds/send_message.py +2 -2
- aprsd/cmds/server.py +26 -9
- aprsd/cmds/webchat.py +34 -29
- aprsd/conf/common.py +46 -31
- aprsd/log/log.py +28 -6
- aprsd/main.py +20 -18
- aprsd/packets/__init__.py +3 -2
- aprsd/packets/collector.py +56 -0
- aprsd/packets/core.py +456 -321
- aprsd/packets/log.py +143 -0
- aprsd/packets/packet_list.py +83 -66
- aprsd/packets/seen_list.py +30 -19
- aprsd/packets/tracker.py +60 -62
- aprsd/packets/watch_list.py +64 -38
- aprsd/plugin.py +41 -16
- aprsd/plugins/email.py +35 -7
- aprsd/plugins/time.py +3 -2
- aprsd/plugins/version.py +4 -5
- aprsd/plugins/weather.py +0 -1
- aprsd/stats/__init__.py +20 -0
- aprsd/stats/app.py +46 -0
- aprsd/stats/collector.py +38 -0
- aprsd/threads/__init__.py +3 -2
- aprsd/threads/aprsd.py +67 -36
- aprsd/threads/keep_alive.py +55 -49
- aprsd/threads/log_monitor.py +46 -0
- aprsd/threads/rx.py +43 -24
- aprsd/threads/stats.py +44 -0
- aprsd/threads/tx.py +36 -17
- aprsd/utils/__init__.py +12 -0
- aprsd/utils/counter.py +6 -3
- aprsd/utils/json.py +20 -0
- aprsd/utils/objectstore.py +22 -17
- aprsd/web/admin/static/css/prism.css +4 -189
- aprsd/web/admin/static/js/charts.js +9 -7
- aprsd/web/admin/static/js/echarts.js +71 -9
- aprsd/web/admin/static/js/main.js +47 -6
- aprsd/web/admin/static/js/prism.js +11 -2246
- aprsd/web/admin/templates/index.html +18 -7
- aprsd/web/chat/static/js/gps.js +3 -1
- aprsd/web/chat/static/js/main.js +4 -3
- aprsd/web/chat/static/js/send-message.js +5 -2
- aprsd/web/chat/templates/index.html +1 -0
- aprsd/wsgi.py +62 -127
- {aprsd-3.3.3.dist-info → aprsd-3.4.0.dist-info}/METADATA +14 -16
- {aprsd-3.3.3.dist-info → aprsd-3.4.0.dist-info}/RECORD +60 -65
- {aprsd-3.3.3.dist-info → aprsd-3.4.0.dist-info}/WHEEL +1 -1
- aprsd-3.4.0.dist-info/pbr.json +1 -0
- aprsd/plugins/query.py +0 -81
- aprsd/rpc/__init__.py +0 -14
- aprsd/rpc/client.py +0 -165
- aprsd/rpc/server.py +0 -99
- aprsd/stats.py +0 -266
- aprsd/threads/store.py +0 -30
- aprsd/utils/converters.py +0 -15
- aprsd/web/admin/static/json-viewer/jquery.json-viewer.css +0 -57
- aprsd/web/admin/static/json-viewer/jquery.json-viewer.js +0 -158
- aprsd/web/chat/static/json-viewer/jquery.json-viewer.css +0 -57
- aprsd/web/chat/static/json-viewer/jquery.json-viewer.js +0 -158
- aprsd-3.3.3.dist-info/pbr.json +0 -1
- {aprsd-3.3.3.dist-info → aprsd-3.4.0.dist-info}/LICENSE +0 -0
- {aprsd-3.3.3.dist-info → aprsd-3.4.0.dist-info}/entry_points.txt +0 -0
- {aprsd-3.3.3.dist-info → aprsd-3.4.0.dist-info}/top_level.txt +0 -0
aprsd/utils/json.py
CHANGED
@@ -3,6 +3,8 @@ import decimal
|
|
3
3
|
import json
|
4
4
|
import sys
|
5
5
|
|
6
|
+
from aprsd.packets import core
|
7
|
+
|
6
8
|
|
7
9
|
class EnhancedJSONEncoder(json.JSONEncoder):
|
8
10
|
def default(self, obj):
|
@@ -42,6 +44,24 @@ class EnhancedJSONEncoder(json.JSONEncoder):
|
|
42
44
|
return super().default(obj)
|
43
45
|
|
44
46
|
|
47
|
+
class SimpleJSONEncoder(json.JSONEncoder):
|
48
|
+
def default(self, obj):
|
49
|
+
if isinstance(obj, datetime.datetime):
|
50
|
+
return obj.isoformat()
|
51
|
+
elif isinstance(obj, datetime.date):
|
52
|
+
return str(obj)
|
53
|
+
elif isinstance(obj, datetime.time):
|
54
|
+
return str(obj)
|
55
|
+
elif isinstance(obj, datetime.timedelta):
|
56
|
+
return str(obj)
|
57
|
+
elif isinstance(obj, decimal.Decimal):
|
58
|
+
return str(obj)
|
59
|
+
elif isinstance(obj, core.Packet):
|
60
|
+
return obj.to_dict()
|
61
|
+
else:
|
62
|
+
return super().default(obj)
|
63
|
+
|
64
|
+
|
45
65
|
class EnhancedJSONDecoder(json.JSONDecoder):
|
46
66
|
|
47
67
|
def __init__(self, *args, **kwargs):
|
aprsd/utils/objectstore.py
CHANGED
@@ -2,6 +2,7 @@ import logging
|
|
2
2
|
import os
|
3
3
|
import pathlib
|
4
4
|
import pickle
|
5
|
+
import threading
|
5
6
|
|
6
7
|
from oslo_config import cfg
|
7
8
|
|
@@ -25,19 +26,28 @@ class ObjectStoreMixin:
|
|
25
26
|
aprsd server -f (flush) will wipe all saved objects.
|
26
27
|
"""
|
27
28
|
|
29
|
+
def __init__(self):
|
30
|
+
self.lock = threading.RLock()
|
31
|
+
|
28
32
|
def __len__(self):
|
29
|
-
|
33
|
+
with self.lock:
|
34
|
+
return len(self.data)
|
30
35
|
|
31
36
|
def __iter__(self):
|
32
|
-
|
37
|
+
with self.lock:
|
38
|
+
return iter(self.data)
|
33
39
|
|
34
40
|
def get_all(self):
|
35
41
|
with self.lock:
|
36
42
|
return self.data
|
37
43
|
|
38
|
-
def get(self,
|
44
|
+
def get(self, key):
|
45
|
+
with self.lock:
|
46
|
+
return self.data.get(key)
|
47
|
+
|
48
|
+
def copy(self):
|
39
49
|
with self.lock:
|
40
|
-
return self.data
|
50
|
+
return self.data.copy()
|
41
51
|
|
42
52
|
def _init_store(self):
|
43
53
|
if not CONF.enable_save:
|
@@ -58,31 +68,26 @@ class ObjectStoreMixin:
|
|
58
68
|
self.__class__.__name__.lower(),
|
59
69
|
)
|
60
70
|
|
61
|
-
def _dump(self):
|
62
|
-
dump = {}
|
63
|
-
with self.lock:
|
64
|
-
for key in self.data.keys():
|
65
|
-
dump[key] = self.data[key]
|
66
|
-
|
67
|
-
return dump
|
68
|
-
|
69
71
|
def save(self):
|
70
72
|
"""Save any queued to disk?"""
|
71
73
|
if not CONF.enable_save:
|
72
74
|
return
|
75
|
+
self._init_store()
|
76
|
+
save_filename = self._save_filename()
|
73
77
|
if len(self) > 0:
|
74
78
|
LOG.info(
|
75
79
|
f"{self.__class__.__name__}::Saving"
|
76
|
-
f" {len(self)} entries to disk at"
|
77
|
-
f"{
|
80
|
+
f" {len(self)} entries to disk at "
|
81
|
+
f"{save_filename}",
|
78
82
|
)
|
79
|
-
with
|
80
|
-
|
83
|
+
with self.lock:
|
84
|
+
with open(save_filename, "wb+") as fp:
|
85
|
+
pickle.dump(self.data, fp)
|
81
86
|
else:
|
82
87
|
LOG.debug(
|
83
88
|
"{} Nothing to save, flushing old save file '{}'".format(
|
84
89
|
self.__class__.__name__,
|
85
|
-
|
90
|
+
save_filename,
|
86
91
|
),
|
87
92
|
)
|
88
93
|
self.flush()
|
@@ -1,189 +1,4 @@
|
|
1
|
-
/* PrismJS 1.
|
2
|
-
https://prismjs.com/download.html#themes=prism-tomorrow&languages=markup+css+clike+javascript+log&plugins=show-language+toolbar */
|
3
|
-
|
4
|
-
|
5
|
-
* Based on https://github.com/chriskempson/tomorrow-theme
|
6
|
-
* @author Rose Pritchard
|
7
|
-
*/
|
8
|
-
|
9
|
-
code[class*="language-"],
|
10
|
-
pre[class*="language-"] {
|
11
|
-
color: #ccc;
|
12
|
-
background: none;
|
13
|
-
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
|
14
|
-
font-size: 1em;
|
15
|
-
text-align: left;
|
16
|
-
white-space: pre;
|
17
|
-
word-spacing: normal;
|
18
|
-
word-break: normal;
|
19
|
-
word-wrap: normal;
|
20
|
-
line-height: 1.5;
|
21
|
-
|
22
|
-
-moz-tab-size: 4;
|
23
|
-
-o-tab-size: 4;
|
24
|
-
tab-size: 4;
|
25
|
-
|
26
|
-
-webkit-hyphens: none;
|
27
|
-
-moz-hyphens: none;
|
28
|
-
-ms-hyphens: none;
|
29
|
-
hyphens: none;
|
30
|
-
|
31
|
-
}
|
32
|
-
|
33
|
-
/* Code blocks */
|
34
|
-
pre[class*="language-"] {
|
35
|
-
padding: 1em;
|
36
|
-
margin: .5em 0;
|
37
|
-
overflow: auto;
|
38
|
-
}
|
39
|
-
|
40
|
-
:not(pre) > code[class*="language-"],
|
41
|
-
pre[class*="language-"] {
|
42
|
-
background: #2d2d2d;
|
43
|
-
}
|
44
|
-
|
45
|
-
/* Inline code */
|
46
|
-
:not(pre) > code[class*="language-"] {
|
47
|
-
padding: .1em;
|
48
|
-
border-radius: .3em;
|
49
|
-
white-space: normal;
|
50
|
-
}
|
51
|
-
|
52
|
-
.token.comment,
|
53
|
-
.token.block-comment,
|
54
|
-
.token.prolog,
|
55
|
-
.token.doctype,
|
56
|
-
.token.cdata {
|
57
|
-
color: #999;
|
58
|
-
}
|
59
|
-
|
60
|
-
.token.punctuation {
|
61
|
-
color: #ccc;
|
62
|
-
}
|
63
|
-
|
64
|
-
.token.tag,
|
65
|
-
.token.attr-name,
|
66
|
-
.token.namespace,
|
67
|
-
.token.deleted {
|
68
|
-
color: #e2777a;
|
69
|
-
}
|
70
|
-
|
71
|
-
.token.function-name {
|
72
|
-
color: #6196cc;
|
73
|
-
}
|
74
|
-
|
75
|
-
.token.boolean,
|
76
|
-
.token.number,
|
77
|
-
.token.function {
|
78
|
-
color: #f08d49;
|
79
|
-
}
|
80
|
-
|
81
|
-
.token.property,
|
82
|
-
.token.class-name,
|
83
|
-
.token.constant,
|
84
|
-
.token.symbol {
|
85
|
-
color: #f8c555;
|
86
|
-
}
|
87
|
-
|
88
|
-
.token.selector,
|
89
|
-
.token.important,
|
90
|
-
.token.atrule,
|
91
|
-
.token.keyword,
|
92
|
-
.token.builtin {
|
93
|
-
color: #cc99cd;
|
94
|
-
}
|
95
|
-
|
96
|
-
.token.string,
|
97
|
-
.token.char,
|
98
|
-
.token.attr-value,
|
99
|
-
.token.regex,
|
100
|
-
.token.variable {
|
101
|
-
color: #7ec699;
|
102
|
-
}
|
103
|
-
|
104
|
-
.token.operator,
|
105
|
-
.token.entity,
|
106
|
-
.token.url {
|
107
|
-
color: #67cdcc;
|
108
|
-
}
|
109
|
-
|
110
|
-
.token.important,
|
111
|
-
.token.bold {
|
112
|
-
font-weight: bold;
|
113
|
-
}
|
114
|
-
.token.italic {
|
115
|
-
font-style: italic;
|
116
|
-
}
|
117
|
-
|
118
|
-
.token.entity {
|
119
|
-
cursor: help;
|
120
|
-
}
|
121
|
-
|
122
|
-
.token.inserted {
|
123
|
-
color: green;
|
124
|
-
}
|
125
|
-
|
126
|
-
div.code-toolbar {
|
127
|
-
position: relative;
|
128
|
-
}
|
129
|
-
|
130
|
-
div.code-toolbar > .toolbar {
|
131
|
-
position: absolute;
|
132
|
-
top: .3em;
|
133
|
-
right: .2em;
|
134
|
-
transition: opacity 0.3s ease-in-out;
|
135
|
-
opacity: 0;
|
136
|
-
}
|
137
|
-
|
138
|
-
div.code-toolbar:hover > .toolbar {
|
139
|
-
opacity: 1;
|
140
|
-
}
|
141
|
-
|
142
|
-
/* Separate line b/c rules are thrown out if selector is invalid.
|
143
|
-
IE11 and old Edge versions don't support :focus-within. */
|
144
|
-
div.code-toolbar:focus-within > .toolbar {
|
145
|
-
opacity: 1;
|
146
|
-
}
|
147
|
-
|
148
|
-
div.code-toolbar > .toolbar > .toolbar-item {
|
149
|
-
display: inline-block;
|
150
|
-
}
|
151
|
-
|
152
|
-
div.code-toolbar > .toolbar > .toolbar-item > a {
|
153
|
-
cursor: pointer;
|
154
|
-
}
|
155
|
-
|
156
|
-
div.code-toolbar > .toolbar > .toolbar-item > button {
|
157
|
-
background: none;
|
158
|
-
border: 0;
|
159
|
-
color: inherit;
|
160
|
-
font: inherit;
|
161
|
-
line-height: normal;
|
162
|
-
overflow: visible;
|
163
|
-
padding: 0;
|
164
|
-
-webkit-user-select: none; /* for button */
|
165
|
-
-moz-user-select: none;
|
166
|
-
-ms-user-select: none;
|
167
|
-
}
|
168
|
-
|
169
|
-
div.code-toolbar > .toolbar > .toolbar-item > a,
|
170
|
-
div.code-toolbar > .toolbar > .toolbar-item > button,
|
171
|
-
div.code-toolbar > .toolbar > .toolbar-item > span {
|
172
|
-
color: #bbb;
|
173
|
-
font-size: .8em;
|
174
|
-
padding: 0 .5em;
|
175
|
-
background: #f5f2f0;
|
176
|
-
background: rgba(224, 224, 224, 0.2);
|
177
|
-
box-shadow: 0 2px 0 0 rgba(0,0,0,0.2);
|
178
|
-
border-radius: .5em;
|
179
|
-
}
|
180
|
-
|
181
|
-
div.code-toolbar > .toolbar > .toolbar-item > a:hover,
|
182
|
-
div.code-toolbar > .toolbar > .toolbar-item > a:focus,
|
183
|
-
div.code-toolbar > .toolbar > .toolbar-item > button:hover,
|
184
|
-
div.code-toolbar > .toolbar > .toolbar-item > button:focus,
|
185
|
-
div.code-toolbar > .toolbar > .toolbar-item > span:hover,
|
186
|
-
div.code-toolbar > .toolbar > .toolbar-item > span:focus {
|
187
|
-
color: inherit;
|
188
|
-
text-decoration: none;
|
189
|
-
}
|
1
|
+
/* PrismJS 1.29.0
|
2
|
+
https://prismjs.com/download.html#themes=prism-tomorrow&languages=markup+css+clike+javascript+json+json5+log&plugins=show-language+toolbar */
|
3
|
+
code[class*=language-],pre[class*=language-]{color:#ccc;background:0 0;font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#2d2d2d}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.block-comment,.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#999}.token.punctuation{color:#ccc}.token.attr-name,.token.deleted,.token.namespace,.token.tag{color:#e2777a}.token.function-name{color:#6196cc}.token.boolean,.token.function,.token.number{color:#f08d49}.token.class-name,.token.constant,.token.property,.token.symbol{color:#f8c555}.token.atrule,.token.builtin,.token.important,.token.keyword,.token.selector{color:#cc99cd}.token.attr-value,.token.char,.token.regex,.token.string,.token.variable{color:#7ec699}.token.entity,.token.operator,.token.url{color:#67cdcc}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}.token.inserted{color:green}
|
4
|
+
div.code-toolbar{position:relative}div.code-toolbar>.toolbar{position:absolute;z-index:10;top:.3em;right:.2em;transition:opacity .3s ease-in-out;opacity:0}div.code-toolbar:hover>.toolbar{opacity:1}div.code-toolbar:focus-within>.toolbar{opacity:1}div.code-toolbar>.toolbar>.toolbar-item{display:inline-block}div.code-toolbar>.toolbar>.toolbar-item>a{cursor:pointer}div.code-toolbar>.toolbar>.toolbar-item>button{background:0 0;border:0;color:inherit;font:inherit;line-height:normal;overflow:visible;padding:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}div.code-toolbar>.toolbar>.toolbar-item>a,div.code-toolbar>.toolbar>.toolbar-item>button,div.code-toolbar>.toolbar>.toolbar-item>span{color:#bbb;font-size:.8em;padding:0 .5em;background:#f5f2f0;background:rgba(224,224,224,.2);box-shadow:0 2px 0 0 rgba(0,0,0,.2);border-radius:.5em}div.code-toolbar>.toolbar>.toolbar-item>a:focus,div.code-toolbar>.toolbar>.toolbar-item>a:hover,div.code-toolbar>.toolbar>.toolbar-item>button:focus,div.code-toolbar>.toolbar>.toolbar-item>button:hover,div.code-toolbar>.toolbar>.toolbar-item>span:focus,div.code-toolbar>.toolbar>.toolbar-item>span:hover{color:inherit;text-decoration:none}
|
@@ -219,15 +219,17 @@ function updateQuadData(chart, label, first, second, third, fourth) {
|
|
219
219
|
}
|
220
220
|
|
221
221
|
function update_stats( data ) {
|
222
|
-
our_callsign = data["
|
223
|
-
$("#version").text( data["
|
222
|
+
our_callsign = data["APRSDStats"]["callsign"];
|
223
|
+
$("#version").text( data["APRSDStats"]["version"] );
|
224
224
|
$("#aprs_connection").html( data["aprs_connection"] );
|
225
|
-
$("#uptime").text( "uptime: " + data["
|
225
|
+
$("#uptime").text( "uptime: " + data["APRSDStats"]["uptime"] );
|
226
226
|
const html_pretty = Prism.highlight(JSON.stringify(data, null, '\t'), Prism.languages.json, 'json');
|
227
227
|
$("#jsonstats").html(html_pretty);
|
228
228
|
short_time = data["time"].split(/\s(.+)/)[1];
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
229
|
+
packet_list = data["PacketList"]["packets"];
|
230
|
+
updateDualData(packets_chart, short_time, data["PacketList"]["sent"], data["PacketList"]["received"]);
|
231
|
+
updateQuadData(message_chart, short_time, packet_list["MessagePacket"]["tx"], packet_list["MessagePacket"]["rx"],
|
232
|
+
packet_list["AckPacket"]["tx"], packet_list["AckPacket"]["rx"]);
|
233
|
+
updateDualData(email_chart, short_time, data["EmailStats"]["sent"], data["EmailStats"]["recieved"]);
|
234
|
+
updateDualData(memory_chart, short_time, data["APRSDStats"]["memory_peak"], data["APRSDStats"]["memory_current"]);
|
233
235
|
}
|
@@ -8,6 +8,8 @@ var packet_types_data = {};
|
|
8
8
|
var mem_current = []
|
9
9
|
var mem_peak = []
|
10
10
|
|
11
|
+
var thread_current = []
|
12
|
+
|
11
13
|
|
12
14
|
function start_charts() {
|
13
15
|
console.log("start_charts() called");
|
@@ -17,6 +19,7 @@ function start_charts() {
|
|
17
19
|
create_messages_chart();
|
18
20
|
create_ack_chart();
|
19
21
|
create_memory_chart();
|
22
|
+
create_thread_chart();
|
20
23
|
}
|
21
24
|
|
22
25
|
|
@@ -258,6 +261,49 @@ function create_memory_chart() {
|
|
258
261
|
memory_chart.setOption(option);
|
259
262
|
}
|
260
263
|
|
264
|
+
function create_thread_chart() {
|
265
|
+
thread_canvas = document.getElementById('threadChart');
|
266
|
+
thread_chart = echarts.init(thread_canvas);
|
267
|
+
|
268
|
+
// Specify the configuration items and data for the chart
|
269
|
+
var option = {
|
270
|
+
title: {
|
271
|
+
text: 'Active Threads'
|
272
|
+
},
|
273
|
+
legend: {},
|
274
|
+
tooltip: {
|
275
|
+
trigger: 'axis'
|
276
|
+
},
|
277
|
+
toolbox: {
|
278
|
+
show: true,
|
279
|
+
feature: {
|
280
|
+
mark : {show: true},
|
281
|
+
dataView : {show: true, readOnly: false},
|
282
|
+
magicType : {show: true, type: ['line', 'bar']},
|
283
|
+
restore : {show: true},
|
284
|
+
saveAsImage : {show: true}
|
285
|
+
}
|
286
|
+
},
|
287
|
+
calculable: true,
|
288
|
+
xAxis: { type: 'time' },
|
289
|
+
yAxis: { },
|
290
|
+
series: [
|
291
|
+
{
|
292
|
+
name: 'current',
|
293
|
+
type: 'line',
|
294
|
+
smooth: true,
|
295
|
+
color: 'red',
|
296
|
+
encode: {
|
297
|
+
x: 'timestamp',
|
298
|
+
y: 'current' // refer sensor 1 value
|
299
|
+
}
|
300
|
+
}
|
301
|
+
]
|
302
|
+
};
|
303
|
+
|
304
|
+
thread_chart.setOption(option);
|
305
|
+
}
|
306
|
+
|
261
307
|
|
262
308
|
|
263
309
|
|
@@ -327,7 +373,6 @@ function updatePacketTypesChart() {
|
|
327
373
|
option = {
|
328
374
|
series: series
|
329
375
|
}
|
330
|
-
console.log(option)
|
331
376
|
packet_types_chart.setOption(option);
|
332
377
|
}
|
333
378
|
|
@@ -372,6 +417,21 @@ function updateMemChart(time, current, peak) {
|
|
372
417
|
memory_chart.setOption(option);
|
373
418
|
}
|
374
419
|
|
420
|
+
function updateThreadChart(time, threads) {
|
421
|
+
keys = Object.keys(threads);
|
422
|
+
thread_count = keys.length;
|
423
|
+
thread_current.push([time, thread_count]);
|
424
|
+
option = {
|
425
|
+
series: [
|
426
|
+
{
|
427
|
+
name: 'current',
|
428
|
+
data: thread_current,
|
429
|
+
}
|
430
|
+
]
|
431
|
+
}
|
432
|
+
thread_chart.setOption(option);
|
433
|
+
}
|
434
|
+
|
375
435
|
function updateMessagesChart() {
|
376
436
|
updateTypeChart(message_chart, "MessagePacket")
|
377
437
|
}
|
@@ -381,22 +441,24 @@ function updateAcksChart() {
|
|
381
441
|
}
|
382
442
|
|
383
443
|
function update_stats( data ) {
|
384
|
-
console.log(
|
385
|
-
|
386
|
-
|
387
|
-
$("#
|
388
|
-
$("#
|
444
|
+
console.log("update_stats() echarts.js called")
|
445
|
+
stats = data["stats"];
|
446
|
+
our_callsign = stats["APRSDStats"]["callsign"];
|
447
|
+
$("#version").text( stats["APRSDStats"]["version"] );
|
448
|
+
$("#aprs_connection").html( stats["aprs_connection"] );
|
449
|
+
$("#uptime").text( "uptime: " + stats["APRSDStats"]["uptime"] );
|
389
450
|
const html_pretty = Prism.highlight(JSON.stringify(data, null, '\t'), Prism.languages.json, 'json');
|
390
451
|
$("#jsonstats").html(html_pretty);
|
391
452
|
|
392
453
|
t = Date.parse(data["time"]);
|
393
454
|
ts = new Date(t);
|
394
|
-
updatePacketData(packets_chart, ts,
|
395
|
-
updatePacketTypesData(ts,
|
455
|
+
updatePacketData(packets_chart, ts, stats["PacketList"]["tx"], stats["PacketList"]["rx"]);
|
456
|
+
updatePacketTypesData(ts, stats["PacketList"]["types"]);
|
396
457
|
updatePacketTypesChart();
|
397
458
|
updateMessagesChart();
|
398
459
|
updateAcksChart();
|
399
|
-
updateMemChart(ts,
|
460
|
+
updateMemChart(ts, stats["APRSDStats"]["memory_current"], stats["APRSDStats"]["memory_peak"]);
|
461
|
+
updateThreadChart(ts, stats["APRSDThreadList"]);
|
400
462
|
//updateQuadData(message_chart, short_time, data["stats"]["messages"]["sent"], data["stats"]["messages"]["received"], data["stats"]["messages"]["ack_sent"], data["stats"]["messages"]["ack_recieved"]);
|
401
463
|
//updateDualData(email_chart, short_time, data["stats"]["email"]["sent"], data["stats"]["email"]["recieved"]);
|
402
464
|
//updateDualData(memory_chart, short_time, data["stats"]["aprsd"]["memory_peak"], data["stats"]["aprsd"]["memory_current"]);
|
@@ -24,11 +24,15 @@ function ord(str){return str.charCodeAt(0);}
|
|
24
24
|
|
25
25
|
|
26
26
|
function update_watchlist( data ) {
|
27
|
-
|
27
|
+
// Update the watch list
|
28
|
+
stats = data["stats"];
|
29
|
+
if (stats.hasOwnProperty("WatchList") == false) {
|
30
|
+
return
|
31
|
+
}
|
28
32
|
var watchdiv = $("#watchDiv");
|
29
33
|
var html_str = '<table class="ui celled striped table"><thead><tr><th>HAM Callsign</th><th>Age since last seen by APRSD</th></tr></thead><tbody>'
|
30
34
|
watchdiv.html('')
|
31
|
-
jQuery.each(
|
35
|
+
jQuery.each(stats["WatchList"], function(i, val) {
|
32
36
|
html_str += '<tr><td class="collapsing"><img id="callsign_'+i+'" class="aprsd_1"></img>' + i + '</td><td>' + val["last"] + '</td></tr>'
|
33
37
|
});
|
34
38
|
html_str += "</tbody></table>";
|
@@ -60,12 +64,16 @@ function update_watchlist_from_packet(callsign, val) {
|
|
60
64
|
}
|
61
65
|
|
62
66
|
function update_seenlist( data ) {
|
67
|
+
stats = data["stats"];
|
68
|
+
if (stats.hasOwnProperty("SeenList") == false) {
|
69
|
+
return
|
70
|
+
}
|
63
71
|
var seendiv = $("#seenDiv");
|
64
72
|
var html_str = '<table class="ui celled striped table">'
|
65
73
|
html_str += '<thead><tr><th>HAM Callsign</th><th>Age since last seen by APRSD</th>'
|
66
74
|
html_str += '<th>Number of packets RX</th></tr></thead><tbody>'
|
67
75
|
seendiv.html('')
|
68
|
-
var seen_list =
|
76
|
+
var seen_list = stats["SeenList"]
|
69
77
|
var len = Object.keys(seen_list).length
|
70
78
|
$('#seen_count').html(len)
|
71
79
|
jQuery.each(seen_list, function(i, val) {
|
@@ -79,6 +87,10 @@ function update_seenlist( data ) {
|
|
79
87
|
}
|
80
88
|
|
81
89
|
function update_plugins( data ) {
|
90
|
+
stats = data["stats"];
|
91
|
+
if (stats.hasOwnProperty("PluginManager") == false) {
|
92
|
+
return
|
93
|
+
}
|
82
94
|
var plugindiv = $("#pluginDiv");
|
83
95
|
var html_str = '<table class="ui celled striped table"><thead><tr>'
|
84
96
|
html_str += '<th>Plugin Name</th><th>Plugin Enabled?</th>'
|
@@ -87,7 +99,7 @@ function update_plugins( data ) {
|
|
87
99
|
html_str += '</tr></thead><tbody>'
|
88
100
|
plugindiv.html('')
|
89
101
|
|
90
|
-
var plugins =
|
102
|
+
var plugins = stats["PluginManager"];
|
91
103
|
var keys = Object.keys(plugins);
|
92
104
|
keys.sort();
|
93
105
|
for (var i=0; i<keys.length; i++) { // now lets iterate in sort order
|
@@ -101,14 +113,42 @@ function update_plugins( data ) {
|
|
101
113
|
plugindiv.append(html_str);
|
102
114
|
}
|
103
115
|
|
116
|
+
function update_threads( data ) {
|
117
|
+
stats = data["stats"];
|
118
|
+
if (stats.hasOwnProperty("APRSDThreadList") == false) {
|
119
|
+
return
|
120
|
+
}
|
121
|
+
var threadsdiv = $("#threadsDiv");
|
122
|
+
var countdiv = $("#thread_count");
|
123
|
+
var html_str = '<table class="ui celled striped table"><thead><tr>'
|
124
|
+
html_str += '<th>Thread Name</th><th>Alive?</th>'
|
125
|
+
html_str += '<th>Age</th><th>Loop Count</th>'
|
126
|
+
html_str += '</tr></thead><tbody>'
|
127
|
+
threadsdiv.html('')
|
128
|
+
|
129
|
+
var threads = stats["APRSDThreadList"];
|
130
|
+
var keys = Object.keys(threads);
|
131
|
+
countdiv.html(keys.length);
|
132
|
+
keys.sort();
|
133
|
+
for (var i=0; i<keys.length; i++) { // now lets iterate in sort order
|
134
|
+
var key = keys[i];
|
135
|
+
var val = threads[key];
|
136
|
+
html_str += '<tr><td class="collapsing">' + key + '</td>';
|
137
|
+
html_str += '<td>' + val["alive"] + '</td><td>' + val["age"] + '</td>';
|
138
|
+
html_str += '<td>' + val["loop_count"] + '</td></tr>';
|
139
|
+
}
|
140
|
+
html_str += "</tbody></table>";
|
141
|
+
threadsdiv.append(html_str);
|
142
|
+
}
|
143
|
+
|
104
144
|
function update_packets( data ) {
|
105
145
|
var packetsdiv = $("#packetsDiv");
|
106
146
|
//nuke the contents first, then add to it.
|
107
147
|
if (size_dict(packet_list) == 0 && size_dict(data) > 0) {
|
108
148
|
packetsdiv.html('')
|
109
149
|
}
|
110
|
-
jQuery.each(data, function(i, val) {
|
111
|
-
pkt =
|
150
|
+
jQuery.each(data.packets, function(i, val) {
|
151
|
+
pkt = val;
|
112
152
|
|
113
153
|
update_watchlist_from_packet(pkt['from_call'], pkt);
|
114
154
|
if ( packet_list.hasOwnProperty(pkt['timestamp']) == false ) {
|
@@ -167,6 +207,7 @@ function start_update() {
|
|
167
207
|
update_watchlist(data);
|
168
208
|
update_seenlist(data);
|
169
209
|
update_plugins(data);
|
210
|
+
update_threads(data);
|
170
211
|
},
|
171
212
|
complete: function() {
|
172
213
|
setTimeout(statsworker, 10000);
|