2020
2121namespace MongoDB \Bundle \DataCollector ;
2222
23- use MongoDB \Bundle \Client ;
24- use MongoDB \Driver \Monitoring \CommandFailedEvent ;
25- use MongoDB \Driver \Monitoring \CommandStartedEvent ;
26- use MongoDB \Driver \Monitoring \CommandSucceededEvent ;
23+ use MongoDB \Client ;
24+ use MongoDB \Driver \Command ;
2725use Symfony \Component \HttpFoundation \Request ;
2826use Symfony \Component \HttpFoundation \Response ;
2927use Symfony \Component \HttpKernel \DataCollector \DataCollector ;
28+ use Symfony \Component \HttpKernel \DataCollector \LateDataCollectorInterface ;
29+ use Throwable ;
30+
31+ use function array_column ;
32+ use function array_diff_key ;
33+ use function array_map ;
34+ use function array_sum ;
35+ use function count ;
36+ use function debug_backtrace ;
37+ use function dump ;
38+ use function iterator_to_array ;
39+
40+ use const DEBUG_BACKTRACE_IGNORE_ARGS ;
3041
3142/** @internal */
32- final class MongoDBDataCollector extends DataCollector
43+ final class MongoDBDataCollector extends DataCollector implements LateDataCollectorInterface
3344{
3445 /**
35- * @var list<array{client:Client, subscriber:DriverEventSubscriber}>
46+ * The list of request by client name is built with driver event data.
47+ *
48+ * @var array<string, array<string, array{clientName:string,databaseName:string,commandName:string,command:array,operationId:int,serviceId:int,durationMicros?:int,error?:string}>>
3649 */
37- private array $ clients = [];
50+ private array $ requests = [];
3851
39- public function addClient (string $ name , Client $ client , DriverEventSubscriber $ subscriber ): void
40- {
41- $ this ->clients [$ name ] = [
42- 'client ' => $ client ,
43- 'subscriber ' => $ subscriber ,
44- ];
52+ public function __construct (
53+ /** @var iterable<string, Client> */
54+ private readonly iterable $ clients = [],
55+ ) {
4556 }
4657
47- public function collect ( Request $ request , Response $ response , ? \ Throwable $ exception = null ): void
58+ public function collectCommandEvent ( string $ clientName , string $ requestId , array $ data ): void
4859 {
49- foreach ($ this ->clients as $ name => ['client ' => $ client , 'subscriber ' => $ subscriber ]) {
50- $ totalTime = 0 ;
51- $ requestCount = 0 ;
52- $ errorCount = 0 ;
53- $ requests = [];
54-
55- foreach ($ subscriber ->getEvents () as $ event ) {
56- $ requestId = $ event ->getRequestId ();
57-
58- if ($ event instanceof CommandStartedEvent) {
59- $ command = (array ) $ event ->getCommand ();
60- unset($ command ['lsid ' ], $ command ['$clusterTime ' ]);
61-
62- $ requests [$ requestId ] = [
63- 'client ' => $ name ,
64- 'startedAt ' => hrtime (true ),
65- 'commandName ' => $ event ->getCommandName (),
66- 'command ' => $ command ,
67- 'operationId ' => $ event ->getOperationId (),
68- 'database ' => $ event ->getDatabaseName (),
69- 'serviceId ' => $ event ->getServiceId (),
70- ];
71- ++$ requestCount ;
72- } elseif ($ event instanceof CommandSucceededEvent) {
73- $ requests [$ requestId ] += [
74- 'duration ' => $ event ->getDurationMicros (),
75- 'endedAt ' => hrtime (true ),
76- 'success ' => true ,
77- ];
78- $ totalTime += $ event ->getDurationMicros ();
79- } elseif ($ event instanceof CommandFailedEvent) {
80- $ requests [$ requestId ] += [
81- 'duration ' => $ event ->getDurationMicros (),
82- 'error ' => $ event ->getError (),
83- 'success ' => false ,
84- ];
85- $ totalTime += $ event ->getDurationMicros ();
86- ++$ errorCount ;
87- }
88- }
89-
90- $ this ->data ['clients ' ][$ name ] = [
91- 'name ' => $ name ,
92- 'uri ' => (string ) $ client ,
93- 'totalTime ' => $ totalTime ,
94- 'requestCount ' => $ requestCount ,
95- 'errorCount ' => $ errorCount ,
96- 'requests ' => $ requests ,
97- ];
60+ if (isset ($ this ->requests [$ clientName ][$ requestId ])) {
61+ $ this ->requests [$ clientName ][$ requestId ] += $ data ;
62+ } else {
63+ $ this ->requests [$ clientName ][$ requestId ] = $ data ;
9864 }
9965 }
10066
67+ public function collect (Request $ request , Response $ response , ?Throwable $ exception = null ): void
68+ {
69+ }
70+
71+ public function lateCollect (): void
72+ {
73+ $ this ->data = [
74+ 'clients ' => array_map (static fn (Client $ client ) => [
75+ 'serverBuildInfo ' => $ client ->getManager ()->executeCommand ('admin ' , new Command (['buildInfo ' => 1 ]))->toArray ()[0 ],
76+ 'clientInfo ' => array_diff_key ($ client ->__debugInfo (), ['manager ' => 1 ]),
77+ ], iterator_to_array ($ this ->clients )),
78+ 'requests ' => $ this ->requests ,
79+ 'requestCount ' => array_sum (array_map (count (...), $ this ->requests )),
80+ 'errorCount ' => array_sum (array_map (static fn (array $ requests ) => count (array_column ($ requests , 'error ' )), $ this ->requests )),
81+ 'durationMicros ' => array_sum (array_map (static fn (array $ requests ) => array_sum (array_column ($ requests , 'durationMicros ' )), $ this ->requests )),
82+ ];
83+
84+ dump ($ this ->data , array_column (debug_backtrace (DEBUG_BACKTRACE_IGNORE_ARGS ), 'class ' ));
85+ }
86+
10187 public function getRequestCount (): int
10288 {
103- return array_sum ( array_column ( $ this ->data ['clients ' ], ' requestCount ')) ;
89+ return $ this ->data ['requestCount ' ] ;
10490 }
10591
10692 public function getErrorCount (): int
10793 {
108- return array_sum (array_column ($ this ->data ['clients ' ], 'errorCount ' ));
94+ return $ this ->data ['errorCount ' ];
95+ }
96+
97+ public function getTime (): int
98+ {
99+ return $ this ->data ['durationMicros ' ];
109100 }
110101
111- public function getTime (): float
102+ public function getRequests (): array
112103 {
113- return array_sum ( array_column ( $ this ->data ['clients ' ], ' totalTime ' )) ;
104+ return $ this ->data ['requests ' ] ;
114105 }
115106
116107 public function getClients (): array
@@ -125,10 +116,7 @@ public function getName(): string
125116
126117 public function reset (): void
127118 {
119+ $ this ->requests = [];
128120 $ this ->data = [];
129-
130- foreach ($ this ->clients as ['subscriber ' => $ subscriber ]) {
131- $ subscriber ->reset ();
132- }
133121 }
134122}
0 commit comments