@@ -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