Skip to content

Commit 29bdfa1

Browse files
authored
Optionally log last known call, publish stacktrace in telemetry (#366)
1 parent f87480a commit 29bdfa1

File tree

1 file changed

+39
-3
lines changed

1 file changed

+39
-3
lines changed

lib/ecto/adapters/sql.ex

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -748,12 +748,13 @@ defmodule Ecto.Adapters.SQL do
748748
end
749749

750750
log = Keyword.get(config, :log, :debug)
751+
stacktrace = Keyword.get(config, :stacktrace, nil)
751752
telemetry_prefix = Keyword.fetch!(config, :telemetry_prefix)
752753
telemetry = {config[:repo], log, telemetry_prefix ++ [:query]}
753754

754755
config = adapter_config(config)
755756
opts = Keyword.take(config, @pool_opts)
756-
meta = %{telemetry: telemetry, sql: connection, opts: opts}
757+
meta = %{telemetry: telemetry, sql: connection, stacktrace: stacktrace, opts: opts}
757758
{:ok, connection.child_spec(config), meta}
758759
end
759760

@@ -1087,7 +1088,8 @@ defmodule Ecto.Adapters.SQL do
10871088
params: params,
10881089
query: query_string,
10891090
source: source,
1090-
options: Keyword.get(opts, :telemetry_options, [])
1091+
options: Keyword.get(opts, :telemetry_options, []),
1092+
stacktrace: Keyword.get(opts, :stacktrace)
10911093
}
10921094

10931095
if event_name = Keyword.get(opts, :telemetry_event, event_name) do
@@ -1148,10 +1150,44 @@ defmodule Ecto.Adapters.SQL do
11481150
?\n,
11491151
query,
11501152
?\s,
1151-
inspect(params, charlists: false)
1153+
inspect(params, charlists: false),
1154+
log_stacktrace(metadata.stacktrace)
11521155
]
11531156
end
11541157

1158+
defp log_stacktrace(stacktrace) do
1159+
with [_ | _] <- stacktrace,
1160+
{module, function, arity, metadata} <- first_non_ecto(stacktrace, nil) do
1161+
[
1162+
?\n,
1163+
"↳ ",
1164+
Exception.format_mfa(module, function, arity),
1165+
", at: ",
1166+
inspect(metadata)
1167+
]
1168+
else
1169+
_ -> []
1170+
end
1171+
end
1172+
1173+
defp first_non_ecto([last_item], first_non_ecto) do
1174+
if is_ecto?(last_item), do: nil, else: first_non_ecto
1175+
end
1176+
1177+
defp first_non_ecto([head | tail], first_non_ecto) do
1178+
if is_ecto?(head) do
1179+
first_non_ecto(tail, nil)
1180+
else
1181+
first_non_ecto(tail, first_non_ecto || head)
1182+
end
1183+
end
1184+
1185+
defp is_ecto?({module, _f, _a, _m}) do
1186+
module
1187+
|> Atom.to_string()
1188+
|> String.starts_with?("Elixir.Ecto.")
1189+
end
1190+
11551191
defp log_ok_error({:ok, _res}), do: "OK"
11561192
defp log_ok_error({:error, _err}), do: "ERROR"
11571193

0 commit comments

Comments
 (0)