Skip to content

Commit 9686617

Browse files
authored
fix: simplify logging approach (#1492)
1 parent 9aed839 commit 9686617

File tree

15 files changed

+327
-488
lines changed

15 files changed

+327
-488
lines changed

config/config.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ config :tailwind,
5151
# Configures Elixir's Logger
5252
config :logger, :console,
5353
format: "$time $metadata[$level] $message\n",
54-
metadata: [:request_id, :project, :external_id, :application_name, :error_code]
54+
metadata: [:request_id, :project, :external_id, :application_name, :error_code, :sub, :iss, :exp]
5555

5656
# Use Jason for JSON parsing in Phoenix
5757
config :phoenix, :json_library, Jason

config/dev.exs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,19 @@ config :realtime, RealtimeWeb.Endpoint,
7373
# Do not include metadata nor timestamps in development logs
7474
config :logger, :console,
7575
format: "$time [$level] $message $metadata\n",
76-
metadata: [:error_code, :file, :pid, :project, :external_id, :application_name, :region, :request_id]
76+
metadata: [
77+
:error_code,
78+
:file,
79+
:pid,
80+
:project,
81+
:external_id,
82+
:application_name,
83+
:region,
84+
:request_id,
85+
:sub,
86+
:iss,
87+
:exp
88+
]
7789

7890
# Set a higher stacktrace during development. Avoid configuring such
7991
# in production as building large stacktraces may be expensive.

config/prod.exs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,19 @@ import Config
1515
# Do not print debug messages in production
1616
config :logger, :warning,
1717
format: "$time [$level] $message $metadata\n",
18-
metadata: [:error_code, :file, :pid, :project, :external_id, :application_name, :region, :request_id]
18+
metadata: [
19+
:error_code,
20+
:file,
21+
:pid,
22+
:project,
23+
:external_id,
24+
:application_name,
25+
:region,
26+
:request_id,
27+
:sub,
28+
:iss,
29+
:exp
30+
]
1931

2032
# ## SSL Support
2133
#

config/runtime.exs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,6 @@ if config_env() != :test do
181181

182182
config :realtime,
183183
request_id_baggage_key: System.get_env("REQUEST_ID_BAGGAGE_KEY", "request-id"),
184-
secure_channels: System.get_env("SECURE_CHANNELS", "true") == "true",
185184
jwt_claim_validators: System.get_env("JWT_CLAIM_VALIDATORS", "{}"),
186185
api_jwt_secret: System.get_env("API_JWT_SECRET"),
187186
api_blocklist: System.get_env("API_TOKEN_BLOCKLIST", "") |> String.split(","),

config/test.exs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ config :realtime, RealtimeWeb.Endpoint,
3232

3333
config :realtime,
3434
region: "us-east-1",
35-
secure_channels: true,
3635
db_enc_key: "1234567890123456",
3736
jwt_claim_validators: System.get_env("JWT_CLAIM_VALIDATORS", "{}"),
3837
api_jwt_secret: System.get_env("API_JWT_SECRET", "secret"),
@@ -48,7 +47,7 @@ config :logger,
4847
# Configures Elixir's Logger
4948
config :logger, :console,
5049
format: "$time $metadata[$level] $message\n",
51-
metadata: [:request_id, :project, :external_id, :application_name, :sub, :exp, :iss]
50+
metadata: [:request_id, :project, :external_id, :application_name, :sub, :iss, :exp]
5251

5352
config :opentelemetry,
5453
span_processor: :simple,

lib/realtime/application.ex

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,13 @@ defmodule Realtime.Application do
2727

2828
topologies = Application.get_env(:libcluster, :topologies) || []
2929

30-
if Application.fetch_env!(:realtime, :secure_channels) do
31-
case Application.fetch_env!(:realtime, :jwt_claim_validators) |> Jason.decode() do
32-
{:ok, claims} when is_map(claims) ->
33-
Application.put_env(:realtime, :jwt_claim_validators, claims)
34-
35-
_ ->
36-
raise JwtClaimValidatorsError,
37-
message: "JWT claim validators is not a valid JSON object"
38-
end
30+
case Application.fetch_env!(:realtime, :jwt_claim_validators) |> Jason.decode() do
31+
{:ok, claims} when is_map(claims) ->
32+
Application.put_env(:realtime, :jwt_claim_validators, claims)
33+
34+
_ ->
35+
raise JwtClaimValidatorsError,
36+
message: "JWT claim validators is not a valid JSON object"
3937
end
4038

4139
:ok =

lib/realtime_web/channels/realtime_channel.ex

Lines changed: 33 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ defmodule RealtimeWeb.RealtimeChannel do
3131
@confirm_token_ms_interval :timer.minutes(5)
3232

3333
@impl true
34-
def join("realtime:", _params, _socket) do
35-
Logging.log_error_message(:error, "TopicNameRequired", "You must provide a topic name")
34+
def join("realtime:", _params, socket) do
35+
Logging.log_error(socket, "TopicNameRequired", "You must provide a topic name")
3636
end
3737

3838
def join("realtime:" <> sub_topic = topic, params, socket) do
@@ -55,22 +55,21 @@ defmodule RealtimeWeb.RealtimeChannel do
5555
|> assign(:private?, !!params["config"]["private"])
5656
|> assign(:policies, nil)
5757

58-
token = socket.assigns.access_token
59-
log_level = socket.assigns.log_level
60-
6158
with :ok <- SignalHandler.shutdown_in_progress?(),
6259
:ok <- only_private?(tenant_id, socket),
63-
:ok <- limit_joins(socket.assigns),
60+
:ok <- limit_joins(socket),
6461
:ok <- limit_channels(socket),
65-
:ok <- limit_max_users(socket.assigns),
62+
:ok <- limit_max_users(socket),
6663
{:ok, claims, confirm_token_ref, access_token, _} <- confirm_token(socket),
6764
socket = assign_authorization_context(socket, sub_topic, access_token, claims),
6865
{:ok, db_conn} <- Connect.lookup_or_start_connection(tenant_id),
6966
{:ok, socket} <- maybe_assign_policies(sub_topic, db_conn, socket) do
7067
tenant_topic = Tenants.tenant_topic(tenant_id, sub_topic, !socket.assigns.private?)
7168

7269
# fastlane subscription
73-
metadata = MessageDispatcher.fastlane_metadata(transport_pid, serializer, topic, log_level, tenant_id)
70+
metadata =
71+
MessageDispatcher.fastlane_metadata(transport_pid, serializer, topic, socket.assigns.log_level, tenant_id)
72+
7473
RealtimeWeb.Endpoint.subscribe(tenant_topic, metadata: metadata)
7574

7675
Phoenix.PubSub.subscribe(Realtime.PubSub, "realtime:operations:" <> tenant_id)
@@ -121,109 +120,77 @@ defmodule RealtimeWeb.RealtimeChannel do
121120
{:ok, state, assign(socket, assigns)}
122121
else
123122
{:error, :expired_token, msg} ->
124-
Logging.maybe_log_warning_with_token_metadata("InvalidJWTToken", msg, token, log_level)
123+
Logging.maybe_log_warning(socket, "InvalidJWTToken", msg)
125124

126125
{:error, :missing_claims} ->
127126
msg = "Fields `role` and `exp` are required in JWT"
128-
Logging.maybe_log_warning_with_token_metadata("InvalidJWTToken", msg, token, log_level)
127+
Logging.maybe_log_warning(socket, "InvalidJWTToken", msg)
129128

130129
{:error, :unauthorized, msg} ->
131-
Logging.log_error_message(:error, "Unauthorized", msg)
130+
Logging.log_error(socket, "Unauthorized", msg)
132131

133132
{:error, :too_many_channels} ->
134133
msg = "Too many channels"
135-
Logging.log_error_message(:error, "ChannelRateLimitReached", msg)
134+
Logging.log_error(socket, "ChannelRateLimitReached", msg)
136135

137136
{:error, :too_many_connections} ->
138137
msg = "Too many connected users"
139-
Logging.log_error_message(:error, "ConnectionRateLimitReached", msg)
138+
Logging.log_error(socket, "ConnectionRateLimitReached", msg)
140139

141140
{:error, :too_many_joins} ->
142141
msg = "Too many joins per second"
143142
{:error, %{reason: msg}}
144143

145144
{:error, :increase_connection_pool} ->
146145
msg = "Please increase your connection pool size"
147-
Logging.log_error_message(:error, "IncreaseConnectionPool", msg)
146+
Logging.log_error(socket, "IncreaseConnectionPool", msg)
148147

149148
{:error, :tenant_db_too_many_connections} ->
150149
msg = "Database can't accept more connections, Realtime won't connect"
151-
Logging.log_error_message(:error, "DatabaseLackOfConnections", msg)
150+
Logging.log_error(socket, "DatabaseLackOfConnections", msg)
152151

153152
{:error, :unable_to_set_policies, error} ->
154-
Logging.log_error_message(:error, "UnableToSetPolicies", error)
153+
Logging.log_error(socket, "UnableToSetPolicies", error)
155154
{:error, %{reason: "Realtime was unable to connect to the project database"}}
156155

157156
{:error, :tenant_database_unavailable} ->
158-
Logging.log_error_message(
159-
:error,
160-
"UnableToConnectToProject",
161-
"Realtime was unable to connect to the project database"
162-
)
157+
Logging.log_error(socket, "UnableToConnectToProject", "Realtime was unable to connect to the project database")
163158

164159
{:error, :rpc_error, :timeout} ->
165-
Logging.log_error_message(:error, "TimeoutOnRpcCall", "Node request timeout")
160+
Logging.log_error(socket, "TimeoutOnRpcCall", "Node request timeout")
166161

167162
{:error, :rpc_error, reason} ->
168-
Logging.log_error_message(:error, "ErrorOnRpcCall", "RPC call error: " <> inspect(reason))
163+
Logging.log_error(socket, "ErrorOnRpcCall", "RPC call error: " <> inspect(reason))
169164

170165
{:error, :initializing} ->
171-
Logging.log_error_message(
172-
:error,
173-
"InitializingProjectConnection",
174-
"Realtime is initializing the project connection"
175-
)
166+
Logging.log_error(socket, "InitializingProjectConnection", "Realtime is initializing the project connection")
176167

177168
{:error, :tenant_database_connection_initializing} ->
178-
Logging.log_error_message(
179-
:error,
180-
"InitializingProjectConnection",
181-
"Connecting to the project database"
182-
)
169+
Logging.log_error(socket, "InitializingProjectConnection", "Connecting to the project database")
183170

184171
{:error, :token_malformed, msg} ->
185-
Logging.log_error_message(:error, "MalformedJWT", msg)
172+
Logging.log_error(socket, "MalformedJWT", msg)
186173

187174
{:error, invalid_exp} when is_integer(invalid_exp) and invalid_exp <= 0 ->
188-
Logging.log_error_with_token_metadata(
189-
"InvalidJWTToken",
190-
"Token expiration time is invalid",
191-
socket.assigns.access_token
192-
)
175+
Logging.log_error(socket, "InvalidJWTToken", "Token expiration time is invalid")
193176

194177
{:error, :private_only} ->
195-
Logging.log_error_message(
196-
:error,
197-
"PrivateOnly",
198-
"This project only allows private channels"
199-
)
178+
Logging.log_error(socket, "PrivateOnly", "This project only allows private channels")
200179

201180
{:error, :tenant_not_found} ->
202-
Logging.log_error_message(
203-
:error,
204-
"TenantNotFound",
205-
"Tenant with the given ID does not exist"
206-
)
181+
Logging.log_error(socket, "TenantNotFound", "Tenant with the given ID does not exist")
207182

208183
{:error, :tenant_suspended} ->
209-
Logging.log_error_message(
210-
:error,
211-
"RealtimeDisabledForTenant",
212-
"Realtime disabled for this tenant"
213-
)
184+
Logging.log_error(socket, "RealtimeDisabledForTenant", "Realtime disabled for this tenant")
214185

215186
{:error, :signature_error} ->
216-
Logging.log_error_message(:error, "JwtSignatureError", "Failed to validate JWT signature")
187+
Logging.log_error(socket, "JwtSignatureError", "Failed to validate JWT signature")
217188

218189
{:error, :shutdown_in_progress} ->
219-
Logging.log_error_message(
220-
:error,
221-
"RealtimeRestarting",
222-
"Realtime is restarting, please standby"
223-
)
190+
Logging.log_error(socket, "RealtimeRestarting", "Realtime is restarting, please standby")
224191

225192
{:error, error} ->
226-
Logging.log_error_message(:error, "UnknownErrorOnChannel", error)
193+
Logging.log_error(socket, "UnknownErrorOnChannel", error)
227194
{:error, %{reason: "Unknown Error on Channel"}}
228195
end
229196
end
@@ -276,14 +243,14 @@ defmodule RealtimeWeb.RealtimeChannel do
276243
log_warning("TooManyPresenceMessages", message)
277244
end
278245

279-
socket = Logging.maybe_log_handle_info(socket, msg)
246+
Logging.maybe_log_info(socket, msg)
280247
push(socket, "presence_diff", payload)
281248
{:noreply, socket}
282249
end
283250

284251
def handle_info(%{event: type, payload: payload} = msg, socket) do
285252
count(socket)
286-
socket = Logging.maybe_log_handle_info(socket, msg)
253+
Logging.maybe_log_info(socket, msg)
287254
push(socket, type, payload)
288255
{:noreply, socket}
289256
end
@@ -503,7 +470,7 @@ defmodule RealtimeWeb.RealtimeChannel do
503470
wait
504471
end
505472

506-
def limit_joins(%{tenant: tenant, limits: limits}) do
473+
def limit_joins(%{assigns: %{tenant: tenant, limits: limits}} = socket) do
507474
rate_args = Tenants.joins_per_second_rate(tenant, limits.max_joins_per_second)
508475

509476
RateCounter.new(rate_args)
@@ -517,7 +484,7 @@ defmodule RealtimeWeb.RealtimeChannel do
517484
{:error, :too_many_joins}
518485

519486
error ->
520-
Logging.log_error_message(:error, "UnknownErrorOnCounter", error)
487+
Logging.log_error(socket, "UnknownErrorOnCounter", error)
521488
{:error, error}
522489
end
523490
end
@@ -533,7 +500,7 @@ defmodule RealtimeWeb.RealtimeChannel do
533500
end
534501
end
535502

536-
defp limit_max_users(%{limits: %{max_concurrent_users: max_conn_users}, tenant: tenant}) do
503+
defp limit_max_users(%{assigns: %{limits: %{max_concurrent_users: max_conn_users}, tenant: tenant}}) do
537504
conns = Realtime.UsersCounter.tenant_users(tenant)
538505

539506
if conns < max_conn_users,

0 commit comments

Comments
 (0)