Add info logging for mobile websocket events and filter healthcheck logs

- Add info-level logging to all mobile websocket handle_in callbacks to track
  incoming messages (subscribe_bounds, update_bounds, search_callsign, etc.)
- Create LogFilter plug to exclude K8s healthcheck requests from Phoenix logs
- Filter logs for /health, /ready, and / endpoints to reduce noise from
  continuous healthcheck probes
- Configure Plug.Telemetry to use custom log level function

This eliminates noisy healthcheck logs while providing better visibility
into mobile websocket API usage.
This commit is contained in:
Graham McIntire 2025-10-25 17:04:59 -05:00
parent 42fce1b933
commit 8dc713ce3f
No known key found for this signature in database
3 changed files with 46 additions and 8 deletions

View file

@ -66,6 +66,8 @@ defmodule AprsmeWeb.MobileChannel do
%{"north" => north, "south" => south, "east" => east, "west" => west} = payload,
socket
) do
Logger.info("Mobile websocket received subscribe_bounds: #{inspect(payload)}")
bounds = %{
north: ensure_float(north),
south: ensure_float(south),
@ -102,7 +104,13 @@ defmodule AprsmeWeb.MobileChannel do
end
@impl true
def handle_in("update_bounds", %{"north" => north, "south" => south, "east" => east, "west" => west}, socket) do
def handle_in(
"update_bounds",
%{"north" => north, "south" => south, "east" => east, "west" => west} = payload,
socket
) do
Logger.info("Mobile websocket received update_bounds: #{inspect(payload)}")
bounds = %{
north: ensure_float(north),
south: ensure_float(south),
@ -138,7 +146,9 @@ defmodule AprsmeWeb.MobileChannel do
end
@impl true
def handle_in("unsubscribe", _payload, socket) do
def handle_in("unsubscribe", payload, socket) do
Logger.info("Mobile websocket received unsubscribe: #{inspect(payload)}")
if socket.assigns[:subscribed] && socket.assigns[:bounds] do
Aprsme.StreamingPacketsPubSub.unsubscribe(self())
@ -157,11 +167,11 @@ defmodule AprsmeWeb.MobileChannel do
@impl true
def handle_in("search_callsign", %{"query" => query} = payload, socket) do
Logger.info("Mobile websocket received search_callsign: #{inspect(payload)}")
limit = Map.get(payload, "limit", 50)
limit = min(limit, 500)
Logger.debug("Mobile client searching for callsign: #{query}")
results = search_callsign(query, limit)
{:reply, {:ok, %{results: results, count: length(results)}}, socket}
@ -169,6 +179,8 @@ defmodule AprsmeWeb.MobileChannel do
@impl true
def handle_in("subscribe_callsign", %{"callsign" => callsign} = payload, socket) do
Logger.info("Mobile websocket received subscribe_callsign: #{inspect(payload)}")
hours_back = Map.get(payload, "hours_back", 24)
# Max 1 week
hours_back = min(hours_back, 168)
@ -176,8 +188,6 @@ defmodule AprsmeWeb.MobileChannel do
# Normalize callsign to uppercase
callsign = String.upcase(callsign)
Logger.info("Mobile client #{socket.assigns[:client_id]} subscribing to callsign: #{callsign}")
# Load historical packets for this callsign
socket = load_callsign_history(socket, callsign, hours_back)
@ -188,7 +198,9 @@ defmodule AprsmeWeb.MobileChannel do
end
@impl true
def handle_in("unsubscribe_callsign", _payload, socket) do
def handle_in("unsubscribe_callsign", payload, socket) do
Logger.info("Mobile websocket received unsubscribe_callsign: #{inspect(payload)}")
if socket.assigns[:tracked_callsign] do
callsign = socket.assigns.tracked_callsign
socket = assign(socket, :tracked_callsign, nil)

View file

@ -45,7 +45,7 @@ defmodule AprsmeWeb.Endpoint do
cookie_key: "request_logger"
plug Plug.RequestId
plug Plug.Telemetry, event_prefix: [:phoenix, :endpoint]
plug Plug.Telemetry, event_prefix: [:phoenix, :endpoint], log: {AprsmeWeb.Plugs.LogFilter, :log_level, []}
plug Plug.Parsers,
parsers: [:urlencoded, :multipart, :json],

View file

@ -0,0 +1,26 @@
defmodule AprsmeWeb.Plugs.LogFilter do
@moduledoc """
Log filter that excludes healthcheck and other noisy requests from Phoenix logs.
Used by Plug.Telemetry to determine the log level for requests.
Returns `false` for requests that shouldn't be logged (like K8s healthchecks),
or `:info` for normal requests.
"""
@doc """
Determines the log level for a given request.
Returns `false` to skip logging, or `:info` to log at info level.
"""
def log_level(conn) do
if should_skip_logging?(conn) do
false
else
:info
end
end
defp should_skip_logging?(conn) do
conn.request_path in ["/health", "/ready", "/"]
end
end