mirror of
https://github.com/craigerl/aprsd.git
synced 2024-11-18 06:11:49 -05:00
Fixed pep8 errors and missing files
This commit is contained in:
parent
bd005f628d
commit
a270c75263
@ -25,6 +25,7 @@ TRANSPORT_FAKE = "fake"
|
||||
# Correct config
|
||||
factory = None
|
||||
|
||||
|
||||
@singleton
|
||||
class APRSClientStats:
|
||||
def stats(self):
|
||||
|
@ -39,7 +39,7 @@ class WatchList(objectstore.ObjectStoreMixin):
|
||||
# is all we can do.
|
||||
self.data[call] = {
|
||||
"last": None,
|
||||
"packet": None,
|
||||
"packet": None,
|
||||
}
|
||||
|
||||
@wrapt.synchronized(lock)
|
||||
|
@ -391,7 +391,9 @@ class PluginManager:
|
||||
try:
|
||||
module_name, class_name = module_class_string.rsplit(".", 1)
|
||||
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:
|
||||
if not module_name:
|
||||
LOG.error(f"Failed to load Plugin {module_class_string}")
|
||||
|
@ -81,8 +81,10 @@ class EmailStats:
|
||||
|
||||
def tx_inc(self):
|
||||
self.tx += 1
|
||||
|
||||
def rx_inc(self):
|
||||
self.rx += 1
|
||||
|
||||
def email_thread_update(self):
|
||||
self.email_thread_last_time = datetime.datetime.now()
|
||||
|
||||
@ -217,10 +219,6 @@ class EmailPlugin(plugin.APRSDRegexCommandPluginBase):
|
||||
def _imap_connect():
|
||||
imap_port = CONF.email_plugin.imap_port
|
||||
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:
|
||||
server = imapclient.IMAPClient(
|
||||
|
19
aprsd/stats/__init__.py
Normal file
19
aprsd/stats/__init__.py
Normal file
@ -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())
|
34
aprsd/stats/app.py
Normal file
34
aprsd/stats/app.py
Normal file
@ -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
|
29
aprsd/stats/collector.py
Normal file
29
aprsd/stats/collector.py
Normal file
@ -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
|
||||
APRSDDupeRXThread, APRSDProcessPacketThread, APRSDRXThread,
|
||||
)
|
||||
from .stats import APRSDStatsStoreThread
|
||||
from .stats import APRSDStatsStoreThread # noqa: F401
|
||||
|
||||
|
||||
packet_queue = queue.Queue(maxsize=20)
|
||||
|
@ -27,7 +27,6 @@ class KeepAliveThread(APRSDThread):
|
||||
def loop(self):
|
||||
if self.loop_count % 60 == 0:
|
||||
stats_json = collector.Collector().collect()
|
||||
#LOG.debug(stats_json)
|
||||
pl = packets.PacketList()
|
||||
thread_list = APRSDThreadList()
|
||||
now = datetime.datetime.now()
|
||||
@ -53,11 +52,10 @@ class KeepAliveThread(APRSDThread):
|
||||
tx_msg = 0
|
||||
rx_msg = 0
|
||||
if "PacketList" in stats_json:
|
||||
msg_packets = stats_json["PacketList"].get("MessagePacket")
|
||||
if msg_packets:
|
||||
tx_msg = msg_packets.get("tx", 0)
|
||||
rx_msg = msg_packets.get("rx", 0)
|
||||
|
||||
msg_packets = stats_json["PacketList"].get("MessagePacket")
|
||||
if msg_packets:
|
||||
tx_msg = msg_packets.get("tx", 0)
|
||||
rx_msg = msg_packets.get("rx", 0)
|
||||
|
||||
keepalive = (
|
||||
"{} - Uptime {} RX:{} TX:{} Tracker:{} Msgs TX:{} RX:{} "
|
||||
|
38
aprsd/threads/stats.py
Normal file
38
aprsd/threads/stats.py
Normal file
@ -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
Block a user