2
2
// for details. All rights reserved. Use of this source code is governed by a
3
3
// BSD-style license that can be found in the LICENSE file.
4
4
5
+ import 'dart:convert' ;
6
+
5
7
import 'package:analysis_server/lsp_protocol/protocol.dart' ;
6
8
import 'package:analysis_server/protocol/protocol.dart' ;
7
9
import 'package:analysis_server/src/analytics/analytics_manager.dart' ;
8
10
import 'package:analysis_server/src/analytics/percentile_calculator.dart' ;
11
+ import 'package:analysis_server/src/plugin/plugin_manager.dart' ;
9
12
import 'package:telemetry/telemetry.dart' ;
10
13
11
14
/// An implementation of [AnalyticsManager] that's appropriate to use when
@@ -18,6 +21,8 @@ class GoogleAnalyticsManager implements AnalyticsManager {
18
21
/// been invoked.
19
22
_SessionData ? _sessionData;
20
23
24
+ final _PluginData _pluginData = _PluginData ();
25
+
21
26
/// A map from the id of a request to data about the request.
22
27
final Map <String , _ActiveRequestData > _activeRequests = {};
23
28
@@ -29,6 +34,11 @@ class GoogleAnalyticsManager implements AnalyticsManager {
29
34
/// service.
30
35
GoogleAnalyticsManager (this .analytics);
31
36
37
+ @override
38
+ void changedPlugins (PluginManager pluginManager) {
39
+ _pluginData.recordPlugins (pluginManager);
40
+ }
41
+
32
42
@override
33
43
void sentResponse ({required Response response}) {
34
44
var sendTime = DateTime .now ();
@@ -59,10 +69,7 @@ class GoogleAnalyticsManager implements AnalyticsManager {
59
69
'clientId' : sessionData.clientId,
60
70
'sdkVersion' : sessionData.sdkVersion,
61
71
'duration' : duration.toString (),
62
- // TODO(brianwilkerson) Report a list of the names of the plugins that
63
- // were loaded, or possibly a map from plugin names to the number of
64
- // analysis roots in which the plugins were loaded.
65
- 'plugins' : '' ,
72
+ 'plugins' : _pluginData.usageCountData,
66
73
});
67
74
// Send response data.
68
75
for (var data in _completedRequests.values) {
@@ -148,6 +155,48 @@ class _ActiveRequestData {
148
155
_ActiveRequestData (this .requestName, this .clientRequestTime, this .startTime);
149
156
}
150
157
158
+ /// Data about the plugins associated with the context roots.
159
+ class _PluginData {
160
+ /// The number of times that plugin information has been recorded.
161
+ int recordCount = 0 ;
162
+
163
+ /// A table mapping the ids of running plugins to the number of context roots
164
+ /// associated with each of the plugins.
165
+ Map <String , PercentileCalculator > usageCounts = {};
166
+
167
+ /// Initialize a newly created holder of plugin data.
168
+ _PluginData ();
169
+
170
+ String get usageCountData {
171
+ return json.encode ({
172
+ 'recordCount' : recordCount,
173
+ 'rootCounts' : _encodeUsageCounts (),
174
+ });
175
+ }
176
+
177
+ /// Use the [pluginManager] to record data about the plugins that are
178
+ /// currently running.
179
+ void recordPlugins (PluginManager pluginManager) {
180
+ recordCount++ ;
181
+ var plugins = pluginManager.plugins;
182
+ for (var i = 0 ; i < plugins.length; i++ ) {
183
+ var info = plugins[i];
184
+ usageCounts
185
+ .putIfAbsent (info.pluginId, () => PercentileCalculator ())
186
+ .addValue (info.contextRoots.length);
187
+ }
188
+ }
189
+
190
+ /// Return an encoding of the [usageCounts] .
191
+ Map <String , String > _encodeUsageCounts () {
192
+ var encoded = < String , String > {};
193
+ for (var entry in usageCounts.entries) {
194
+ encoded[entry.key] = entry.value.toAnalyticsString ();
195
+ }
196
+ return encoded;
197
+ }
198
+ }
199
+
151
200
/// Data about the requests that have been responded to that have the same name.
152
201
class _RequestData {
153
202
/// The name of the requests.
0 commit comments