Chore: make webserver IP standout more in log
authorMarcel van der Veldt <m.vanderveldt@outlook.com>
Fri, 16 May 2025 22:54:41 +0000 (00:54 +0200)
committerMarcel van der Veldt <m.vanderveldt@outlook.com>
Fri, 16 May 2025 22:54:41 +0000 (00:54 +0200)
music_assistant/controllers/streams.py
music_assistant/controllers/webserver.py
music_assistant/helpers/util.py
music_assistant/helpers/webserver.py

index ed6f52008f12ba134027a936a51ad62c6c35399a..981bc04d2d68be7dc20b2f7e749d120d01199fcd 100644 (file)
@@ -9,6 +9,7 @@ the upnp callbacks and json rpc api for slimproto clients.
 from __future__ import annotations
 
 import asyncio
+import logging
 import os
 import urllib.parse
 from collections.abc import AsyncGenerator
@@ -266,6 +267,20 @@ class StreamsController(CoreController):
         # start the webserver
         self.publish_port = config.get_value(CONF_BIND_PORT)
         self.publish_ip = config.get_value(CONF_PUBLISH_IP)
+        # print a big fat message in the log where the streamserver is running
+        # because this is a common source of issues for people with more complex setups
+        self.logger.log(
+            logging.INFO if self.mass.config.onboard_done else logging.WARNING,
+            "\n\n################################################################################\n"
+            "Starting streamserver on  %s:%s\n"
+            "This is the IP address that is communicated to players.\n"
+            "If this is incorrect, audio will not play!\n"
+            "See the documentation how to configure the publish IP for the Streamserver\n"
+            "in Settings --> Core modules --> Streamserver\n"
+            "################################################################################\n",
+            self.publish_ip,
+            self.publish_port,
+        )
         await self._server.setup(
             bind_ip=config.get_value(CONF_BIND_IP),
             bind_port=self.publish_port,
index 2a6a4109fee0d15e4947259fcba0d3498a08f462..69bf56796a5bd0a93862d610a9df86b43071602c 100644 (file)
@@ -190,6 +190,26 @@ class WebserverController(CoreController):
             self.publish_port = config.get_value(CONF_BIND_PORT)
             self.publish_ip = default_publish_ip
             bind_ip = config.get_value(CONF_BIND_IP)
+            # print a big fat message in the log where the webserver is running
+            # because this is a common source of issues for people with more complex setups
+            if not self.mass.config.onboard_done:
+                self.logger.warning(
+                    "\n\n################################################################################\n"
+                    "Starting webserver on  %s:%s - base url: %s\n"
+                    "If this is incorrect, see the documentation how to configure the Webserver\n"
+                    "in Settings --> Core modules --> Webserver\n"
+                    "################################################################################\n",
+                    bind_ip,
+                    self.publish_port,
+                    base_url,
+                )
+            else:
+                self.logger.info(
+                    "Starting webserver on  %s:%s - base url: %s\n#\n",
+                    bind_ip,
+                    self.publish_port,
+                    base_url,
+                )
         await self._server.setup(
             bind_ip=bind_ip,
             bind_port=self.publish_port,
index 6dbbaadf686f9c58f4384b50cf96c0f74ac7cfc8..64d38117cbab4637858098d740631c0ca2de8914 100644 (file)
@@ -226,6 +226,19 @@ async def get_ip_addresses(include_ipv6: bool = False) -> tuple[str, ...]:
 
     def call() -> tuple[str, ...]:
         result: list[tuple[int, str]] = []
+        # try to get the primary IP address
+        # this is the IP address of the default route
+        _sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+        _sock.settimeout(0)
+        try:
+            # doesn't even have to be reachable
+            _sock.connect(("10.254.254.254", 1))
+            primary_ip = _sock.getsockname()[0]
+        except Exception:
+            primary_ip = ""
+        finally:
+            _sock.close()
+        # get all IP addresses of all network interfaces
         adapters = ifaddr.get_adapters()
         for adapter in adapters:
             for ip in adapter.ips:
@@ -238,7 +251,9 @@ async def get_ip_addresses(include_ipv6: bool = False) -> tuple[str, ...]:
                 if ip_str.startswith(("::1", "::ffff:", "fe80")):
                     # filter out IPv6 loopback/link-local address
                     continue
-                if ip_str.startswith(("192.168.",)):
+                if ip_str == primary_ip:
+                    score = 10
+                elif ip_str.startswith(("192.168.",)):
                     # we rank the 192.168 range a bit higher as its most
                     # often used as the private network subnet
                     score = 2
@@ -255,6 +270,10 @@ async def get_ip_addresses(include_ipv6: bool = False) -> tuple[str, ...]:
     return await asyncio.to_thread(call)
 
 
+async def get_primary_ip_address() -> str | None:
+    """Return the primary IP address of the system."""
+
+
 async def is_port_in_use(port: int) -> bool:
     """Check if port is in use."""
 
index 137ad9255c4ed6a03f7f80c82230105d7332bda1..4dac602af9255aa4a55e4a43b96fa96856392fb3 100644 (file)
@@ -56,7 +56,6 @@ class Webserver:
                 "max_field_size": MAX_LINE_SIZE,
             },
         )
-        self.logger.info("Starting server on  %s:%s - base url: %s", bind_ip, bind_port, base_url)
         self._apprunner = web.AppRunner(self._webapp, access_log=None, shutdown_timeout=10)
         # add static routes
         if self._static_routes: