From a5cbf5253e75fcab1cf1544b00f5d33d7347ca34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Charvet=20=E9=BB=91=E7=93=9C?= Date: Fri, 24 Jan 2025 07:41:57 +0000 Subject: [PATCH 01/10] Upgrade logger file backend dependency This gets rid of the compilation warning "warn logging level is deprecated" --- mix.exs | 2 +- mix.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mix.exs b/mix.exs index 75e50603d..aa23a8347 100644 --- a/mix.exs +++ b/mix.exs @@ -73,7 +73,7 @@ defmodule Teiserver.MixProject do # Extra deps {:ecto_psql_extras, "~> 0.7"}, - {:logger_file_backend, "~> 0.0.10"}, + {:logger_file_backend, "~> 0.0.14"}, {:timex, "~> 3.7.5"}, {:breadcrumble, "~> 1.0.0"}, {:guardian, "~> 2.1"}, diff --git a/mix.lock b/mix.lock index 14e428f74..d64db770a 100644 --- a/mix.lock +++ b/mix.lock @@ -60,7 +60,7 @@ "kcl": {:hex, :kcl, "1.4.2", "8b73a55a14899dc172fcb05a13a754ac171c8165c14f65043382d567922f44ab", [:mix], [{:curve25519, ">= 1.0.4", [hex: :curve25519, repo: "hexpm", optional: false]}, {:ed25519, "~> 1.3", [hex: :ed25519, repo: "hexpm", optional: false]}, {:poly1305, "~> 1.0", [hex: :poly1305, repo: "hexpm", optional: false]}, {:salsa20, "~> 1.0", [hex: :salsa20, repo: "hexpm", optional: false]}], "hexpm", "9f083dd3844d902df6834b258564a82b21a15eb9f6acdc98e8df0c10feeabf05"}, "libcluster": {:hex, :libcluster, "3.3.3", "a4f17721a19004cfc4467268e17cff8b1f951befe428975dd4f6f7b84d927fe0", [:mix], [{:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "7c0a2275a0bb83c07acd17dab3c3bfb4897b145106750eeccc62d302e3bdfee5"}, "libring": {:hex, :libring, "1.6.0", "d5dca4bcb1765f862ab59f175b403e356dec493f565670e0bacc4b35e109ce0d", [:mix], [], "hexpm", "5e91ece396af4bce99953d49ee0b02f698cd38326d93cd068361038167484319"}, - "logger_file_backend": {:hex, :logger_file_backend, "0.0.13", "df07b14970e9ac1f57362985d76e6f24e3e1ab05c248055b7d223976881977c2", [:mix], [], "hexpm", "71a453a7e6e899ae4549fb147b1c6621f4233f8f48f58ca10a64ec67b6c50018"}, + "logger_file_backend": {:hex, :logger_file_backend, "0.0.14", "774bb661f1c3fed51b624d2859180c01e386eb1273dc22de4f4a155ef749a602", [:mix], [], "hexpm", "071354a18196468f3904ef09413af20971d55164267427f6257b52cfba03f9e6"}, "math": {:hex, :math, "0.7.0", "12af548c3892abf939a2e242216c3e7cbfb65b9b2fe0d872d05c6fb609f8127b", [:mix], [], "hexpm", "7987af97a0c6b58ad9db43eb5252a49fc1dfe1f6d98f17da9282e297f594ebc2"}, "meck": {:hex, :meck, "0.9.2", "85ccbab053f1db86c7ca240e9fc718170ee5bda03810a6292b5306bf31bae5f5", [:rebar3], [], "hexpm", "81344f561357dc40a8344afa53767c32669153355b626ea9fcbc8da6b3045826"}, "merkle_map": {:hex, :merkle_map, "0.2.1", "01a88c87a6b9fb594c67c17ebaf047ee55ffa34e74297aa583ed87148006c4c8", [:mix], [], "hexpm", "fed4d143a5c8166eee4fa2b49564f3c4eace9cb252f0a82c1613bba905b2d04d"}, From 08ce788c07df4d4c2e12c3d12c0ec7a0fde96442 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Charvet=20=E9=BB=91=E7=93=9C?= Date: Fri, 24 Jan 2025 07:41:57 +0000 Subject: [PATCH 02/10] Move logger config to logger_backend https://hexdocs.pm/logger/main/Logger.html#module-backends-and-backwards-compatibility the api for custom logging has changed in elixir 1.15 to instead use the logger_backend project. Also centralise the logging config. Logger definition and base config done at compile time in config/config.exs and runtime or env specific overrides done in config/.exs or config/runtime.exs --- config/config.exs | 28 +++++++++++++++++++++++--- config/dev.exs | 22 -------------------- config/prod.exs | 3 +++ config/runtime.exs | 39 ++++++++---------------------------- lib/teiserver/application.ex | 5 +++++ mix.exs | 1 + mix.lock | 1 + 7 files changed, 43 insertions(+), 56 deletions(-) diff --git a/config/config.exs b/config/config.exs index 3efeae624..198607e95 100644 --- a/config/config.exs +++ b/config/config.exs @@ -94,9 +94,31 @@ config :teiserver, Teiserver, # config :grpc, # start_server: true -config :logger, :console, - format: "$date $time $metadata[$level] $message\n", - metadata: [:request_id, :user_id] +config :logger, :default_formatter, + type: :standard_io, + metadata: [:request_id, :user_id], + format: "$date $time [$level] $metadata $message\n" + + +config :logger, LoggerBackends.Console, + format: "$date $time [$level] $metadata $message\n", + metadata: [:request_id, :user_id], + level: :debug + +config :logger, :error_log, + format: "$time [$level] $metadata $message\n", + metadata: [:request_id, :user_id], + level: :error + +config :logger, :notice_log, + format: "$time [$level] $metadata $message\n", + metadata: [:request_id, :user_id], + level: :notice + +config :logger, :info_log, + format: "$time [$level] $metadata $message\n", + metadata: [:request_id, :user_id], + level: :info # Use Jason for JSON parsing in Phoenix config :phoenix, :json_library, Jason diff --git a/config/dev.exs b/config/dev.exs index 5931816ed..53eb3c0ac 100644 --- a/config/dev.exs +++ b/config/dev.exs @@ -84,28 +84,6 @@ config :teiserver, Oban, queues: false, crontab: false -# Do not include metadata nor timestamps in development logs -config :logger, :console, format: "[$level] $message\n" - -config :logger, - backends: [ - {LoggerFileBackend, :error_log}, - {LoggerFileBackend, :info_log}, - :console - ] - -config :logger, :error_log, - path: "/tmp/teiserver_error.log", - format: "$time [$level] $metadata $message\n", - metadata: [:request_id, :user_id], - level: :error - -config :logger, :info_log, - path: "/tmp/teiserver_info.log", - format: "$time [$level] $metadata $message\n", - metadata: [:request_id, :user_id], - level: :info - try do import_config "dev.secret.exs" rescue diff --git a/config/prod.exs b/config/prod.exs index 6467d2cf5..7db2f9f72 100644 --- a/config/prod.exs +++ b/config/prod.exs @@ -62,3 +62,6 @@ config :teiserver, TeiserverWeb.Endpoint, cache_static_manifest: "priv/static/cache_manifest.json", server: true, version: Mix.Project.config()[:version] + + +config :logger, :default_handler, level: :info diff --git a/config/runtime.exs b/config/runtime.exs index cdf89af50..62de90a14 100644 --- a/config/runtime.exs +++ b/config/runtime.exs @@ -134,37 +134,6 @@ if config_env() == :prod do auth: :always end - log_root_path = Teiserver.ConfigHelpers.get_env("TEI_LOG_ROOT_PATH", "/var/log/teiserver/") - - config :logger, - backends: [ - {LoggerFileBackend, :error_log}, - {LoggerFileBackend, :notice_log}, - {LoggerFileBackend, :info_log}, - :console - ] - - # Do not print debug messages in production - config :logger, :default_handler, false - - config :logger, :error_log, - path: "#{log_root_path}error.log", - format: "$date $time [$level] $metadata $message\n", - metadata: [:request_id, :user_id], - level: :error - - config :logger, :notice_log, - path: "#{log_root_path}notice.log", - format: "$date $time [$level] $metadata $message\n", - metadata: [:request_id, :user_id], - level: :notice - - config :logger, :info_log, - path: "#{log_root_path}info.log", - format: "$date $time [$level] $metadata $message\n", - metadata: [:request_id, :user_id], - level: :info - if enable_discord_bridge do config :nostrum, gateway_intents: [ @@ -185,3 +154,11 @@ if config_env() == :prod do bot_name: Teiserver.ConfigHelpers.get_env("TEI_DISCORD_BOT_NAME") end end + +log_root_path = Teiserver.ConfigHelpers.get_env("TEI_LOG_ROOT_PATH", "/tmp/teiserver") + +config :logger, :error_log, path: "#{log_root_path}/error.log" + +config :logger, :notice_log, path: "#{log_root_path}/notice.log" + +config :logger, :info_log, path: "#{log_root_path}/info.log" diff --git a/lib/teiserver/application.ex b/lib/teiserver/application.ex index 8fa997f97..e290bfc3b 100644 --- a/lib/teiserver/application.ex +++ b/lib/teiserver/application.ex @@ -12,6 +12,11 @@ defmodule Teiserver.Application do @impl true def start(_type, _args) do + LoggerBackends.add(LoggerBackends.Console) + LoggerBackends.add({LoggerFileBackend, :error_log}) + LoggerBackends.add({LoggerFileBackend, :notice_log}) + LoggerBackends.add({LoggerFileBackend, :info_log}) + # List all child processes to be supervised children = [ diff --git a/mix.exs b/mix.exs index aa23a8347..6bc61cc4b 100644 --- a/mix.exs +++ b/mix.exs @@ -74,6 +74,7 @@ defmodule Teiserver.MixProject do # Extra deps {:ecto_psql_extras, "~> 0.7"}, {:logger_file_backend, "~> 0.0.14"}, + {:logger_backends, "~> 1.0"}, {:timex, "~> 3.7.5"}, {:breadcrumble, "~> 1.0.0"}, {:guardian, "~> 2.1"}, diff --git a/mix.lock b/mix.lock index d64db770a..7f8786b4a 100644 --- a/mix.lock +++ b/mix.lock @@ -60,6 +60,7 @@ "kcl": {:hex, :kcl, "1.4.2", "8b73a55a14899dc172fcb05a13a754ac171c8165c14f65043382d567922f44ab", [:mix], [{:curve25519, ">= 1.0.4", [hex: :curve25519, repo: "hexpm", optional: false]}, {:ed25519, "~> 1.3", [hex: :ed25519, repo: "hexpm", optional: false]}, {:poly1305, "~> 1.0", [hex: :poly1305, repo: "hexpm", optional: false]}, {:salsa20, "~> 1.0", [hex: :salsa20, repo: "hexpm", optional: false]}], "hexpm", "9f083dd3844d902df6834b258564a82b21a15eb9f6acdc98e8df0c10feeabf05"}, "libcluster": {:hex, :libcluster, "3.3.3", "a4f17721a19004cfc4467268e17cff8b1f951befe428975dd4f6f7b84d927fe0", [:mix], [{:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "7c0a2275a0bb83c07acd17dab3c3bfb4897b145106750eeccc62d302e3bdfee5"}, "libring": {:hex, :libring, "1.6.0", "d5dca4bcb1765f862ab59f175b403e356dec493f565670e0bacc4b35e109ce0d", [:mix], [], "hexpm", "5e91ece396af4bce99953d49ee0b02f698cd38326d93cd068361038167484319"}, + "logger_backends": {:hex, :logger_backends, "1.0.0", "09c4fad6202e08cb0fbd37f328282f16539aca380f512523ce9472b28edc6bdf", [:mix], [], "hexpm", "1faceb3e7ec3ef66a8f5746c5afd020e63996df6fd4eb8cdb789e5665ae6c9ce"}, "logger_file_backend": {:hex, :logger_file_backend, "0.0.14", "774bb661f1c3fed51b624d2859180c01e386eb1273dc22de4f4a155ef749a602", [:mix], [], "hexpm", "071354a18196468f3904ef09413af20971d55164267427f6257b52cfba03f9e6"}, "math": {:hex, :math, "0.7.0", "12af548c3892abf939a2e242216c3e7cbfb65b9b2fe0d872d05c6fb609f8127b", [:mix], [], "hexpm", "7987af97a0c6b58ad9db43eb5252a49fc1dfe1f6d98f17da9282e297f594ebc2"}, "meck": {:hex, :meck, "0.9.2", "85ccbab053f1db86c7ca240e9fc718170ee5bda03810a6292b5306bf31bae5f5", [:rebar3], [], "hexpm", "81344f561357dc40a8344afa53767c32669153355b626ea9fcbc8da6b3045826"}, From 9fc253ffd7e2fd77429ab1d4e4d999fd3cb713eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Charvet=20=E9=BB=91=E7=93=9C?= Date: Fri, 24 Jan 2025 07:41:57 +0000 Subject: [PATCH 03/10] Disable default logger With LoggerBackends.Console configured we don't need the default one anymore, which would duplicate all logs sent to the console --- config/config.exs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/config/config.exs b/config/config.exs index 198607e95..d868df29a 100644 --- a/config/config.exs +++ b/config/config.exs @@ -94,11 +94,7 @@ config :teiserver, Teiserver, # config :grpc, # start_server: true -config :logger, :default_formatter, - type: :standard_io, - metadata: [:request_id, :user_id], - format: "$date $time [$level] $metadata $message\n" - +config :logger, :default_handler, false config :logger, LoggerBackends.Console, format: "$date $time [$level] $metadata $message\n", From c2eabb422ae337f1d5dc23962207e0c0e8a8e01b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Charvet=20=E9=BB=91=E7=93=9C?= Date: Fri, 24 Jan 2025 07:41:57 +0000 Subject: [PATCH 04/10] Use metadata to log player in tachyon session --- lib/teiserver/player/session.ex | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/lib/teiserver/player/session.ex b/lib/teiserver/player/session.ex index aafd5ae71..57fbf6dd5 100644 --- a/lib/teiserver/player/session.ex +++ b/lib/teiserver/player/session.ex @@ -128,6 +128,7 @@ defmodule Teiserver.Player.Session do @impl true def init({conn_pid, user}) do ref = Process.monitor(conn_pid) + Logger.metadata(user_id: user.id) state = %{ user: user, @@ -136,7 +137,7 @@ defmodule Teiserver.Player.Session do matchmaking: initial_matchmaking_state() } - Logger.debug("init session #{inspect(self())} for player #{user.id}") + Logger.debug("init session #{inspect(self())}") {:ok, state} end @@ -150,7 +151,7 @@ defmodule Teiserver.Player.Session do Process.demonitor(state.mon_ref, [:flush]) mon_ref = Process.monitor(new_conn_pid) - Logger.info("session reused for player #{state.user.id}") + Logger.info("session reused") {:reply, :ok, %{state | conn_pid: new_conn_pid, mon_ref: mon_ref}} end @@ -277,9 +278,7 @@ defmodule Teiserver.Player.Session do # we're not searching anything. This can happen as a race when two queues # match the same player at the same time. # Do log it since it should not happen too often unless something is wrong - Logger.info( - "Got a matchmaking found but in state #{inspect(state.matchmaking)} for user #{inspect(state.user.id)}" - ) + Logger.info("Got a matchmaking found but in state #{inspect(state.matchmaking)}") Matchmaking.cancel(room_pid, state.user.id) {:noreply, state} @@ -351,7 +350,7 @@ defmodule Teiserver.Player.Session do _ -> Logger.warning( - "User #{state.user.id} received a request to start a battle but is not in a state to do so #{inspect(state)}" + "User received a request to start a battle but is not in a state to do so #{inspect(state)}" ) {:noreply, state} @@ -362,8 +361,8 @@ defmodule Teiserver.Player.Session do def handle_info({:DOWN, ref, :process, _, _reason}, state) when ref == state.mon_ref do # we don't care about cancelling the timer if the player reconnects since reconnection # should be fairly low (and rate limited) so too many messages isn't an issue - {:ok, _} = :timer.send_after(30_000, :player_timeout) - Logger.debug("Player #{state.user.id} disconnected abruptly") + {:ok, _} = :timer.send_after(2_000, :player_timeout) + Logger.info("Player disconnected abruptly") {:noreply, %{state | conn_pid: nil}} end @@ -389,7 +388,7 @@ defmodule Teiserver.Player.Session do def handle_info(:player_timeout, state) do if is_nil(state.conn_pid) do - Logger.debug("Player #{state.user.id} timed out, stopping session") + Logger.debug("Player timed out, stopping session") {:stop, :normal, state} else {:noreply, state} From 9d8f51f778fbe710ac57e129d449d59d1318a423 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Charvet=20=E9=BB=91=E7=93=9C?= Date: Fri, 24 Jan 2025 07:41:57 +0000 Subject: [PATCH 05/10] Use metadata to log player id in tachyon handler --- lib/teiserver/player/tachyon_handler.ex | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/teiserver/player/tachyon_handler.ex b/lib/teiserver/player/tachyon_handler.ex index 38c424d10..01f549dee 100644 --- a/lib/teiserver/player/tachyon_handler.ex +++ b/lib/teiserver/player/tachyon_handler.ex @@ -48,6 +48,7 @@ defmodule Teiserver.Player.TachyonHandler do initial_state |> Map.put(:sess_monitor, sess_monitor) |> Map.put(:pending_responses, %{}) user = initial_state.user + Logger.metadata(user_id: user.id) event = %{ users: [ @@ -67,7 +68,7 @@ defmodule Teiserver.Player.TachyonHandler do @impl Handler def handle_info({:DOWN, _, :process, _, reason}, state) do Logger.warning( - "Session for player #{state.user.id} went down because #{inspect(reason)}, terminating connection" + "Session for player went down because #{inspect(reason)}, terminating connection" ) {:stop, :normal, @@ -117,7 +118,7 @@ defmodule Teiserver.Player.TachyonHandler do def handle_info({:timeout, message_id}, state) when is_map_key(state.pending_responses, message_id) do - Logger.debug("User(#{state.user.id}) did not reply in time to request with id #{message_id}") + Logger.debug("User did not reply in time to request with id #{message_id}") {:stop, :normal, state} end From 15c6c9c85bd3361fd9f1e924b3bb957b6ce89224 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Charvet=20=E9=BB=91=E7=93=9C?= Date: Fri, 24 Jan 2025 07:41:57 +0000 Subject: [PATCH 06/10] Use metadata to log queue id We get logs like: 2025-01-24 08:28:16.231 [debug] queue_id=1v1 Player 43 went down, removing from queue 1v1 --- lib/teiserver/matchmaking/queue_server.ex | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/teiserver/matchmaking/queue_server.ex b/lib/teiserver/matchmaking/queue_server.ex index 85cdb2b6a..8880c5702 100644 --- a/lib/teiserver/matchmaking/queue_server.ex +++ b/lib/teiserver/matchmaking/queue_server.ex @@ -156,6 +156,8 @@ defmodule Teiserver.Matchmaking.QueueServer do @impl true def init(state) do + Logger.metadata(queue_id: state.id) + if state.settings.tick_interval_ms != :manual do :timer.send_interval(state.settings.tick_interval_ms, :tick) end From 759ce1081fa2998b343d712da79bb9368241f109 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Charvet=20=E9=BB=91=E7=93=9C?= Date: Fri, 24 Jan 2025 07:41:57 +0000 Subject: [PATCH 07/10] log more metadata Don't use `:all` because this logs way too much, things like file, line, erl_level and so on. Maybe later if we go structured log --- config/config.exs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/config/config.exs b/config/config.exs index d868df29a..ed206f6a1 100644 --- a/config/config.exs +++ b/config/config.exs @@ -96,24 +96,26 @@ config :teiserver, Teiserver, config :logger, :default_handler, false +metadata = [:request_id, :user_id, :queue_id] + config :logger, LoggerBackends.Console, format: "$date $time [$level] $metadata $message\n", - metadata: [:request_id, :user_id], + metadata: metadata, level: :debug config :logger, :error_log, format: "$time [$level] $metadata $message\n", - metadata: [:request_id, :user_id], + metadata: metadata, level: :error config :logger, :notice_log, format: "$time [$level] $metadata $message\n", - metadata: [:request_id, :user_id], + metadata: metadata, level: :notice config :logger, :info_log, format: "$time [$level] $metadata $message\n", - metadata: [:request_id, :user_id], + metadata: metadata, level: :info # Use Jason for JSON parsing in Phoenix From e8d08049feda511afc6068ddb053273b300fae09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Charvet=20=E9=BB=91=E7=93=9C?= Date: Fri, 24 Jan 2025 08:46:28 +0000 Subject: [PATCH 08/10] Disable stdout logging in prod builds Not sure if that'a what we want but this keeps the same config as before the logging changes. --- config/prod.exs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/config/prod.exs b/config/prod.exs index 7db2f9f72..1a365a0f8 100644 --- a/config/prod.exs +++ b/config/prod.exs @@ -63,5 +63,7 @@ config :teiserver, TeiserverWeb.Endpoint, server: true, version: Mix.Project.config()[:version] - config :logger, :default_handler, level: :info + +# disable stdout logging in production, rely on log files +config :logger, LoggerBackends.Console, false From 425a05d6b037f9d888c99764f7024ee274bb8e18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Charvet=20=E9=BB=91=E7=93=9C?= Date: Fri, 24 Jan 2025 08:46:28 +0000 Subject: [PATCH 09/10] Add date to logs to files Not sure why it's not there. Since the file name don't have date on them, it's better to at least have the date there. --- config/config.exs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config/config.exs b/config/config.exs index ed206f6a1..e22512d4f 100644 --- a/config/config.exs +++ b/config/config.exs @@ -104,17 +104,17 @@ config :logger, LoggerBackends.Console, level: :debug config :logger, :error_log, - format: "$time [$level] $metadata $message\n", + format: "$date $time [$level] $metadata $message\n", metadata: metadata, level: :error config :logger, :notice_log, - format: "$time [$level] $metadata $message\n", + format: "$date $time [$level] $metadata $message\n", metadata: metadata, level: :notice config :logger, :info_log, - format: "$time [$level] $metadata $message\n", + format: "$date $time [$level] $metadata $message\n", metadata: metadata, level: :info From 0853080a7912528be03eca24e3c7caac0fd086aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Charvet=20=E9=BB=91=E7=93=9C?= Date: Fri, 24 Jan 2025 08:46:28 +0000 Subject: [PATCH 10/10] mark some flaky tests --- test/teiserver_web/live/battles/match/chat_live_test.exs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/teiserver_web/live/battles/match/chat_live_test.exs b/test/teiserver_web/live/battles/match/chat_live_test.exs index cf76bf157..4f2d5c67d 100644 --- a/test/teiserver_web/live/battles/match/chat_live_test.exs +++ b/test/teiserver_web/live/battles/match/chat_live_test.exs @@ -4,6 +4,10 @@ defmodule TeiserverWeb.Battle.MatchLive.ChatLiveTest do alias Central.Helpers.GeneralTestLib + # https://github.com/beyond-all-reason/teiserver/actions/runs/12946468298/job/36111060092?pr=560 + # at a glance there's a problem with throttling in some cases? + @moduletag :needs_attention + setup do {:ok, kw} = GeneralTestLib.conn_setup(["Overwatch"], [:no_login])