This commit is contained in:
@@ -23,7 +23,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Build and push backend image
|
- name: Build and push backend image
|
||||||
run: |
|
run: |
|
||||||
docker build -t alexmickelson/ai-liveview:$GITHUB_RUN_NUMBER .
|
docker build -q -t alexmickelson/ai-liveview:$GITHUB_RUN_NUMBER .
|
||||||
docker push -q alexmickelson/ai-liveview:$GITHUB_RUN_NUMBER
|
docker push -q alexmickelson/ai-liveview:$GITHUB_RUN_NUMBER
|
||||||
|
|
||||||
- name: Deploy to Kubernetes
|
- name: Deploy to Kubernetes
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ config :elixir_ai, ElixirAiWeb.Endpoint,
|
|||||||
layout: false
|
layout: false
|
||||||
],
|
],
|
||||||
pubsub_server: ElixirAi.PubSub,
|
pubsub_server: ElixirAi.PubSub,
|
||||||
live_view: [signing_salt: "4UG1IVt+"]
|
live_view: [signing_salt: "4UG1IVt+"],
|
||||||
|
log: false
|
||||||
|
|
||||||
# Configure esbuild (the version is required)
|
# Configure esbuild (the version is required)
|
||||||
config :esbuild,
|
config :esbuild,
|
||||||
@@ -46,12 +47,7 @@ config :tailwind,
|
|||||||
# Configures Elixir's Logger
|
# Configures Elixir's Logger
|
||||||
config :logger, :console,
|
config :logger, :console,
|
||||||
format: "$time $metadata[$level] $message\n",
|
format: "$time $metadata[$level] $message\n",
|
||||||
metadata: [:request_id],
|
metadata: [:request_id]
|
||||||
filters: [:health_check_filter]
|
|
||||||
|
|
||||||
config :logger, :health_check_filter,
|
|
||||||
module: ElixirAiWeb.HealthCheckFilter,
|
|
||||||
function: :filter
|
|
||||||
|
|
||||||
# Use Jason for JSON parsing in Phoenix
|
# Use Jason for JSON parsing in Phoenix
|
||||||
config :phoenix, :json_library, Jason
|
config :phoenix, :json_library, Jason
|
||||||
@@ -59,7 +55,9 @@ config :phoenix, :json_library, Jason
|
|||||||
# Lower the BEAM node-down detection window from the default 60s.
|
# Lower the BEAM node-down detection window from the default 60s.
|
||||||
# Nodes send ticks every (net_ticktime / 4)s; a node is declared down
|
# Nodes send ticks every (net_ticktime / 4)s; a node is declared down
|
||||||
# after 4 missed ticks (net_ticktime total). 5s means detection in ≤5s.
|
# after 4 missed ticks (net_ticktime total). 5s means detection in ≤5s.
|
||||||
|
if System.get_env("RELEASE_MODE") do
|
||||||
config :kernel, net_ticktime: 2
|
config :kernel, net_ticktime: 2
|
||||||
|
end
|
||||||
|
|
||||||
# Libcluster — Gossip strategy works for local dev and Docker Compose
|
# Libcluster — Gossip strategy works for local dev and Docker Compose
|
||||||
# (UDP multicast, zero config). Overridden to Kubernetes.DNS in runtime.exs for prod.
|
# (UDP multicast, zero config). Overridden to Kubernetes.DNS in runtime.exs for prod.
|
||||||
|
|||||||
@@ -4,6 +4,14 @@ defmodule ElixirAi.Application do
|
|||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def start(_type, _args) do
|
def start(_type, _args) do
|
||||||
|
# Attach custom logger that filters health checks
|
||||||
|
:telemetry.attach(
|
||||||
|
"phoenix-endpoint-logger",
|
||||||
|
[:phoenix, :endpoint, :stop],
|
||||||
|
&__MODULE__.log_request/4,
|
||||||
|
%{}
|
||||||
|
)
|
||||||
|
|
||||||
children = [
|
children = [
|
||||||
ElixirAiWeb.Telemetry,
|
ElixirAiWeb.Telemetry,
|
||||||
ElixirAi.Repo,
|
ElixirAi.Repo,
|
||||||
@@ -39,4 +47,32 @@ defmodule ElixirAi.Application do
|
|||||||
ElixirAiWeb.Endpoint.config_change(changed, removed)
|
ElixirAiWeb.Endpoint.config_change(changed, removed)
|
||||||
:ok
|
:ok
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Custom request logger that filters health check endpoint
|
||||||
|
require Logger
|
||||||
|
|
||||||
|
def log_request(_event, measurements, %{conn: conn}, _config) do
|
||||||
|
# Skip logging for health check endpoint
|
||||||
|
if conn.request_path != "/health" do
|
||||||
|
duration = System.convert_time_unit(measurements.duration, :native, :microsecond)
|
||||||
|
|
||||||
|
Logger.info(
|
||||||
|
fn ->
|
||||||
|
[conn.method, " ", conn.request_path]
|
||||||
|
end,
|
||||||
|
request_id: conn.assigns[:request_id]
|
||||||
|
)
|
||||||
|
|
||||||
|
Logger.info(
|
||||||
|
fn ->
|
||||||
|
["Sent ", to_string(conn.status), " in ", format_duration(duration)]
|
||||||
|
end,
|
||||||
|
request_id: conn.assigns[:request_id]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp format_duration(μs) when μs < 1000, do: "#{μs}µs"
|
||||||
|
defp format_duration(μs) when μs < 1_000_000, do: "#{div(μs, 1000)}ms"
|
||||||
|
defp format_duration(μs), do: "#{Float.round(μs / 1_000_000, 2)}s"
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ defmodule ElixirAiWeb.Endpoint do
|
|||||||
cookie_key: "request_logger"
|
cookie_key: "request_logger"
|
||||||
|
|
||||||
plug Plug.RequestId
|
plug Plug.RequestId
|
||||||
plug ElixirAiWeb.Plugs.HealthCheckLogger
|
|
||||||
plug Plug.Telemetry, event_prefix: [:phoenix, :endpoint]
|
plug Plug.Telemetry, event_prefix: [:phoenix, :endpoint]
|
||||||
|
|
||||||
plug Plug.Parsers,
|
plug Plug.Parsers,
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
defmodule ElixirAiWeb.HealthCheckFilter do
|
|
||||||
@moduledoc """
|
|
||||||
Logger filter to suppress health check endpoint logs.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def filter(%{meta: meta}, _config) when is_map(meta) do
|
|
||||||
if Map.get(meta, :health_check) == true do
|
|
||||||
:stop
|
|
||||||
else
|
|
||||||
:ignore
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def filter(_log_event, _config), do: :ignore
|
|
||||||
end
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
defmodule ElixirAiWeb.Plugs.HealthCheckLogger do
|
|
||||||
@moduledoc """
|
|
||||||
Plug that marks health check requests for filtering.
|
|
||||||
"""
|
|
||||||
@behaviour Plug
|
|
||||||
require Logger
|
|
||||||
|
|
||||||
@impl true
|
|
||||||
def init(opts), do: opts
|
|
||||||
|
|
||||||
@impl true
|
|
||||||
def call(%Plug.Conn{path_info: ["health"]} = conn, _opts) do
|
|
||||||
# Mark this as a health check for logger filtering
|
|
||||||
Logger.metadata(health_check: true)
|
|
||||||
conn
|
|
||||||
end
|
|
||||||
|
|
||||||
def call(conn, _opts), do: conn
|
|
||||||
end
|
|
||||||
2
mix.lock
2
mix.lock
@@ -1,8 +1,10 @@
|
|||||||
%{
|
%{
|
||||||
"acceptor_pool": {:hex, :acceptor_pool, "1.0.1", "d88c2e8a0be9216cf513fbcd3e5a4beb36bee3ff4168e85d6152c6f899359cdb", [:rebar3], [], "hexpm", "f172f3d74513e8edd445c257d596fc84dbdd56d2c6fa287434269648ae5a421e"},
|
"acceptor_pool": {:hex, :acceptor_pool, "1.0.1", "d88c2e8a0be9216cf513fbcd3e5a4beb36bee3ff4168e85d6152c6f899359cdb", [:rebar3], [], "hexpm", "f172f3d74513e8edd445c257d596fc84dbdd56d2c6fa287434269648ae5a421e"},
|
||||||
"bandit": {:hex, :bandit, "1.10.3", "1e5d168fa79ec8de2860d1b4d878d97d4fbbe2fdbe7b0a7d9315a4359d1d4bb9", [:mix], [{:hpax, "~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}, {:plug, "~> 1.18", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:thousand_island, "~> 1.0", [hex: :thousand_island, repo: "hexpm", optional: false]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "99a52d909c48db65ca598e1962797659e3c0f1d06e825a50c3d75b74a5e2db18"},
|
"bandit": {:hex, :bandit, "1.10.3", "1e5d168fa79ec8de2860d1b4d878d97d4fbbe2fdbe7b0a7d9315a4359d1d4bb9", [:mix], [{:hpax, "~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}, {:plug, "~> 1.18", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:thousand_island, "~> 1.0", [hex: :thousand_island, repo: "hexpm", optional: false]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "99a52d909c48db65ca598e1962797659e3c0f1d06e825a50c3d75b74a5e2db18"},
|
||||||
|
"bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"},
|
||||||
"castore": {:hex, :castore, "1.0.17", "4f9770d2d45fbd91dcf6bd404cf64e7e58fed04fadda0923dc32acca0badffa2", [:mix], [], "hexpm", "12d24b9d80b910dd3953e165636d68f147a31db945d2dcb9365e441f8b5351e5"},
|
"castore": {:hex, :castore, "1.0.17", "4f9770d2d45fbd91dcf6bd404cf64e7e58fed04fadda0923dc32acca0badffa2", [:mix], [], "hexpm", "12d24b9d80b910dd3953e165636d68f147a31db945d2dcb9365e441f8b5351e5"},
|
||||||
"chatterbox": {:hex, :ts_chatterbox, "0.15.1", "5cac4d15dd7ad61fc3c4415ce4826fc563d4643dee897a558ec4ea0b1c835c9c", [:rebar3], [{:hpack, "~> 0.3.0", [hex: :hpack_erl, repo: "hexpm", optional: false]}], "hexpm", "4f75b91451338bc0da5f52f3480fa6ef6e3a2aeecfc33686d6b3d0a0948f31aa"},
|
"chatterbox": {:hex, :ts_chatterbox, "0.15.1", "5cac4d15dd7ad61fc3c4415ce4826fc563d4643dee897a558ec4ea0b1c835c9c", [:rebar3], [{:hpack, "~> 0.3.0", [hex: :hpack_erl, repo: "hexpm", optional: false]}], "hexpm", "4f75b91451338bc0da5f52f3480fa6ef6e3a2aeecfc33686d6b3d0a0948f31aa"},
|
||||||
|
"credo": {:hex, :credo, "1.7.17", "f92b6aa5b26301eaa5a35e4d48ebf5aa1e7094ac00ae38f87086c562caf8a22f", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "1eb5645c835f0b6c9b5410f94b5a185057bcf6d62a9c2b476da971cde8749645"},
|
||||||
"ctx": {:hex, :ctx, "0.6.0", "8ff88b70e6400c4df90142e7f130625b82086077a45364a78d208ed3ed53c7fe", [:rebar3], [], "hexpm", "a14ed2d1b67723dbebbe423b28d7615eb0bdcba6ff28f2d1f1b0a7e1d4aa5fc2"},
|
"ctx": {:hex, :ctx, "0.6.0", "8ff88b70e6400c4df90142e7f130625b82086077a45364a78d208ed3ed53c7fe", [:rebar3], [], "hexpm", "a14ed2d1b67723dbebbe423b28d7615eb0bdcba6ff28f2d1f1b0a7e1d4aa5fc2"},
|
||||||
"db_connection": {:hex, :db_connection, "2.9.0", "a6a97c5c958a2d7091a58a9be40caf41ab496b0701d21e1d1abff3fa27a7f371", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "17d502eacaf61829db98facf6f20808ed33da6ccf495354a41e64fe42f9c509c"},
|
"db_connection": {:hex, :db_connection, "2.9.0", "a6a97c5c958a2d7091a58a9be40caf41ab496b0701d21e1d1abff3fa27a7f371", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "17d502eacaf61829db98facf6f20808ed33da6ccf495354a41e64fe42f9c509c"},
|
||||||
"decimal": {:hex, :decimal, "2.3.0", "3ad6255aa77b4a3c4f818171b12d237500e63525c2fd056699967a3e7ea20f62", [:mix], [], "hexpm", "a4d66355cb29cb47c3cf30e71329e58361cfcb37c34235ef3bf1d7bf3773aeac"},
|
"decimal": {:hex, :decimal, "2.3.0", "3ad6255aa77b4a3c4f818171b12d237500e63525c2fd056699967a3e7ea20f62", [:mix], [], "hexpm", "a4d66355cb29cb47c3cf30e71329e58361cfcb37c34235ef3bf1d7bf3773aeac"},
|
||||||
|
|||||||
Reference in New Issue
Block a user