@@ -799,7 +799,7 @@ defmodule Mongo do
799
799
with { :ok , conn , new_cmd } <- Session . bind_session ( session , cmd ) ,
800
800
{ :ok , _cmd , response } <- DBConnection . execute ( conn , % Query { action: :command } , [ new_cmd ] , defaults ( opts ) ) ,
801
801
:ok <- Session . update_session ( session , response , opts ) ,
802
- { :ok , { _flags , doc } } <- check_for_error ( response ) do
802
+ { :ok , { _flags , doc } } <- check_for_error ( response , cmd , opts ) do
803
803
{ :ok , doc }
804
804
else
805
805
{ :error , error } ->
@@ -812,20 +812,20 @@ defmodule Mongo do
812
812
{ :ok , BSON . document ( ) | nil } | { :error , Mongo.Error . t ( ) }
813
813
def exec_command ( conn , cmd , opts ) do
814
814
with { :ok , _cmd , response } <- DBConnection . execute ( conn , % Query { action: :command } , [ cmd ] , defaults ( opts ) ) do
815
- check_for_error ( response )
815
+ check_for_error ( response , cmd , opts )
816
816
end
817
817
end
818
818
819
819
def exec_more_to_come ( conn , opts ) do
820
820
with { :ok , _cmd , response } <- DBConnection . execute ( conn , % Query { action: :command } , [ :more_to_come ] , defaults ( opts ) ) do
821
- check_for_error ( response )
821
+ check_for_error ( response , [ :more_to_come ] , opts )
822
822
end
823
823
end
824
824
825
825
##
826
826
# Checks for an error and broadcast the event.
827
827
##
828
- defp check_for_error ( { % { "ok" => ok } = response , % { request_id: request_id , operation_id: operation_id , connection_id: connection_id } = event , flags , duration } ) when ok == 1 do
828
+ defp check_for_error ( { % { "ok" => ok } = response , % { request_id: request_id , operation_id: operation_id , connection_id: connection_id } = event , flags , duration } , cmd , opts ) when ok == 1 do
829
829
Events . notify (
830
830
% CommandSucceededEvent {
831
831
reply: response ,
@@ -838,10 +838,12 @@ defmodule Mongo do
838
838
:commands
839
839
)
840
840
841
+ do_log ( cmd , duration , opts )
842
+
841
843
{ :ok , { flags , response } }
842
844
end
843
845
844
- defp check_for_error ( { % { "ok" => ok } = response , event , flags , duration } ) when ok == 1 do
846
+ defp check_for_error ( { % { "ok" => ok } = response , event , flags , duration } , cmd , opts ) when ok == 1 do
845
847
Events . notify (
846
848
% CommandSucceededEvent {
847
849
reply: response ,
@@ -851,10 +853,12 @@ defmodule Mongo do
851
853
:commands
852
854
)
853
855
856
+ do_log ( cmd , duration , opts )
857
+
854
858
{ :ok , { flags , response } }
855
859
end
856
860
857
- defp check_for_error ( { doc , % { request_id: request_id , operation_id: operation_id , connection_id: connection_id } = event , _flags , duration } ) do
861
+ defp check_for_error ( { doc , % { request_id: request_id , operation_id: operation_id , connection_id: connection_id } = event , _flags , duration } , cmd , opts ) do
858
862
error = Mongo.Error . exception ( doc )
859
863
860
864
Events . notify (
@@ -869,10 +873,12 @@ defmodule Mongo do
869
873
:commands
870
874
)
871
875
876
+ do_log ( cmd , duration , opts )
877
+
872
878
{ :error , error }
873
879
end
874
880
875
- defp check_for_error ( { doc , event , _flags , duration } ) do
881
+ defp check_for_error ( { doc , event , _flags , duration } , cmd , opts ) do
876
882
error = Mongo.Error . exception ( doc )
877
883
878
884
Events . notify (
@@ -884,6 +890,8 @@ defmodule Mongo do
884
890
:commands
885
891
)
886
892
893
+ do_log ( cmd , duration , opts )
894
+
887
895
{ :error , error }
888
896
end
889
897
@@ -1521,4 +1529,103 @@ defmodule Mongo do
1521
1529
defp defaults ( opts ) do
1522
1530
Keyword . put_new ( opts , :timeout , @ timeout )
1523
1531
end
1532
+
1533
+ ## support for logging like Ecto
1534
+ defp do_log ( [ :more_to_come ] , _duration , _opts ) do
1535
+ :ok
1536
+ end
1537
+
1538
+ defp do_log ( cmd , duration , opts ) do
1539
+ case Keyword . has_key? ( cmd , :isMaster ) || Keyword . has_key? ( cmd , :more_to_come ) do
1540
+ true ->
1541
+ :ok
1542
+
1543
+ false ->
1544
+ command =
1545
+ cmd
1546
+ |> Keyword . keys ( )
1547
+ |> Enum . at ( 0 )
1548
+
1549
+ { _ , params } = Keyword . pop_first ( cmd , command )
1550
+ collection = Keyword . get ( cmd , command )
1551
+ do_log ( command , collection , params , duration , opts )
1552
+ end
1553
+ end
1554
+
1555
+ defp do_log ( command , collection , params , duration , opts ) do
1556
+ metadata = % {
1557
+ type: :mongodb_driver ,
1558
+ command: command ,
1559
+ params: params ,
1560
+ collection: collection ,
1561
+ options: Keyword . get ( opts , :telemetry_options , [ ] )
1562
+ }
1563
+
1564
+ :telemetry . execute ( [ :mongodb_driver , :execution ] , % { duration: duration } , metadata )
1565
+
1566
+ log = Application . get_env ( :mongodb_driver , :log , false )
1567
+
1568
+ case Keyword . get ( opts , :log , log ) do
1569
+ true ->
1570
+ Logger . log ( :info , fn -> log_iodata ( command , collection , params , duration ) end , ansi_color: command_color ( command ) )
1571
+
1572
+ false ->
1573
+ :ok
1574
+
1575
+ level ->
1576
+ Logger . log ( level , fn -> log_iodata ( command , collection , params , duration ) end , ansi_color: command_color ( command ) )
1577
+ end
1578
+ end
1579
+
1580
+ defp log_iodata ( command , collection , params , duration ) do
1581
+ us = duration
1582
+ ms = div ( us , 100 ) / 10
1583
+
1584
+ [
1585
+ "CMD" ,
1586
+ ?\s ,
1587
+ Atom . to_string ( command ) ,
1588
+ ?\s ,
1589
+ to_iodata ( collection ) ,
1590
+ ?\s ,
1591
+ to_iodata ( params ) ,
1592
+ [ ?\s , "db" , ?= , :io_lib_format . fwrite_g ( ms ) , ?m , ?s ]
1593
+ ]
1594
+ end
1595
+
1596
+ defp to_iodata ( doc ) do
1597
+ opts = Inspect.Opts . new ( [ ] )
1598
+
1599
+ doc =
1600
+ doc
1601
+ |> Inspect.Algebra . to_doc ( opts )
1602
+ |> Inspect.Algebra . group ( )
1603
+
1604
+ Inspect.Algebra . format ( doc , opts . width )
1605
+ end
1606
+
1607
+ defp command_color ( :getMore ) , do: :cyan
1608
+ defp command_color ( :ping ) , do: :cyan
1609
+ defp command_color ( :aggregate ) , do: :cyan
1610
+ defp command_color ( :find ) , do: :cyan
1611
+ defp command_color ( :count ) , do: :cyan
1612
+ defp command_color ( :distinct ) , do: :cyan
1613
+ defp command_color ( :listIndexes ) , do: :cyan
1614
+ defp command_color ( :listCollections ) , do: :cyan
1615
+ defp command_color ( :insert ) , do: :green
1616
+ defp command_color ( :delete ) , do: :red
1617
+ defp command_color ( :dropIndexes ) , do: :red
1618
+ defp command_color ( :drop ) , do: :red
1619
+ defp command_color ( :dropDatabase ) , do: :red
1620
+ defp command_color ( :dropUser ) , do: :red
1621
+ defp command_color ( :abortTransaction ) , do: :red
1622
+ defp command_color ( :update ) , do: :yellow
1623
+ defp command_color ( :findAndModify ) , do: :yellow
1624
+ defp command_color ( :createUser ) , do: :magenta
1625
+ defp command_color ( :createIndexes ) , do: :magenta
1626
+ defp command_color ( :create ) , do: :magenta
1627
+ defp command_color ( :killCursors ) , do: :magenta
1628
+ defp command_color ( :commitTransaction ) , do: :magenta
1629
+ defp command_color ( :configureFailPoint ) , do: :blue
1630
+ defp command_color ( _ ) , do: nil
1524
1631
end
0 commit comments