diff --git a/aprsd/cmds/listen.py b/aprsd/cmds/listen.py index 646d3c9..0c2ab0e 100644 --- a/aprsd/cmds/listen.py +++ b/aprsd/cmds/listen.py @@ -10,12 +10,13 @@ import sys import time import click +from loguru import logger from oslo_config import cfg from rich.console import Console # local imports here import aprsd -from aprsd import cli_helper, packets, plugin, threads +from aprsd import cli_helper, packets, plugin, threads, utils from aprsd.client import client_factory from aprsd.main import cli from aprsd.packets import collector as packet_collector @@ -24,12 +25,14 @@ from aprsd.packets import seen_list from aprsd.stats import collector from aprsd.threads import keep_alive, rx from aprsd.threads import stats as stats_thread +from aprsd.threads.aprsd import APRSDThread # setup the global logger # log.basicConfig(level=log.DEBUG) # level=10 LOG = logging.getLogger("APRSD") CONF = cfg.CONF +LOGU = logger console = Console() @@ -88,6 +91,37 @@ class APRSDListenThread(rx.APRSDRXThread): packet_collector.PacketCollector().rx(packet) +class ListenStatsThread(APRSDThread): + """Log the stats from the PacketList.""" + + def __init__(self): + super().__init__("SimpleStatsLog") + self._last_total_rx = 0 + + def loop(self): + if self.loop_count % 10 == 0: + # log the stats every 10 seconds + stats_json = collector.Collector().collect() + stats = stats_json["PacketList"] + total_rx = stats["rx"] + rate = (total_rx - self._last_total_rx) / 10 + LOGU.opt(colors=True).info( + f"RX Rate: {rate} pps " + f"Total RX: {total_rx} " + f"RX Last 10 secs: {total_rx - self._last_total_rx}", + ) + self._last_total_rx = total_rx + for k, v in stats["types"].items(): + thread_hex = f"fg {utils.hex_from_name(k)}" + LOGU.opt(colors=True).info( + f"<{thread_hex}>{k:<15} " + f"RX: {v['rx']} TX: {v['tx']}", + ) + + time.sleep(1) + return True + + @cli.command() @cli_helper.add_options(cli_helper.common_options) @click.option( @@ -195,7 +229,6 @@ def listen( aprs_client.set_filter(filter) keepalive = keep_alive.KeepAliveThread() - # keepalive.start() if not CONF.enable_seen_list: # just deregister the class from the packet collector @@ -222,6 +255,8 @@ def listen( ) LOG.debug("Start APRSDListenThread") listen_thread.start() + listen_stats = ListenStatsThread() + listen_stats.start() keepalive.start() LOG.debug("keepalive Join") diff --git a/aprsd/stats/collector.py b/aprsd/stats/collector.py index c3da428..d899031 100644 --- a/aprsd/stats/collector.py +++ b/aprsd/stats/collector.py @@ -35,3 +35,8 @@ class Collector: if not isinstance(producer_name, StatsProducer): raise TypeError(f"Producer {producer_name} is not a StatsProducer") self.producers.append(producer_name) + + def unregister_producer(self, producer_name: Callable): + if not isinstance(producer_name, StatsProducer): + raise TypeError(f"Producer {producer_name} is not a StatsProducer") + self.producers.remove(producer_name)