diff --git a/lib/extensions/postgres_cdc_rls/cdc_rls.ex b/lib/extensions/postgres_cdc_rls/cdc_rls.ex index 1a3ee54c3..2a107a3bb 100644 --- a/lib/extensions/postgres_cdc_rls/cdc_rls.ex +++ b/lib/extensions/postgres_cdc_rls/cdc_rls.ex @@ -5,7 +5,7 @@ defmodule Extensions.PostgresCdcRls do @behaviour Realtime.PostgresCdc require Logger - import Realtime.Helpers, only: [log_error: 2] + import Realtime.Logs alias RealtimeWeb.Endpoint alias Extensions.PostgresCdcRls, as: Rls diff --git a/lib/extensions/postgres_cdc_rls/replication_poller.ex b/lib/extensions/postgres_cdc_rls/replication_poller.ex index 1a2aeb526..aef4d2172 100644 --- a/lib/extensions/postgres_cdc_rls/replication_poller.ex +++ b/lib/extensions/postgres_cdc_rls/replication_poller.ex @@ -8,7 +8,8 @@ defmodule Extensions.PostgresCdcRls.ReplicationPoller do require Logger - import Realtime.Helpers, only: [cancel_timer: 1, log_error: 2] + import Realtime.Logs + import Realtime.Helpers alias DBConnection.Backoff diff --git a/lib/extensions/postgres_cdc_rls/subscription_manager.ex b/lib/extensions/postgres_cdc_rls/subscription_manager.ex index e95b5cf7e..1d838e7f2 100644 --- a/lib/extensions/postgres_cdc_rls/subscription_manager.ex +++ b/lib/extensions/postgres_cdc_rls/subscription_manager.ex @@ -4,6 +4,7 @@ defmodule Extensions.PostgresCdcRls.SubscriptionManager do """ use GenServer require Logger + import Realtime.Logs alias Extensions.PostgresCdcRls, as: Rls @@ -165,7 +166,7 @@ defmodule Extensions.PostgresCdcRls.SubscriptionManager do q1 {:error, reason} -> - Helpers.log_error("SubscriptionDeletionFailed", reason) + log_error("SubscriptionDeletionFailed", reason) q end @@ -204,7 +205,7 @@ defmodule Extensions.PostgresCdcRls.SubscriptionManager do end def handle_info(msg, state) do - Helpers.log_error("UnhandledProcessMessage", msg) + log_error("UnhandledProcessMessage", msg) {:noreply, state} end diff --git a/lib/extensions/postgres_cdc_rls/subscriptions.ex b/lib/extensions/postgres_cdc_rls/subscriptions.ex index c482216b5..f6dac0669 100644 --- a/lib/extensions/postgres_cdc_rls/subscriptions.ex +++ b/lib/extensions/postgres_cdc_rls/subscriptions.ex @@ -4,7 +4,7 @@ defmodule Extensions.PostgresCdcRls.Subscriptions do """ require Logger import Postgrex, only: [transaction: 2, query: 3, rollback: 2] - import Realtime.Helpers, only: [to_log: 1, log_error: 2] + import Realtime.Logs @type conn() :: Postgrex.conn() diff --git a/lib/extensions/postgres_cdc_rls/subscriptions_checker.ex b/lib/extensions/postgres_cdc_rls/subscriptions_checker.ex index d5db017b6..5f4e674fa 100644 --- a/lib/extensions/postgres_cdc_rls/subscriptions_checker.ex +++ b/lib/extensions/postgres_cdc_rls/subscriptions_checker.ex @@ -2,7 +2,7 @@ defmodule Extensions.PostgresCdcRls.SubscriptionsChecker do @moduledoc false use GenServer require Logger - + import Realtime.Logs alias Extensions.PostgresCdcRls, as: Rls alias Realtime.Database @@ -107,7 +107,7 @@ defmodule Extensions.PostgresCdcRls.SubscriptionsChecker do q1 {:error, reason} -> - Helpers.log_error("UnableToDeletePhantomSubscriptions", reason) + log_error("UnableToDeletePhantomSubscriptions", reason) q end @@ -177,7 +177,7 @@ defmodule Extensions.PostgresCdcRls.SubscriptionsChecker do else case Rpc.call(node, __MODULE__, :not_alive_pids, [pids], timeout: 15_000) do {:badrpc, _} = error -> - Helpers.log_error("UnableToCheckProcessesOnRemoteNode", error) + log_error("UnableToCheckProcessesOnRemoteNode", error) acc pids -> diff --git a/lib/extensions/postgres_cdc_stream/cdc_stream.ex b/lib/extensions/postgres_cdc_stream/cdc_stream.ex index b61d5e8e2..8af7ed90c 100644 --- a/lib/extensions/postgres_cdc_stream/cdc_stream.ex +++ b/lib/extensions/postgres_cdc_stream/cdc_stream.ex @@ -3,7 +3,7 @@ defmodule Extensions.PostgresCdcStream do @behaviour Realtime.PostgresCdc require Logger - import Realtime.Helpers, only: [log_error: 2] + import Realtime.Logs alias Extensions.PostgresCdcStream, as: Stream alias Realtime.Rpc diff --git a/lib/extensions/postgres_cdc_stream/replication.ex b/lib/extensions/postgres_cdc_stream/replication.ex index c99c7c5d9..3aa52a506 100644 --- a/lib/extensions/postgres_cdc_stream/replication.ex +++ b/lib/extensions/postgres_cdc_stream/replication.ex @@ -7,7 +7,7 @@ defmodule Extensions.PostgresCdcStream.Replication do use Postgrex.ReplicationConnection require Logger - import Realtime.Helpers, only: [log_error: 2] + import Realtime.Logs import Realtime.Adapters.Postgres.Protocol alias Extensions.PostgresCdcStream diff --git a/lib/realtime/broadcast_changes/handler.ex b/lib/realtime/broadcast_changes/handler.ex index d10b3bcf3..c79e65c2c 100644 --- a/lib/realtime/broadcast_changes/handler.ex +++ b/lib/realtime/broadcast_changes/handler.ex @@ -21,7 +21,7 @@ defmodule Realtime.BroadcastChanges.Handler do import Realtime.Adapters.Postgres.Protocol import Realtime.Adapters.Postgres.Decoder - import Realtime.Helpers, only: [log_error: 2] + import Realtime.Logs alias Realtime.Adapters.Postgres.Decoder alias Realtime.Adapters.Postgres.Protocol.KeepAlive diff --git a/lib/realtime/database.ex b/lib/realtime/database.ex index cd746ecd3..05a426767 100644 --- a/lib/realtime/database.ex +++ b/lib/realtime/database.ex @@ -2,11 +2,10 @@ defmodule Realtime.Database do @moduledoc """ Handles tenant database operations """ - import Realtime.Helpers, only: [log_error: 2] + import Realtime.Logs alias Realtime.Api.Tenant alias Realtime.Crypto - alias Realtime.Helpers alias Realtime.PostgresCdc alias Realtime.Rpc @@ -138,7 +137,7 @@ defmodule Realtime.Database do {:error, e} -> Process.exit(conn, :kill) - Helpers.log_error("UnableToConnectToTenantDatabase", e) + log_error("UnableToConnectToTenantDatabase", e) {:error, e} end end diff --git a/lib/realtime/gen_counter/gen_counter.ex b/lib/realtime/gen_counter/gen_counter.ex index f62d7f27b..4b4b05f91 100644 --- a/lib/realtime/gen_counter/gen_counter.ex +++ b/lib/realtime/gen_counter/gen_counter.ex @@ -8,7 +8,7 @@ defmodule Realtime.GenCounter do """ use GenServer require Logger - import Realtime.Helpers, only: [log_error: 2] + import Realtime.Logs alias Realtime.GenCounter defstruct id: nil, counters: [] diff --git a/lib/realtime/helpers.ex b/lib/realtime/helpers.ex index 7344fe716..6c6209768 100644 --- a/lib/realtime/helpers.ex +++ b/lib/realtime/helpers.ex @@ -33,18 +33,4 @@ defmodule Realtime.Helpers do end end) end - - @doc """ - Prepares a value to be logged - """ - def to_log(value) when is_binary(value), do: value - def to_log(value), do: inspect(value, pretty: true) - - @doc """ - Logs error with a given Operational Code - """ - @spec log_error(String.t(), any(), keyword()) :: :ok - def log_error(code, error, metadata \\ []) do - Logger.error("#{code}: #{to_log(error)}", [error_code: code] ++ metadata) - end end diff --git a/lib/realtime/logs.ex b/lib/realtime/logs.ex new file mode 100644 index 000000000..caf0cceac --- /dev/null +++ b/lib/realtime/logs.ex @@ -0,0 +1,41 @@ +defmodule Realtime.Logs do + @moduledoc """ + Logging operations for Realtime + """ + require Logger + + @doc """ + Prepares a value to be logged + """ + def to_log(value) when is_binary(value), do: value + def to_log(value), do: inspect(value, pretty: true) + + @doc """ + Logs error with a given Operational Code + """ + @spec log_error(String.t(), any(), keyword()) :: :ok + def log_error(code, error, metadata \\ []) do + Logger.error("#{code}: #{to_log(error)}", [error_code: code] ++ metadata) + end +end + +defimpl Jason.Encoder, for: DBConnection.ConnectionError do + def encode( + %DBConnection.ConnectionError{message: message, reason: reason, severity: severity}, + _opts + ) do + inspect(%{message: message, reason: reason, severity: severity}, pretty: true) + end +end + +defimpl Jason.Encoder, for: Postgrex.Error do + def encode( + %Postgrex.Error{ + message: message, + postgres: %{code: code, schema: schema, table: table} + }, + _opts + ) do + inspect(%{message: message, schema: schema, table: table, code: code}, pretty: true) + end +end diff --git a/lib/realtime/monitoring/latency.ex b/lib/realtime/monitoring/latency.ex index 9828af86e..2abb3cc10 100644 --- a/lib/realtime/monitoring/latency.ex +++ b/lib/realtime/monitoring/latency.ex @@ -4,10 +4,9 @@ defmodule Realtime.Latency do """ use GenServer - require Logger + import Realtime.Logs - alias Realtime.Helpers alias Realtime.Nodes alias Realtime.Rpc @@ -107,7 +106,7 @@ defmodule Realtime.Latency do case response do {:badrpc, reason} -> - Helpers.log_error( + log_error( "RealtimeNodeDisconnected", "Unable to connect to #{short_name} from #{region}: #{reason}" ) diff --git a/lib/realtime/repo.ex b/lib/realtime/repo.ex index f37c9f8fd..a7b4f4380 100644 --- a/lib/realtime/repo.ex +++ b/lib/realtime/repo.ex @@ -6,7 +6,7 @@ defmodule Realtime.Repo do adapter: Ecto.Adapters.Postgres import Ecto.Query - import Realtime.Helpers, only: [log_error: 2] + import Realtime.Logs def with_dynamic_repo(config, callback) do default_dynamic_repo = get_dynamic_repo() diff --git a/lib/realtime/rpc.ex b/lib/realtime/rpc.ex index 1d081a196..1564db0ab 100644 --- a/lib/realtime/rpc.ex +++ b/lib/realtime/rpc.ex @@ -3,7 +3,7 @@ defmodule Realtime.Rpc do RPC module for Realtime with the intent of standardizing the RPC interface and collect telemetry """ alias Realtime.Telemetry - import Realtime.Helpers + import Realtime.Logs @doc """ Calls external node using :rpc.call/5 and collects telemetry diff --git a/lib/realtime/tenants/authorization/policies/broadcast_policies.ex b/lib/realtime/tenants/authorization/policies/broadcast_policies.ex index 732b7d661..d6d2245ba 100644 --- a/lib/realtime/tenants/authorization/policies/broadcast_policies.ex +++ b/lib/realtime/tenants/authorization/policies/broadcast_policies.ex @@ -8,7 +8,7 @@ defmodule Realtime.Tenants.Authorization.Policies.BroadcastPolicies do """ require Logger import Ecto.Query - import Realtime.Helpers, only: [log_error: 2, to_log: 1] + import Realtime.Logs alias Realtime.Api.Message alias Realtime.Repo diff --git a/lib/realtime/tenants/authorization/policies/presence_policies.ex b/lib/realtime/tenants/authorization/policies/presence_policies.ex index c6f36ad6d..cd5d7ff9c 100644 --- a/lib/realtime/tenants/authorization/policies/presence_policies.ex +++ b/lib/realtime/tenants/authorization/policies/presence_policies.ex @@ -8,7 +8,7 @@ defmodule Realtime.Tenants.Authorization.Policies.PresencePolicies do """ require Logger import Ecto.Query - import Realtime.Helpers, only: [to_log: 1, log_error: 2] + import Realtime.Logs alias Realtime.Api.Message alias Realtime.Repo diff --git a/lib/realtime/tenants/connect.ex b/lib/realtime/tenants/connect.ex index 03e312c26..a99ddb246 100644 --- a/lib/realtime/tenants/connect.ex +++ b/lib/realtime/tenants/connect.ex @@ -10,7 +10,7 @@ defmodule Realtime.Tenants.Connect do require Logger - import Realtime.Helpers, only: [log_error: 2] + import Realtime.Logs alias Realtime.Api.Tenant alias Realtime.BroadcastChanges.Handler diff --git a/lib/realtime/tenants/janitor.ex b/lib/realtime/tenants/janitor.ex index ea7a7726d..06c5f26c2 100644 --- a/lib/realtime/tenants/janitor.ex +++ b/lib/realtime/tenants/janitor.ex @@ -6,7 +6,7 @@ defmodule Realtime.Tenants.Janitor do use GenServer require Logger - import Realtime.Helpers, only: [log_error: 2] + import Realtime.Logs alias Realtime.Api.Tenant alias Realtime.Database diff --git a/lib/realtime/tenants/migrations.ex b/lib/realtime/tenants/migrations.ex index 22f4e324d..7264b8257 100644 --- a/lib/realtime/tenants/migrations.ex +++ b/lib/realtime/tenants/migrations.ex @@ -6,7 +6,7 @@ defmodule Realtime.Tenants.Migrations do require Logger - import Realtime.Helpers, only: [log_error: 2] + import Realtime.Logs alias Realtime.Crypto alias Realtime.Database @@ -203,7 +203,7 @@ defmodule Realtime.Tenants.Migrations do If not all migrations have been run, it will run the missing migrations. """ @spec maybe_run_migrations(pid(), Tenant.t()) :: :ok - def maybe_run_migrations(db_conn, tenant) do + def maybe_run_migrations(_db_conn, tenant) do # Logger.metadata(external_id: tenant.external_id, project: tenant.external_id) # check_migrations_exist_query = diff --git a/lib/realtime_web/channels/auth/channels_authorization.ex b/lib/realtime_web/channels/auth/channels_authorization.ex index 967742328..44291ade2 100644 --- a/lib/realtime_web/channels/auth/channels_authorization.ex +++ b/lib/realtime_web/channels/auth/channels_authorization.ex @@ -3,7 +3,7 @@ defmodule RealtimeWeb.ChannelsAuthorization do Check connection is authorized to access channel """ require Logger - import Realtime.Helpers, only: [log_error: 2] + import Realtime.Logs def authorize(token, jwt_secret, jwt_jwks) when is_binary(token) do token diff --git a/lib/realtime_web/channels/realtime_channel.ex b/lib/realtime_web/channels/realtime_channel.ex index d12106312..e51483e24 100644 --- a/lib/realtime_web/channels/realtime_channel.ex +++ b/lib/realtime_web/channels/realtime_channel.ex @@ -4,6 +4,7 @@ defmodule RealtimeWeb.RealtimeChannel do """ use RealtimeWeb, :channel require Logger + import Realtime.Logs alias DBConnection.Backoff @@ -240,7 +241,7 @@ defmodule RealtimeWeb.RealtimeChannel do {:noreply, assign(socket, :pg_sub_ref, nil)} error -> - Helpers.log_error("UnableToSubscribeToPostgres", error) + log_error("UnableToSubscribeToPostgres", error) push_system_message("postgres_changes", socket, "error", error, channel_name) {:noreply, assign(socket, :pg_sub_ref, postgres_subscribe(5, 10))} end @@ -267,13 +268,13 @@ defmodule RealtimeWeb.RealtimeChannel do shutdown_response(socket, "Fields `role` and `exp` are required in JWT") {:error, error} -> - message = "Access token has expired: " <> Helpers.to_log(error) + message = "Access token has expired: " <> to_log(error) shutdown_response(socket, message) end end def handle_info(msg, socket) do - Helpers.log_error("UnhandledSystemMessage", msg) + log_error("UnhandledSystemMessage", msg) {:noreply, socket} end @@ -522,7 +523,7 @@ defmodule RealtimeWeb.RealtimeChannel do defp shutdown_response(%{assigns: %{channel_name: channel_name}} = socket, message) when is_binary(message) do - Helpers.log_error("ChannelShutdown", message) + log_error("ChannelShutdown", message) push_system_message("system", socket, "error", message, channel_name) {:stop, :shutdown, socket} end diff --git a/lib/realtime_web/channels/realtime_channel/logging.ex b/lib/realtime_web/channels/realtime_channel/logging.ex index 439af3190..a5bd6c1c3 100644 --- a/lib/realtime_web/channels/realtime_channel/logging.ex +++ b/lib/realtime_web/channels/realtime_channel/logging.ex @@ -3,7 +3,7 @@ defmodule RealtimeWeb.RealtimeChannel.Logging do Log functions for Realtime channels to ensure """ require Logger - import Realtime.Helpers, only: [log_error: 2, to_log: 1] + import Realtime.Logs @doc """ Logs messages according to user options given on config diff --git a/lib/realtime_web/channels/user_socket.ex b/lib/realtime_web/channels/user_socket.ex index a687734a8..3f85af6c4 100644 --- a/lib/realtime_web/channels/user_socket.ex +++ b/lib/realtime_web/channels/user_socket.ex @@ -3,7 +3,7 @@ defmodule RealtimeWeb.UserSocket do require Logger - import Realtime.Helpers, only: [log_error: 2] + import Realtime.Logs alias Realtime.Api.Tenant alias Realtime.Crypto diff --git a/lib/realtime_web/controllers/fallback_controller.ex b/lib/realtime_web/controllers/fallback_controller.ex index 7df1b76b9..5ad81e005 100644 --- a/lib/realtime_web/controllers/fallback_controller.ex +++ b/lib/realtime_web/controllers/fallback_controller.ex @@ -6,7 +6,7 @@ defmodule RealtimeWeb.FallbackController do """ use RealtimeWeb, :controller import RealtimeWeb.ErrorHelpers - alias Realtime.Helpers + import Realtime.Logs def call(conn, {:error, :not_found}) do conn @@ -16,7 +16,7 @@ defmodule RealtimeWeb.FallbackController do end def call(conn, {:error, %Ecto.Changeset{} = changeset}) do - Helpers.log_error( + log_error( "UnprocessableEntity", Ecto.Changeset.traverse_errors(changeset, &translate_error/1) ) @@ -35,7 +35,7 @@ defmodule RealtimeWeb.FallbackController do end def call(conn, {:error, status, message}) when is_atom(status) and is_binary(message) do - Helpers.log_error("UnprocessableEntity", message) + log_error("UnprocessableEntity", message) conn |> put_status(status) @@ -44,7 +44,7 @@ defmodule RealtimeWeb.FallbackController do end def call(conn, %Ecto.Changeset{valid?: true} = changeset) do - Helpers.log_error( + log_error( "UnprocessableEntity", Ecto.Changeset.traverse_errors(changeset, &translate_error/1) ) @@ -56,7 +56,7 @@ defmodule RealtimeWeb.FallbackController do end def call(conn, %Ecto.Changeset{valid?: false} = changeset) do - Helpers.log_error( + log_error( "UnprocessableEntity", Ecto.Changeset.traverse_errors(changeset, &translate_error/1) ) @@ -68,7 +68,7 @@ defmodule RealtimeWeb.FallbackController do end def call(conn, response) do - Helpers.log_error("UnknownError", response) + log_error("UnknownError", response) conn |> put_status(:unprocessable_entity) diff --git a/lib/realtime_web/controllers/tenant_controller.ex b/lib/realtime_web/controllers/tenant_controller.ex index 1224ffebb..e76f49212 100644 --- a/lib/realtime_web/controllers/tenant_controller.ex +++ b/lib/realtime_web/controllers/tenant_controller.ex @@ -1,15 +1,12 @@ defmodule RealtimeWeb.TenantController do - alias RealtimeWeb.OpenApiSchemas.UnauthorizedResponse - alias RealtimeWeb.OpenApiSchemas.ErrorResponse use RealtimeWeb, :controller use OpenApiSpex.ControllerSpecs - require Logger + import Realtime.Logs alias Realtime.Api alias Realtime.Api.Tenant alias Realtime.Database - alias Realtime.Helpers alias Realtime.PostgresCdc alias Realtime.Tenants alias Realtime.Tenants.Cache @@ -19,11 +16,13 @@ defmodule RealtimeWeb.TenantController do alias RealtimeWeb.OpenApiSchemas.{ EmptyResponse, + ErrorResponse, NotFoundResponse, + TenantHealthResponse, + TenantParams, TenantResponse, TenantResponseList, - TenantParams, - TenantHealthResponse + UnauthorizedResponse } @stop_timeout 10_000 @@ -199,11 +198,11 @@ defmodule RealtimeWeb.TenantController do send_resp(conn, 204, "") else nil -> - Helpers.log_error("TenantNotFound", "Tenant not found") + log_error("TenantNotFound", "Tenant not found") send_resp(conn, 204, "") err -> - Helpers.log_error("UnableToDeleteTenant", err) + log_error("UnableToDeleteTenant", err) conn |> put_status(500) |> json(err) |> halt() end end @@ -233,7 +232,7 @@ defmodule RealtimeWeb.TenantController do case Tenants.get_tenant_by_external_id(tenant_id) do nil -> - Helpers.log_error("TenantNotFound", "Tenant not found") + log_error("TenantNotFound", "Tenant not found") conn |> put_status(404) @@ -276,7 +275,7 @@ defmodule RealtimeWeb.TenantController do json(conn, %{data: response}) {:error, :tenant_not_found} -> - Helpers.log_error("TenantNotFound", "Tenant not found") + log_error("TenantNotFound", "Tenant not found") conn |> put_status(404) @@ -292,7 +291,7 @@ defmodule RealtimeWeb.TenantController do render(conn, "show.json", tenant: tenant) nil -> - Helpers.log_error("TenantNotFound", "Tenant not found") + log_error("TenantNotFound", "Tenant not found") conn |> put_status(404) diff --git a/mix.exs b/mix.exs index ef7238970..6f9cfa6db 100644 --- a/mix.exs +++ b/mix.exs @@ -4,7 +4,7 @@ defmodule Realtime.MixProject do def project do [ app: :realtime, - version: "2.33.47", + version: "2.33.48", elixir: "~> 1.16.0", elixirc_paths: elixirc_paths(Mix.env()), start_permanent: Mix.env() == :prod,