1
0
mirror of https://github.com/craigerl/aprsd.git synced 2025-12-04 18:13:38 -05:00
aprsd/aprsd/stats.py
Hemna 1a1fcba1c4 Add new watchlist feature
This patch adds a new optional feature called Watch list.
Aprsd will filter IN all aprs packets from a list of callsigns.
APRSD will keep track of the last time a callsign has been seen.
When the configured timeout value has been reached, the next time
a callsign is seen, APRSD will send the next packet from that callsign
through the new notification plugins list.

The new BaseNotifyPlugin is the default core APRSD notify based plugin.
When it gets a packet it will construct a reply message to be sent
to the configured alert callsign to alert them that the seen callsign
is now on the APRS network.

This basically acts as a notification that your watched callsign list is
available on APRS.

The new configuration options:
aprsd:
    watch_list:
        # The callsign to send a message to once a watch list callsign
        # is now seen on APRS-IS
        alert_callsign: NOCALL
        # The time in seconds to wait for notification.
        # The default is 12 hours.
        alert_time_seconds: 43200
        # The list of callsigns to watch for
        callsigns:
          - WB4BOR
          - KFART
        # Enable/disable this feature
        enabled: false
        # The list of notify based plugins to load for
        # processing a new seen packet from a callsign.
        enabled_plugins:
        - aprsd.plugins.notify.BaseNotifyPlugin

This patch also adds a new section in the Admin UI for showing the
watch list and the age of the last seen packet for each callsing since
APRSD startup.
2021-07-16 08:31:38 -04:00

255 lines
6.2 KiB
Python

import datetime
import logging
import threading
import aprsd
from aprsd import plugin, utils
LOG = logging.getLogger("APRSD")
class APRSDStats:
_instance = None
lock = None
config = None
start_time = None
_aprsis_server = None
_aprsis_keepalive = None
_msgs_tracked = 0
_msgs_tx = 0
_msgs_rx = 0
_msgs_mice_rx = 0
_ack_tx = 0
_ack_rx = 0
_email_thread_last_time = None
_email_tx = 0
_email_rx = 0
_mem_current = 0
_mem_peak = 0
_watch_list = {}
def __new__(cls, *args, **kwargs):
if cls._instance is None:
cls._instance = super().__new__(cls)
# any initializetion here
cls._instance.lock = threading.Lock()
cls._instance.start_time = datetime.datetime.now()
cls._instance._aprsis_keepalive = datetime.datetime.now()
return cls._instance
def __init__(self, config=None):
if config:
self.config = config
@property
def uptime(self):
with self.lock:
return datetime.datetime.now() - self.start_time
@property
def memory(self):
with self.lock:
return self._mem_current
def set_memory(self, memory):
with self.lock:
self._mem_current = memory
@property
def memory_peak(self):
with self.lock:
return self._mem_peak
def set_memory_peak(self, memory):
with self.lock:
self._mem_peak = memory
@property
def aprsis_server(self):
with self.lock:
return self._aprsis_server
def set_aprsis_server(self, server):
with self.lock:
self._aprsis_server = server
@property
def aprsis_keepalive(self):
with self.lock:
return self._aprsis_keepalive
def set_aprsis_keepalive(self):
with self.lock:
self._aprsis_keepalive = datetime.datetime.now()
@property
def msgs_tx(self):
with self.lock:
return self._msgs_tx
def msgs_tx_inc(self):
with self.lock:
self._msgs_tx += 1
@property
def msgs_rx(self):
with self.lock:
return self._msgs_rx
def msgs_rx_inc(self):
with self.lock:
self._msgs_rx += 1
@property
def msgs_mice_rx(self):
with self.lock:
return self._msgs_mice_rx
def msgs_mice_inc(self):
with self.lock:
self._msgs_mice_rx += 1
@property
def ack_tx(self):
with self.lock:
return self._ack_tx
def ack_tx_inc(self):
with self.lock:
self._ack_tx += 1
@property
def ack_rx(self):
with self.lock:
return self._ack_rx
def ack_rx_inc(self):
with self.lock:
self._ack_rx += 1
@property
def msgs_tracked(self):
with self.lock:
return self._msgs_tracked
def msgs_tracked_inc(self):
with self.lock:
self._msgs_tracked += 1
@property
def email_tx(self):
with self.lock:
return self._email_tx
def email_tx_inc(self):
with self.lock:
self._email_tx += 1
@property
def email_rx(self):
with self.lock:
return self._email_rx
def email_rx_inc(self):
with self.lock:
self._email_rx += 1
@property
def email_thread_time(self):
with self.lock:
return self._email_thread_last_time
def email_thread_update(self):
with self.lock:
self._email_thread_last_time = datetime.datetime.now()
@property
def watch_list(self):
with self.lock:
return self._watch_list
def update_watch_list(self, watch_list):
with self.lock:
self._watch_list = watch_list
def stats(self):
now = datetime.datetime.now()
if self._email_thread_last_time:
last_update = str(now - self._email_thread_last_time)
else:
last_update = "never"
if self._aprsis_keepalive:
last_aprsis_keepalive = str(now - self._aprsis_keepalive)
else:
last_aprsis_keepalive = "never"
pm = plugin.PluginManager()
plugins = pm.get_msg_plugins()
plugin_stats = {}
def full_name_with_qualname(obj):
return "{}.{}".format(
obj.__class__.__module__,
obj.__class__.__qualname__,
)
for p in plugins:
plugin_stats[full_name_with_qualname(p)] = p.message_count
stats = {
"aprsd": {
"version": aprsd.__version__,
"uptime": utils.strfdelta(self.uptime),
"memory_current": self.memory,
"memory_current_str": utils.human_size(self.memory),
"memory_peak": self.memory_peak,
"memory_peak_str": utils.human_size(self.memory_peak),
"watch_list": self.watch_list,
},
"aprs-is": {
"server": self.aprsis_server,
"callsign": self.config["aprs"]["login"],
"last_update": last_aprsis_keepalive,
},
"messages": {
"tracked": self.msgs_tracked,
"sent": self.msgs_tx,
"recieved": self.msgs_rx,
"ack_sent": self.ack_tx,
"ack_recieved": self.ack_rx,
"mic-e recieved": self.msgs_mice_rx,
},
"email": {
"enabled": self.config["aprsd"]["email"]["enabled"],
"sent": self._email_tx,
"recieved": self._email_rx,
"thread_last_update": last_update,
},
"plugins": plugin_stats,
}
return stats
def __str__(self):
return (
"Uptime:{} Msgs TX:{} RX:{} "
"ACK: TX:{} RX:{} "
"Email TX:{} RX:{} LastLoop:{} ".format(
self.uptime,
self._msgs_tx,
self._msgs_rx,
self._ack_tx,
self._ack_rx,
self._email_tx,
self._email_rx,
self._email_thread_last_time,
)
)