mirror of https://github.com/craigerl/aprsd.git
Fixed pep8 errors and missing files
This commit is contained in:
parent
bd005f628d
commit
a270c75263
|
@ -25,6 +25,7 @@ TRANSPORT_FAKE = "fake"
|
||||||
# Correct config
|
# Correct config
|
||||||
factory = None
|
factory = None
|
||||||
|
|
||||||
|
|
||||||
@singleton
|
@singleton
|
||||||
class APRSClientStats:
|
class APRSClientStats:
|
||||||
def stats(self):
|
def stats(self):
|
||||||
|
|
|
@ -39,7 +39,7 @@ class WatchList(objectstore.ObjectStoreMixin):
|
||||||
# is all we can do.
|
# is all we can do.
|
||||||
self.data[call] = {
|
self.data[call] = {
|
||||||
"last": None,
|
"last": None,
|
||||||
"packet": None,
|
"packet": None,
|
||||||
}
|
}
|
||||||
|
|
||||||
@wrapt.synchronized(lock)
|
@wrapt.synchronized(lock)
|
||||||
|
|
|
@ -391,7 +391,9 @@ class PluginManager:
|
||||||
try:
|
try:
|
||||||
module_name, class_name = module_class_string.rsplit(".", 1)
|
module_name, class_name = module_class_string.rsplit(".", 1)
|
||||||
module = importlib.import_module(module_name)
|
module = importlib.import_module(module_name)
|
||||||
#module = importlib.reload(module)
|
# Commented out because the email thread starts in a different context
|
||||||
|
# and hence gives a different singleton for the EmailStats
|
||||||
|
# module = importlib.reload(module)
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
if not module_name:
|
if not module_name:
|
||||||
LOG.error(f"Failed to load Plugin {module_class_string}")
|
LOG.error(f"Failed to load Plugin {module_class_string}")
|
||||||
|
|
|
@ -81,8 +81,10 @@ class EmailStats:
|
||||||
|
|
||||||
def tx_inc(self):
|
def tx_inc(self):
|
||||||
self.tx += 1
|
self.tx += 1
|
||||||
|
|
||||||
def rx_inc(self):
|
def rx_inc(self):
|
||||||
self.rx += 1
|
self.rx += 1
|
||||||
|
|
||||||
def email_thread_update(self):
|
def email_thread_update(self):
|
||||||
self.email_thread_last_time = datetime.datetime.now()
|
self.email_thread_last_time = datetime.datetime.now()
|
||||||
|
|
||||||
|
@ -217,10 +219,6 @@ class EmailPlugin(plugin.APRSDRegexCommandPluginBase):
|
||||||
def _imap_connect():
|
def _imap_connect():
|
||||||
imap_port = CONF.email_plugin.imap_port
|
imap_port = CONF.email_plugin.imap_port
|
||||||
use_ssl = CONF.email_plugin.imap_use_ssl
|
use_ssl = CONF.email_plugin.imap_use_ssl
|
||||||
# host = CONFIG["aprsd"]["email"]["imap"]["host"]
|
|
||||||
# msg = "{}{}:{}".format("TLS " if use_ssl else "", host, imap_port)
|
|
||||||
# LOG.debug("Connect to IMAP host {} with user '{}'".
|
|
||||||
# format(msg, CONFIG['imap']['login']))
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
server = imapclient.IMAPClient(
|
server = imapclient.IMAPClient(
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
from aprsd import client as aprs_client
|
||||||
|
from aprsd import plugin
|
||||||
|
from aprsd.packets import packet_list, tracker, watch_list
|
||||||
|
from aprsd.plugins import email
|
||||||
|
from aprsd.stats import app, collector
|
||||||
|
from aprsd.threads import aprsd
|
||||||
|
|
||||||
|
|
||||||
|
# Create the collector and register all the objects
|
||||||
|
# that APRSD has that implement the stats protocol
|
||||||
|
stats_collector = collector.Collector()
|
||||||
|
stats_collector.register_producer(app.APRSDStats())
|
||||||
|
stats_collector.register_producer(packet_list.PacketList())
|
||||||
|
stats_collector.register_producer(watch_list.WatchList())
|
||||||
|
stats_collector.register_producer(tracker.PacketTrack())
|
||||||
|
stats_collector.register_producer(plugin.PluginManager())
|
||||||
|
stats_collector.register_producer(aprsd.APRSDThreadList())
|
||||||
|
stats_collector.register_producer(email.EmailStats())
|
||||||
|
stats_collector.register_producer(aprs_client.APRSClientStats())
|
|
@ -0,0 +1,34 @@
|
||||||
|
import datetime
|
||||||
|
import tracemalloc
|
||||||
|
|
||||||
|
from oslo_config import cfg
|
||||||
|
|
||||||
|
import aprsd
|
||||||
|
from aprsd import utils
|
||||||
|
|
||||||
|
|
||||||
|
CONF = cfg.CONF
|
||||||
|
|
||||||
|
|
||||||
|
@utils.singleton
|
||||||
|
class APRSDStats:
|
||||||
|
"""The AppStats class is used to collect stats from the application."""
|
||||||
|
def __init__(self):
|
||||||
|
self.start_time = datetime.datetime.now()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def uptime(self):
|
||||||
|
return datetime.datetime.now() - self.start_time
|
||||||
|
|
||||||
|
def stats(self) -> dict:
|
||||||
|
current, peak = tracemalloc.get_traced_memory()
|
||||||
|
stats = {
|
||||||
|
"version": aprsd.__version__,
|
||||||
|
"uptime": self.uptime,
|
||||||
|
"callsign": CONF.callsign,
|
||||||
|
"memory_current": int(current),
|
||||||
|
"memory_current_str": utils.human_size(current),
|
||||||
|
"memory_peak": int(peak),
|
||||||
|
"memory_peak_str": utils.human_size(peak),
|
||||||
|
}
|
||||||
|
return stats
|
|
@ -0,0 +1,29 @@
|
||||||
|
from typing import Protocol
|
||||||
|
|
||||||
|
from aprsd.utils import singleton
|
||||||
|
|
||||||
|
|
||||||
|
class StatsProducer(Protocol):
|
||||||
|
"""The StatsProducer protocol is used to define the interface for collecting stats."""
|
||||||
|
def stats(self) -> dict:
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
@singleton
|
||||||
|
class Collector:
|
||||||
|
"""The Collector class is used to collect stats from multiple StatsProducer instances."""
|
||||||
|
def __init__(self):
|
||||||
|
self.producers: dict[str, StatsProducer] = {}
|
||||||
|
|
||||||
|
def collect(self):
|
||||||
|
stats = {}
|
||||||
|
for name, producer in self.producers.items():
|
||||||
|
# No need to put in empty stats
|
||||||
|
tmp_stats = producer.stats()
|
||||||
|
if tmp_stats:
|
||||||
|
stats[name] = tmp_stats
|
||||||
|
return stats
|
||||||
|
|
||||||
|
def register_producer(self, producer: StatsProducer):
|
||||||
|
name = producer.__class__.__name__
|
||||||
|
self.producers[name] = producer
|
|
@ -7,7 +7,7 @@ from .keep_alive import KeepAliveThread # noqa: F401
|
||||||
from .rx import ( # noqa: F401
|
from .rx import ( # noqa: F401
|
||||||
APRSDDupeRXThread, APRSDProcessPacketThread, APRSDRXThread,
|
APRSDDupeRXThread, APRSDProcessPacketThread, APRSDRXThread,
|
||||||
)
|
)
|
||||||
from .stats import APRSDStatsStoreThread
|
from .stats import APRSDStatsStoreThread # noqa: F401
|
||||||
|
|
||||||
|
|
||||||
packet_queue = queue.Queue(maxsize=20)
|
packet_queue = queue.Queue(maxsize=20)
|
||||||
|
|
|
@ -27,7 +27,6 @@ class KeepAliveThread(APRSDThread):
|
||||||
def loop(self):
|
def loop(self):
|
||||||
if self.loop_count % 60 == 0:
|
if self.loop_count % 60 == 0:
|
||||||
stats_json = collector.Collector().collect()
|
stats_json = collector.Collector().collect()
|
||||||
#LOG.debug(stats_json)
|
|
||||||
pl = packets.PacketList()
|
pl = packets.PacketList()
|
||||||
thread_list = APRSDThreadList()
|
thread_list = APRSDThreadList()
|
||||||
now = datetime.datetime.now()
|
now = datetime.datetime.now()
|
||||||
|
@ -53,11 +52,10 @@ class KeepAliveThread(APRSDThread):
|
||||||
tx_msg = 0
|
tx_msg = 0
|
||||||
rx_msg = 0
|
rx_msg = 0
|
||||||
if "PacketList" in stats_json:
|
if "PacketList" in stats_json:
|
||||||
msg_packets = stats_json["PacketList"].get("MessagePacket")
|
msg_packets = stats_json["PacketList"].get("MessagePacket")
|
||||||
if msg_packets:
|
if msg_packets:
|
||||||
tx_msg = msg_packets.get("tx", 0)
|
tx_msg = msg_packets.get("tx", 0)
|
||||||
rx_msg = msg_packets.get("rx", 0)
|
rx_msg = msg_packets.get("rx", 0)
|
||||||
|
|
||||||
|
|
||||||
keepalive = (
|
keepalive = (
|
||||||
"{} - Uptime {} RX:{} TX:{} Tracker:{} Msgs TX:{} RX:{} "
|
"{} - Uptime {} RX:{} TX:{} Tracker:{} Msgs TX:{} RX:{} "
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
import logging
|
||||||
|
import threading
|
||||||
|
import time
|
||||||
|
|
||||||
|
from oslo_config import cfg
|
||||||
|
|
||||||
|
from aprsd.stats import collector
|
||||||
|
from aprsd.threads import APRSDThread
|
||||||
|
from aprsd.utils import objectstore
|
||||||
|
|
||||||
|
|
||||||
|
CONF = cfg.CONF
|
||||||
|
LOG = logging.getLogger("APRSD")
|
||||||
|
|
||||||
|
|
||||||
|
class StatsStore(objectstore.ObjectStoreMixin):
|
||||||
|
"""Container to save the stats from the collector."""
|
||||||
|
lock = threading.Lock()
|
||||||
|
|
||||||
|
|
||||||
|
class APRSDStatsStoreThread(APRSDThread):
|
||||||
|
"""Save APRSD Stats to disk periodically."""
|
||||||
|
|
||||||
|
# how often in seconds to write the file
|
||||||
|
save_interval = 10
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("StatsStore")
|
||||||
|
|
||||||
|
def loop(self):
|
||||||
|
if self.loop_count % self.save_interval == 0:
|
||||||
|
stats = collector.Collector().collect()
|
||||||
|
ss = StatsStore()
|
||||||
|
ss.data = stats
|
||||||
|
ss.save()
|
||||||
|
|
||||||
|
time.sleep(1)
|
||||||
|
return True
|
|
@ -1,54 +0,0 @@
|
||||||
from unittest import mock
|
|
||||||
|
|
||||||
from oslo_config import cfg
|
|
||||||
|
|
||||||
from aprsd import packets
|
|
||||||
from aprsd.packets import tracker
|
|
||||||
from aprsd.plugins import query as query_plugin
|
|
||||||
|
|
||||||
from .. import fake, test_plugin
|
|
||||||
|
|
||||||
|
|
||||||
CONF = cfg.CONF
|
|
||||||
|
|
||||||
|
|
||||||
class TestQueryPlugin(test_plugin.TestPlugin):
|
|
||||||
@mock.patch("aprsd.packets.tracker.PacketTrack.flush")
|
|
||||||
def test_query_flush(self, mock_flush):
|
|
||||||
packet = fake.fake_packet(message="!delete")
|
|
||||||
CONF.callsign = fake.FAKE_TO_CALLSIGN
|
|
||||||
CONF.save_enabled = True
|
|
||||||
CONF.query_plugin.callsign = fake.FAKE_FROM_CALLSIGN
|
|
||||||
query = query_plugin.QueryPlugin()
|
|
||||||
query.enabled = True
|
|
||||||
|
|
||||||
expected = "Deleted ALL pending msgs."
|
|
||||||
actual = query.filter(packet)
|
|
||||||
mock_flush.assert_called_once()
|
|
||||||
self.assertEqual(expected, actual)
|
|
||||||
|
|
||||||
@mock.patch("aprsd.packets.tracker.PacketTrack.restart_delayed")
|
|
||||||
def test_query_restart_delayed(self, mock_restart):
|
|
||||||
CONF.callsign = fake.FAKE_TO_CALLSIGN
|
|
||||||
CONF.save_enabled = True
|
|
||||||
CONF.query_plugin.callsign = fake.FAKE_FROM_CALLSIGN
|
|
||||||
track = tracker.PacketTrack()
|
|
||||||
track.data = {}
|
|
||||||
packet = fake.fake_packet(message="!4")
|
|
||||||
query = query_plugin.QueryPlugin()
|
|
||||||
|
|
||||||
expected = "No pending msgs to resend"
|
|
||||||
actual = query.filter(packet)
|
|
||||||
mock_restart.assert_not_called()
|
|
||||||
self.assertEqual(expected, actual)
|
|
||||||
mock_restart.reset_mock()
|
|
||||||
|
|
||||||
# add a message
|
|
||||||
pkt = packets.MessagePacket(
|
|
||||||
from_call=self.fromcall,
|
|
||||||
to_call="testing",
|
|
||||||
msgNo=self.ack,
|
|
||||||
)
|
|
||||||
track.add(pkt)
|
|
||||||
actual = query.filter(packet)
|
|
||||||
mock_restart.assert_called_once()
|
|
Loading…
Reference in New Issue