@@ -658,10 +658,11 @@ defmodule Ecto.Adapters.SQL do
658658 sql_call ( adapter_meta , :query_many , [ sql ] , params , opts )
659659 end
660660
661+
661662 defp sql_call ( adapter_meta , callback , args , params , opts ) do
662- % { pid: pool , telemetry: telemetry , sql: sql , opts: default_opts } = adapter_meta
663+ % { pid: pool , telemetry: telemetry , sql: sql , opts: default_opts , stacktrace: stacktrace_config } = adapter_meta
663664 conn = get_conn_or_pool ( pool , adapter_meta )
664- opts = with_log ( telemetry , params , opts ++ default_opts )
665+ opts = with_log ( telemetry , stacktrace_config , params , opts ++ default_opts )
665666 args = args ++ [ params , opts ]
666667 apply ( sql , callback , [ conn | args ] )
667668 end
@@ -872,7 +873,7 @@ defmodule Ecto.Adapters.SQL do
872873 """
873874 end
874875
875- stacktrace = Keyword . get ( config , :stacktrace , nil )
876+ stacktrace = Keyword . get ( config , :stacktrace )
876877 telemetry_prefix = Keyword . fetch! ( config , :telemetry_prefix )
877878 telemetry = { config [ :repo ] , log , telemetry_prefix ++ [ :query ] }
878879
@@ -1097,8 +1098,8 @@ defmodule Ecto.Adapters.SQL do
10971098
10981099 @ doc false
10991100 def reduce ( adapter_meta , statement , params , opts , acc , fun ) do
1100- % { pid: pool , telemetry: telemetry , sql: sql , opts: default_opts } = adapter_meta
1101- opts = with_log ( telemetry , params , opts ++ default_opts )
1101+ % { pid: pool , telemetry: telemetry , sql: sql , stacktrace: stacktrace_config , opts: default_opts } = adapter_meta
1102+ opts = with_log ( telemetry , stacktrace_config , params , opts ++ default_opts )
11021103
11031104 case get_conn ( pool ) do
11041105 % DBConnection { conn_mode: :transaction } = conn ->
@@ -1113,8 +1114,8 @@ defmodule Ecto.Adapters.SQL do
11131114
11141115 @ doc false
11151116 def into ( adapter_meta , statement , params , opts ) do
1116- % { pid: pool , telemetry: telemetry , sql: sql , opts: default_opts } = adapter_meta
1117- opts = with_log ( telemetry , params , opts ++ default_opts )
1117+ % { pid: pool , telemetry: telemetry , sql: sql , opts: default_opts , stacktrace: stacktrace_config } = adapter_meta
1118+ opts = with_log ( telemetry , stacktrace_config , params , opts ++ default_opts )
11181119
11191120 case get_conn ( pool ) do
11201121 % DBConnection { conn_mode: :transaction } = conn ->
@@ -1231,11 +1232,11 @@ defmodule Ecto.Adapters.SQL do
12311232
12321233 ## Log
12331234
1234- defp with_log ( telemetry , params , opts ) do
1235- [ log: & log ( telemetry , params , & 1 , opts ) ] ++ opts
1235+ defp with_log ( telemetry , stacktrace_config , params , opts ) do
1236+ [ log: & log ( telemetry , stacktrace_config , params , & 1 , opts ) ] ++ opts
12361237 end
12371238
1238- defp log ( { repo , log , event_name } , params , entry , opts ) do
1239+ defp log ( { repo , log , event_name } , stacktrace_config , params , entry , opts ) do
12391240 % {
12401241 connection_time: query_time ,
12411242 decode_time: decode_time ,
@@ -1286,21 +1287,24 @@ defmodule Ecto.Adapters.SQL do
12861287 { true , level } ->
12871288 Logger . log (
12881289 level ,
1289- fn -> log_iodata ( measurements , repo , source , query , log_params , result , stacktrace ) end ,
1290+ fn -> log_iodata ( measurements , repo , source , query , log_params , result , stacktrace , stacktrace_size ( stacktrace_config ) ) end ,
12901291 ansi_color: sql_color ( query )
12911292 )
12921293
12931294 { opts_level , args_level } ->
12941295 Logger . log (
12951296 opts_level || args_level ,
1296- fn -> log_iodata ( measurements , repo , source , query , log_params , result , stacktrace ) end ,
1297+ fn -> log_iodata ( measurements , repo , source , query , log_params , result , stacktrace , stacktrace_size ( stacktrace_config ) ) end ,
12971298 ansi_color: sql_color ( query )
12981299 )
12991300 end
13001301
13011302 :ok
13021303 end
13031304
1305+ defp stacktrace_size ( val ) when is_integer ( val ) , do: val
1306+ defp stacktrace_size ( _ ) , do: 1
1307+
13041308 defp log_measurements ( [ { _ , nil } | rest ] , total , acc ) ,
13051309 do: log_measurements ( rest , total , acc )
13061310
@@ -1310,7 +1314,7 @@ defmodule Ecto.Adapters.SQL do
13101314 defp log_measurements ( [ ] , total , acc ) ,
13111315 do: Map . new ( [ total_time: total ] ++ acc )
13121316
1313- defp log_iodata ( measurements , repo , source , query , params , result , stacktrace ) do
1317+ defp log_iodata ( measurements , repo , source , query , params , result , stacktrace , stacktrace_size ) do
13141318 [
13151319 "QUERY" ,
13161320 ?\s ,
@@ -1324,7 +1328,7 @@ defmodule Ecto.Adapters.SQL do
13241328 query ,
13251329 ?\s ,
13261330 inspect ( params , charlists: false ) ,
1327- log_stacktrace ( stacktrace , repo )
1331+ log_stacktrace ( stacktrace , repo , stacktrace_size )
13281332 ]
13291333 end
13301334
@@ -1351,19 +1355,19 @@ defmodule Ecto.Adapters.SQL do
13511355 end
13521356 end
13531357
1354- defp log_stacktrace ( stacktrace , repo ) do
1355- with [ _ | _ ] <- stacktrace ,
1356- { module , function , arity , info } <- last_non_ecto ( Enum . reverse ( stacktrace ) , repo , nil ) do
1358+ defp log_stacktrace ( [ ] , _ , _ ) , do: [ ]
1359+
1360+ defp log_stacktrace ( stacktrace , repo , size ) do
1361+ for { { module , function , arity , info } , idx } <- Enum . with_index ( last_non_ecto ( Enum . reverse ( stacktrace ) , repo , size ) ) do
13571362 [
13581363 ?\n ,
13591364 IO.ANSI . light_black ( ) ,
1365+ List . duplicate ( ?\s , 2 * idx ) ,
13601366 "↳ " ,
13611367 Exception . format_mfa ( module , function , arity ) ,
13621368 log_stacktrace_info ( info ) ,
13631369 IO.ANSI . reset ( )
13641370 ]
1365- else
1366- _ -> [ ]
13671371 end
13681372 end
13691373
@@ -1377,21 +1381,21 @@ defmodule Ecto.Adapters.SQL do
13771381
13781382 @ repo_modules [ Ecto.Repo.Queryable , Ecto.Repo.Schema , Ecto.Repo.Transaction ]
13791383
1380- defp last_non_ecto ( [ { mod , _ , _ , _ } | _stacktrace ] , repo , last )
1381- when mod == repo or mod in @ repo_modules ,
1382- do: last
1383-
1384- defp last_non_ecto ( [ last | stacktrace ] , repo , _last ) ,
1385- do: last_non_ecto ( stacktrace , repo , last )
1384+ defp last_non_ecto ( stacktrace , repo , size ) do
1385+ stacktrace
1386+ |> last_non_ecto_entries ( repo , [ ] )
1387+ |> Enum . take ( size )
1388+ end
13861389
1387- defp last_non_ecto ( [ ] , _repo , last ) ,
1388- do: last
1390+ defp last_non_ecto_entries ( [ { mod , _ , _ , _ } | _ ] , repo , acc ) when mod == repo or mod in @ repo_modules , do: acc
1391+ defp last_non_ecto_entries ( [ entry | rest ] , repo , acc ) , do: last_non_ecto_entries ( rest , repo , [ entry | acc ] )
1392+ defp last_non_ecto_entries ( [ ] , _ , acc ) , do: acc
13891393
13901394 ## Connection helpers
13911395
13921396 defp checkout_or_transaction ( fun , adapter_meta , opts , callback ) do
1393- % { pid: pool , telemetry: telemetry , opts: default_opts } = adapter_meta
1394- opts = with_log ( telemetry , [ ] , opts ++ default_opts )
1397+ % { pid: pool , telemetry: telemetry , opts: default_opts , stacktrace: stacktrace_config } = adapter_meta
1398+ opts = with_log ( telemetry , stacktrace_config , [ ] , opts ++ default_opts )
13951399
13961400 callback = fn conn ->
13971401 previous_conn = put_conn ( pool , conn )
0 commit comments