@@ -748,12 +748,13 @@ defmodule Ecto.Adapters.SQL do
748
748
end
749
749
750
750
log = Keyword . get ( config , :log , :debug )
751
+ stacktrace = Keyword . get ( config , :stacktrace , nil )
751
752
telemetry_prefix = Keyword . fetch! ( config , :telemetry_prefix )
752
753
telemetry = { config [ :repo ] , log , telemetry_prefix ++ [ :query ] }
753
754
754
755
config = adapter_config ( config )
755
756
opts = Keyword . take ( config , @ pool_opts )
756
- meta = % { telemetry: telemetry , sql: connection , opts: opts }
757
+ meta = % { telemetry: telemetry , sql: connection , stacktrace: stacktrace , opts: opts }
757
758
{ :ok , connection . child_spec ( config ) , meta }
758
759
end
759
760
@@ -1087,7 +1088,8 @@ defmodule Ecto.Adapters.SQL do
1087
1088
params: params ,
1088
1089
query: query_string ,
1089
1090
source: source ,
1090
- options: Keyword . get ( opts , :telemetry_options , [ ] )
1091
+ options: Keyword . get ( opts , :telemetry_options , [ ] ) ,
1092
+ stacktrace: Keyword . get ( opts , :stacktrace )
1091
1093
}
1092
1094
1093
1095
if event_name = Keyword . get ( opts , :telemetry_event , event_name ) do
@@ -1148,10 +1150,44 @@ defmodule Ecto.Adapters.SQL do
1148
1150
?\n ,
1149
1151
query ,
1150
1152
?\s ,
1151
- inspect ( params , charlists: false )
1153
+ inspect ( params , charlists: false ) ,
1154
+ log_stacktrace ( metadata . stacktrace )
1152
1155
]
1153
1156
end
1154
1157
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
+
1155
1191
defp log_ok_error ( { :ok , _res } ) , do: "OK"
1156
1192
defp log_ok_error ( { :error , _err } ) , do: "ERROR"
1157
1193
0 commit comments