20
20
21
21
namespace MongoDB \Bundle \DataCollector ;
22
22
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 ;
27
25
use Symfony \Component \HttpFoundation \Request ;
28
26
use Symfony \Component \HttpFoundation \Response ;
29
27
use 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 ;
30
41
31
42
/** @internal */
32
- final class MongoDBDataCollector extends DataCollector
43
+ final class MongoDBDataCollector extends DataCollector implements LateDataCollectorInterface
33
44
{
34
45
/**
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}>>
36
49
*/
37
- private array $ clients = [];
50
+ private array $ requests = [];
38
51
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
+ ) {
45
56
}
46
57
47
- public function collect ( Request $ request , Response $ response , ? \ Throwable $ exception = null ): void
58
+ public function collectCommandEvent ( string $ clientName , string $ requestId , array $ data ): void
48
59
{
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 ;
98
64
}
99
65
}
100
66
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
+
101
87
public function getRequestCount (): int
102
88
{
103
- return array_sum ( array_column ( $ this ->data ['clients ' ], ' requestCount ')) ;
89
+ return $ this ->data ['requestCount ' ] ;
104
90
}
105
91
106
92
public function getErrorCount (): int
107
93
{
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 ' ];
109
100
}
110
101
111
- public function getTime (): float
102
+ public function getRequests (): array
112
103
{
113
- return array_sum ( array_column ( $ this ->data ['clients ' ], ' totalTime ' )) ;
104
+ return $ this ->data ['requests ' ] ;
114
105
}
115
106
116
107
public function getClients (): array
@@ -125,10 +116,7 @@ public function getName(): string
125
116
126
117
public function reset (): void
127
118
{
119
+ $ this ->requests = [];
128
120
$ this ->data = [];
129
-
130
- foreach ($ this ->clients as ['subscriber ' => $ subscriber ]) {
131
- $ subscriber ->reset ();
132
- }
133
121
}
134
122
}
0 commit comments