Replace root logger calls with module-specific loggers

This commit is contained in:
Ian Renton
2026-08-15 08:35:06 +01:00
parent 74bcd9cded
commit dd89ff4af7
64 changed files with 328 additions and 216 deletions
+5 -3
View File
@@ -9,6 +9,8 @@ from core.config import SERVER_OWNER_CALLSIGN
from data.spot import Spot
from providers.spot.spot_provider import SpotProvider
logger = logging.getLogger(__name__)
class APRSIS(SpotProvider):
"""Spot provider for the APRS-IS."""
@@ -25,10 +27,10 @@ class APRSIS(SpotProvider):
def _connect(self):
self._aprsis = aprslib.IS(SERVER_OWNER_CALLSIGN)
self.status = "Connecting"
logging.info("APRS-IS connecting...")
logger.info("APRS-IS connecting...")
self._aprsis.connect()
self._aprsis.consumer(self._handle)
logging.info("APRS-IS connected.")
logger.info("APRS-IS connected.")
def stop(self):
self.status = "Shutting down"
@@ -60,4 +62,4 @@ class APRSIS(SpotProvider):
self.status = "OK"
self.last_update_time = datetime.now(pytz.UTC)
logging.debug("Data received from APRS-IS.")
logger.debug("Data received from APRS-IS.")
+11 -9
View File
@@ -11,6 +11,8 @@ from core.config import SERVER_OWNER_CALLSIGN
from data.spot import Spot
from providers.spot.spot_provider import SpotProvider
logger = logging.getLogger(__name__)
class DXCluster(SpotProvider):
"""Spot provider for a DX Cluster. Hostname, port, login_prompt, login_callsign and allow_rbn_spots are provided in config.
@@ -59,19 +61,19 @@ class DXCluster(SpotProvider):
while not connected and self._running:
try:
self.status = "Connecting"
logging.info(f"DX Cluster {self._hostname} connecting...")
logger.info(f"DX Cluster {self._hostname} connecting...")
self._telnet = telnetlib3.Telnet(self._hostname, self._port)
self._telnet.read_until(self._login_prompt.encode("latin-1"))
self._telnet.write(f"{self._login_callsign}\n".encode("latin-1"))
connected = True
logging.info(f"DX Cluster {self._hostname} connected.")
logger.info(f"DX Cluster {self._hostname} connected.")
except ConnectionRefusedError:
self.status = "Error"
logging.warning(f"Connection refused to DX cluster {self._hostname}")
logger.warning(f"Connection refused to DX cluster {self._hostname}")
sleep(300)
except Exception:
self.status = "Error"
logging.exception(f"Exception while connecting to DX Cluster Provider ({self._hostname}).")
logger.exception(f"Exception while connecting to DX Cluster Provider ({self._hostname}).")
sleep(5)
self.status = "Waiting for Data"
@@ -101,25 +103,25 @@ class DXCluster(SpotProvider):
self.status = "OK"
self.last_update_time = datetime.now(pytz.UTC)
logging.debug(f"Data received from DX Cluster {self._hostname}.")
logger.debug(f"Data received from DX Cluster {self._hostname}.")
except EOFError:
connected = False
if self._running:
self.status = "Restarting"
logging.warning(f"Disconnected from DX Cluster {self._hostname}. Reconnecting...")
logger.warning(f"Disconnected from DX Cluster {self._hostname}. Reconnecting...")
sleep(5)
else:
logging.info(f"DX Cluster {self._hostname} shutting down...")
logger.info(f"DX Cluster {self._hostname} shutting down...")
self.status = "Shutting down"
except Exception:
connected = False
if self._running:
self.status = "Error"
logging.exception(f"Exception in DX Cluster Provider ({self._hostname})")
logger.exception(f"Exception in DX Cluster Provider ({self._hostname})")
sleep(5)
else:
logging.info(f"DX Cluster {self._hostname} shutting down...")
logger.info(f"DX Cluster {self._hostname} shutting down...")
self.status = "Shutting down"
self.status = "Disconnected"
+8 -6
View File
@@ -9,6 +9,8 @@ from data.sig_ref import SIGRef
from data.spot import Spot
from providers.spot.http_spot_provider import HTTPSpotProvider
logger = logging.getLogger(__name__)
class GMA(HTTPSpotProvider):
"""Spot provider for General Mountain Activity"""
@@ -24,7 +26,7 @@ class GMA(HTTPSpotProvider):
self._api_key = provider_config.get("api_key", "")
if self._api_key == "":
provider_config["enabled"] = False
logging.warning("GMA spot provider configured but no api key was provided, this API will not be queried.")
logger.warning("GMA spot provider configured but no api key was provided, this API will not be queried.")
self._url_data_cache = URLDataCache("GMA")
super().__init__(
@@ -127,7 +129,7 @@ class GMA(HTTPSpotProvider):
spot.sig_refs[0].sig = "MOTA"
spot.sig = "MOTA"
case _:
logging.warning(
logger.warning(
f"GMA spot found with ref type {ref_info['reftype']}, developer needs to add support for this!"
)
spot.sig_refs[0].sig = ref_info["reftype"]
@@ -139,19 +141,19 @@ class GMA(HTTPSpotProvider):
elif not ref_response.from_cache:
if not ref_response.ok:
logging.warning(
logger.warning(
f"HTTP {ref_response.status_code} when looking up GMA ref {source_spot['REF']}"
)
else:
logging.warning(
logger.warning(
f"GMA API returned a malformed response when looking up ref {source_spot['REF']}"
)
except:
logging.exception(
logger.exception(
f"Exception when looking up {self.REF_INFO_URL_ROOT}{source_spot['REF']}, ignoring this spot for now"
)
else:
logging.warning(f"The GMA API returned an unexpected response (HTTP {http_response.status_code}).")
logger.warning(f"The GMA API returned an unexpected response (HTTP {http_response.status_code}).")
return new_spots
+4 -2
View File
@@ -11,6 +11,8 @@ from data.sig_ref import SIGRef
from data.spot import Spot
from providers.spot.http_spot_provider import HTTPSpotProvider
logger = logging.getLogger(__name__)
class HEMA(HTTPSpotProvider):
"""Spot provider for HuMPs Excluding Marilyns Award"""
@@ -80,9 +82,9 @@ class HEMA(HTTPSpotProvider):
# code will do that for us.
new_spots.append(spot)
except (ConnectTimeout, ReadTimeout):
logging.warning("Timeout when accessing HEMA spots API.")
logger.warning("Timeout when accessing HEMA spots API.")
except ConnectionError:
logging.warning("Connection error when accessing HEMA spots API.")
logger.warning("Connection error when accessing HEMA spots API.")
return new_spots
def can_submit_spot(self, sig):
+9 -7
View File
@@ -10,6 +10,8 @@ from requests.exceptions import ConnectionError, ConnectTimeout
from core.constants import HTTP_HEADERS
from providers.spot.spot_provider import SpotProvider
logger = logging.getLogger(__name__)
class HTTPSpotProvider(SpotProvider):
"""Generic spot provider class for providers that request data via HTTP(S). Just for convenience to avoid code
@@ -26,7 +28,7 @@ class HTTPSpotProvider(SpotProvider):
def start(self):
# Fire off the polling thread. It will poll immediately on startup, then sleep for poll_interval between
# subsequent polls, so start() returns immediately and the application can continue starting.
logging.info(f"Set up query of {self.name} spot API every {self._poll_interval!s} seconds.")
logger.info(f"Set up query of {self.name} spot API every {self._poll_interval!s} seconds.")
self._thread = Thread(target=self._run, name=f"HTTPSpotProvider-{self.name}")
self._thread.start()
@@ -50,7 +52,7 @@ class HTTPSpotProvider(SpotProvider):
def _poll(self):
try:
# Request data from API
logging.debug(f"Polling {self.name} spot API...")
logger.debug(f"Polling {self.name} spot API...")
http_response = requests.get(self._url, headers=HTTP_HEADERS, timeout=(5, 30))
# Check response code was good
if http_response.ok:
@@ -62,18 +64,18 @@ class HTTPSpotProvider(SpotProvider):
self.status = "OK"
self.last_update_time = datetime.now(pytz.UTC)
logging.debug(f"Received data from {self.name} spot API.")
logger.debug(f"Received data from {self.name} spot API.")
else:
self.status = "Error"
logging.warning(f"HTTP {http_response.status_code} when calling {self.name} spot API.")
logger.warning(f"HTTP {http_response.status_code} when calling {self.name} spot API.")
except ConnectionError:
logging.warning(f"Connection error when accessing {self.name} spots API.")
logger.warning(f"Connection error when accessing {self.name} spots API.")
except (ConnectTimeout, ReadTimeout):
logging.warning(f"Timeout when accessing {self.name} spots API.")
logger.warning(f"Timeout when accessing {self.name} spots API.")
except Exception:
self.status = "Error"
logging.exception(f"Exception in HTTP Spot Provider ({self.name})")
logger.exception(f"Exception in HTTP Spot Provider ({self.name})")
self._stop_event.wait(timeout=1)
def _http_response_to_spots(self, http_response):
+3 -1
View File
@@ -10,6 +10,8 @@ from data.sig_ref import SIGRef
from data.spot import Spot
from providers.spot.http_spot_provider import HTTPSpotProvider
logger = logging.getLogger(__name__)
class ParksNPeaks(HTTPSpotProvider):
"""Spot provider for Parks n Peaks"""
@@ -91,7 +93,7 @@ class ParksNPeaks(HTTPSpotProvider):
"SANPCPA",
"LLOTA",
]:
logging.warning(f"PNP spot found with sig {sig}, developer needs to add support for this!")
logger.warning(f"PNP spot found with sig {sig}, developer needs to add support for this!")
# Add new spot to the list
new_spots.append(spot)
+10 -8
View File
@@ -11,6 +11,8 @@ from core.config import SERVER_OWNER_CALLSIGN
from data.spot import Spot
from providers.spot.spot_provider import SpotProvider
logger = logging.getLogger(__name__)
class RBN(SpotProvider):
"""Spot provider for the Reverse Beacon Network. Connects to a single port, if you want both CW/RTTY (port 7000) and FT8
@@ -46,15 +48,15 @@ class RBN(SpotProvider):
while not connected and self._running:
try:
self.status = "Connecting"
logging.info(f"RBN port {self._port!s} connecting...")
logger.info(f"RBN port {self._port!s} connecting...")
self._telnet = telnetlib3.Telnet("telnet.reversebeacon.net", self._port)
self._telnet.read_until("Please enter your call: ".encode("latin-1"))
self._telnet.write(f"{SERVER_OWNER_CALLSIGN}\n".encode("latin-1"))
connected = True
logging.info(f"RBN port {self._port!s} connected.")
logger.info(f"RBN port {self._port!s} connected.")
except Exception:
self.status = "Error"
logging.exception(f"Exception while connecting to RBN (port {self._port!s}).")
logger.exception(f"Exception while connecting to RBN (port {self._port!s}).")
sleep(5)
self.status = "Waiting for Data"
@@ -84,25 +86,25 @@ class RBN(SpotProvider):
self.status = "OK"
self.last_update_time = datetime.now(pytz.UTC)
logging.debug(f"Data received from RBN on port {self._port!s}.")
logger.debug(f"Data received from RBN on port {self._port!s}.")
except EOFError:
connected = False
if self._running:
self.status = "Restarting"
logging.warning(f"Disconnected from RBN provider (port {self._port!s}). Reconnecting...")
logger.warning(f"Disconnected from RBN provider (port {self._port!s}). Reconnecting...")
sleep(5)
else:
logging.info(f"RBN provider (port {self._port!s}) shutting down...")
logger.info(f"RBN provider (port {self._port!s}) shutting down...")
self.status = "Shutting down"
except Exception:
connected = False
if self._running:
self.status = "Error"
logging.exception(f"Exception in RBN provider (port {self._port!s})")
logger.exception(f"Exception in RBN provider (port {self._port!s})")
sleep(5)
else:
logging.info(f"RBN provider (port {self._port!s}) shutting down...")
logger.info(f"RBN provider (port {self._port!s}) shutting down...")
self.status = "Shutting down"
self.status = "Disconnected"
+4 -2
View File
@@ -9,6 +9,8 @@ from data.sig_ref import SIGRef
from data.spot import Spot
from providers.spot.http_spot_provider import HTTPSpotProvider
logger = logging.getLogger(__name__)
class SOTA(HTTPSpotProvider):
"""Spot provider for Summits on the Air"""
@@ -73,9 +75,9 @@ class SOTA(HTTPSpotProvider):
# that for us.
new_spots.append(spot)
except ConnectionError:
logging.warning("Connection error when accessing SOTA spots API")
logger.warning("Connection error when accessing SOTA spots API")
except (ConnectTimeout, ReadTimeout):
logging.warning("Timeout when accessing SOTA spots API.")
logger.warning("Timeout when accessing SOTA spots API.")
return new_spots
def can_submit_spot(self, sig):
+9 -7
View File
@@ -8,6 +8,8 @@ from requests_sse import EventSource
from core.constants import HTTP_HEADERS
from providers.spot.spot_provider import SpotProvider
logger = logging.getLogger(__name__)
class SSESpotProvider(SpotProvider):
"""Spot provider using Server-Sent Events."""
@@ -22,7 +24,7 @@ class SSESpotProvider(SpotProvider):
self._event_source = None
def start(self):
logging.info(f"Set up SSE connection to {self.name} spot API.")
logger.info(f"Set up SSE connection to {self.name} spot API.")
self._stop_event.clear()
self._thread = Thread(target=self._run, name=f"SSESpotProvider-{self.name}")
self._thread.daemon = True
@@ -37,12 +39,12 @@ class SSESpotProvider(SpotProvider):
try:
event_source.close()
except Exception:
logging.exception(f"Exception closing SSE connection for {self.name} during stop()")
logger.exception(f"Exception closing SSE connection for {self.name} during stop()")
if self._thread:
self._thread.join(timeout=15)
if self._thread.is_alive():
logging.warning(f"{self.name} SSE worker thread did not exit on time and will be killed.")
logger.warning(f"{self.name} SSE worker thread did not exit on time and will be killed.")
def _on_open(self):
self.status = "Waiting for Data"
@@ -57,7 +59,7 @@ class SSESpotProvider(SpotProvider):
def _run(self):
while not self._stop_event.is_set():
try:
logging.debug(f"Connecting to {self.name} spot API...")
logger.debug(f"Connecting to {self.name} spot API...")
self.status = "Connecting"
with EventSource(
self._url,
@@ -81,10 +83,10 @@ class SSESpotProvider(SpotProvider):
self.status = "OK"
self.last_update_time = datetime.now(pytz.UTC)
logging.debug(f"Received data from {self.name} spot API.")
logger.debug(f"Received data from {self.name} spot API.")
except Exception:
logging.exception(
logger.exception(
f"Exception processing message from SSE Spot Provider ({self.name})"
)
finally:
@@ -92,7 +94,7 @@ class SSESpotProvider(SpotProvider):
except Exception:
self.status = "Error"
logging.exception(f"Exception in SSE Spot Provider ({self.name})")
logger.exception(f"Exception in SSE Spot Provider ({self.name})")
else:
self.status = "Disconnected"
self._stop_event.wait(timeout=5) # Wait before trying to reconnect
+7 -5
View File
@@ -9,6 +9,8 @@ from websocket import create_connection
from core.constants import HTTP_HEADERS
from providers.spot.spot_provider import SpotProvider
logger = logging.getLogger(__name__)
class WebsocketSpotProvider(SpotProvider):
"""Spot provider using websockets."""
@@ -22,7 +24,7 @@ class WebsocketSpotProvider(SpotProvider):
self._last_event_id = None
def start(self):
logging.info(f"Set up websocket connection to {self.name} spot API.")
logger.info(f"Set up websocket connection to {self.name} spot API.")
self._stopped = False
self._thread = Thread(target=self._run, name=f"WebsocketSpotProvider-{self.name}")
self._thread.daemon = True
@@ -44,7 +46,7 @@ class WebsocketSpotProvider(SpotProvider):
def _run(self):
while not self._stopped:
try:
logging.debug(f"Connecting to {self.name} spot API...")
logger.debug(f"Connecting to {self.name} spot API...")
self.status = "Connecting"
self._ws = create_connection(self._url, header=HTTP_HEADERS)
self.status = "Connected"
@@ -57,14 +59,14 @@ class WebsocketSpotProvider(SpotProvider):
self.status = "OK"
self.last_update_time = datetime.now(pytz.UTC)
logging.debug(f"Received data from {self.name} spot API.")
logger.debug(f"Received data from {self.name} spot API.")
except Exception:
logging.exception(f"Exception processing message from Websocket Spot Provider ({self.name})")
logger.exception(f"Exception processing message from Websocket Spot Provider ({self.name})")
except Exception as e:
self.status = "Error"
logging.exception(f"Exception in Websocket Spot Provider ({self.name})", e)
logger.exception(f"Exception in Websocket Spot Provider ({self.name})", e)
else:
self.status = "Disconnected"
sleep(5) # Wait before trying to reconnect
+3 -1
View File
@@ -11,6 +11,8 @@ from data.sig_ref import SIGRef
from data.spot import Spot
from providers.spot.http_spot_provider import HTTPSpotProvider
logger = logging.getLogger(__name__)
class WOTA(HTTPSpotProvider):
"""Spot provider for Wainwrights on the Air"""
@@ -82,7 +84,7 @@ class WOTA(HTTPSpotProvider):
new_spots.append(spot)
except Exception as e:
logging.error("Exception parsing WOTA spot", e)
logger.error("Exception parsing WOTA spot", e)
return new_spots
def can_submit_spot(self, sig):