Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(531)

Side by Side Diff: pkg/analysis_server/lib/src/server/driver.dart

Issue 2963323002: Add analytics to analyzer-cli and analysis server. (Closed)
Patch Set: Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 import 'dart:async'; 5 import 'dart:async';
6 import 'dart:io'; 6 import 'dart:io';
7 import 'dart:math'; 7 import 'dart:math';
8 8
9 import 'package:analysis_server/src/analysis_server.dart'; 9 import 'package:analysis_server/src/analysis_server.dart';
10 import 'package:analysis_server/src/plugin/server_plugin.dart'; 10 import 'package:analysis_server/src/plugin/server_plugin.dart';
11 import 'package:analysis_server/src/provisional/completion/dart/completion_plugi n.dart'; 11 import 'package:analysis_server/src/provisional/completion/dart/completion_plugi n.dart';
12 import 'package:analysis_server/src/server/diagnostic_server.dart'; 12 import 'package:analysis_server/src/server/diagnostic_server.dart';
13 import 'package:analysis_server/src/server/http_server.dart'; 13 import 'package:analysis_server/src/server/http_server.dart';
14 import 'package:analysis_server/src/server/stdio_server.dart'; 14 import 'package:analysis_server/src/server/stdio_server.dart';
15 import 'package:analysis_server/src/socket_server.dart'; 15 import 'package:analysis_server/src/socket_server.dart';
16 import 'package:analysis_server/starter.dart'; 16 import 'package:analysis_server/starter.dart';
17 import 'package:analyzer/file_system/physical_file_system.dart'; 17 import 'package:analyzer/file_system/physical_file_system.dart';
18 import 'package:analyzer/instrumentation/file_instrumentation.dart'; 18 import 'package:analyzer/instrumentation/file_instrumentation.dart';
19 import 'package:analyzer/instrumentation/instrumentation.dart'; 19 import 'package:analyzer/instrumentation/instrumentation.dart';
20 import 'package:analyzer/plugin/resolver_provider.dart'; 20 import 'package:analyzer/plugin/resolver_provider.dart';
21 import 'package:analyzer/src/dart/sdk/sdk.dart'; 21 import 'package:analyzer/src/dart/sdk/sdk.dart';
22 import 'package:analyzer/src/generated/engine.dart'; 22 import 'package:analyzer/src/generated/engine.dart';
23 import 'package:analyzer/src/generated/sdk.dart'; 23 import 'package:analyzer/src/generated/sdk.dart';
24 import 'package:args/args.dart'; 24 import 'package:args/args.dart';
25 import 'package:linter/src/rules.dart' as linter; 25 import 'package:linter/src/rules.dart' as linter;
26 import 'package:plugin/manager.dart'; 26 import 'package:plugin/manager.dart';
27 import 'package:plugin/plugin.dart'; 27 import 'package:plugin/plugin.dart';
28 import 'package:telemetry/crash_reporting.dart';
29 import 'package:telemetry/telemetry.dart' as telemetry;
28 30
29 /// Commandline argument parser. (Copied from analyzer/lib/options.dart) 31 /// Commandline argument parser. (Copied from analyzer/lib/options.dart)
30 /// TODO(pquitslund): replaces with a simple [ArgParser] instance 32 /// TODO(pquitslund): replaces with a simple [ArgParser] instance
31 /// when the args package supports ignoring unrecognized 33 /// when the args package supports ignoring unrecognized
32 /// options/flags (https://github.com/dart-lang/args/issues/9). 34 /// options/flags (https://github.com/dart-lang/args/issues/9).
33 class CommandLineParser { 35 class CommandLineParser {
34 final List<String> _knownFlags; 36 final List<String> _knownFlags;
35 final bool _alwaysIgnoreUnrecognized; 37 final bool _alwaysIgnoreUnrecognized;
36 final ArgParser _parser; 38 final ArgParser _parser;
37 39
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 // Only filter args if the ignore flag is specified, or if 120 // Only filter args if the ignore flag is specified, or if
119 // _alwaysIgnoreUnrecognized was set to true 121 // _alwaysIgnoreUnrecognized was set to true
120 if (_alwaysIgnoreUnrecognized || 122 if (_alwaysIgnoreUnrecognized ||
121 args.contains('--ignore-unrecognized-flags')) { 123 args.contains('--ignore-unrecognized-flags')) {
122 // Filter all unrecognized flags and options. 124 // Filter all unrecognized flags and options.
123 List<String> filtered = <String>[]; 125 List<String> filtered = <String>[];
124 for (int i = 0; i < args.length; ++i) { 126 for (int i = 0; i < args.length; ++i) {
125 String arg = args[i]; 127 String arg = args[i];
126 if (arg.startsWith('--') && arg.length > 2) { 128 if (arg.startsWith('--') && arg.length > 2) {
127 String option = arg.substring(2); 129 String option = arg.substring(2);
130 // remove any leading 'no-'
131 if (option.startsWith('no-')) {
132 option = option.substring(3);
133 }
128 // strip the last '=value' 134 // strip the last '=value'
129 int equalsOffset = option.lastIndexOf('='); 135 int equalsOffset = option.lastIndexOf('=');
130 if (equalsOffset != -1) { 136 if (equalsOffset != -1) {
131 option = option.substring(0, equalsOffset); 137 option = option.substring(0, equalsOffset);
132 } 138 }
133 // check the option 139 // check the option
134 if (!_knownFlags.contains(option)) { 140 if (!_knownFlags.contains(option)) {
135 //"eat" params by advancing to the next flag/option 141 //"eat" params by advancing to the next flag/option
136 i = _getNextFlagIndex(args, i); 142 i = _getNextFlagIndex(args, i);
137 } else { 143 } else {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 * The name of the option used to set the file read mode. 194 * The name of the option used to set the file read mode.
189 */ 195 */
190 static const String FILE_READ_MODE = "file-read-mode"; 196 static const String FILE_READ_MODE = "file-read-mode";
191 197
192 /** 198 /**
193 * The name of the option used to print usage information. 199 * The name of the option used to print usage information.
194 */ 200 */
195 static const String HELP_OPTION = "help"; 201 static const String HELP_OPTION = "help";
196 202
197 /** 203 /**
204 * The name of the flag used to configure reporting analytics.
205 */
206 static const String ANALYTICS_FLAG = "analytics";
207
208 /**
198 * The name of the option used to cause instrumentation to also be written to 209 * The name of the option used to cause instrumentation to also be written to
199 * a local file. 210 * a local file.
200 */ 211 */
201 static const String INSTRUMENTATION_LOG_FILE = "instrumentation-log-file"; 212 static const String INSTRUMENTATION_LOG_FILE = "instrumentation-log-file";
202 213
203 /** 214 /**
204 * The name of the option used to specify if [print] should print to the 215 * The name of the option used to specify if [print] should print to the
205 * console instead of being intercepted. 216 * console instead of being intercepted.
206 */ 217 */
207 static const String INTERNAL_PRINT_TO_CONSOLE = "internal-print-to-console"; 218 static const String INTERNAL_PRINT_TO_CONSOLE = "internal-print-to-console";
(...skipping 17 matching lines...) Expand all
225 236
226 /** 237 /**
227 * The option for specifying the http diagnostic port. 238 * The option for specifying the http diagnostic port.
228 * If specified, users can review server status and performance information 239 * If specified, users can review server status and performance information
229 * by opening a web browser on http://localhost:<port> 240 * by opening a web browser on http://localhost:<port>
230 */ 241 */
231 static const String PORT_OPTION = "port"; 242 static const String PORT_OPTION = "port";
232 243
233 /** 244 /**
234 * The path to the SDK. 245 * The path to the SDK.
235 * TODO(paulberry): get rid of this once the 'analysis.updateSdks' request is
236 * operational.
237 */ 246 */
238 static const String SDK_OPTION = "sdk"; 247 static const String SDK_OPTION = "sdk";
239 248
240 /** 249 /**
241 * The instrumentation server that is to be used by the analysis server. 250 * The instrumentation server that is to be used by the analysis server.
242 */ 251 */
243 InstrumentationServer instrumentationServer; 252 InstrumentationServer instrumentationServer;
244 253
245 /** 254 /**
246 * The file resolver provider used to override the way file URI's are 255 * The file resolver provider used to override the way file URI's are
(...skipping 30 matching lines...) Expand all
277 /** 286 /**
278 * Use the given command-line [arguments] to start this server. 287 * Use the given command-line [arguments] to start this server.
279 * 288 *
280 * At least temporarily returns AnalysisServer so that consumers of the 289 * At least temporarily returns AnalysisServer so that consumers of the
281 * starter API can then use the server, this is done as a stopgap for the 290 * starter API can then use the server, this is done as a stopgap for the
282 * angular plugin until the official plugin API is finished. 291 * angular plugin until the official plugin API is finished.
283 */ 292 */
284 AnalysisServer start(List<String> arguments) { 293 AnalysisServer start(List<String> arguments) {
285 CommandLineParser parser = _createArgParser(); 294 CommandLineParser parser = _createArgParser();
286 ArgResults results = parser.parse(arguments, <String, String>{}); 295 ArgResults results = parser.parse(arguments, <String, String>{});
287 if (results[HELP_OPTION]) { 296
288 _printUsage(parser.parser); 297 AnalysisServerOptions analysisServerOptions = new AnalysisServerOptions();
298 analysisServerOptions.useAnalysisHighlight2 =
299 results[USE_ANALYSIS_HIGHLIGHT2];
300 analysisServerOptions.fileReadMode = results[FILE_READ_MODE];
301 analysisServerOptions.newAnalysisDriverLog =
302 results[NEW_ANALYSIS_DRIVER_LOG];
303 analysisServerOptions.clientId = results[CLIENT_ID];
304 analysisServerOptions.clientVersion = results[CLIENT_VERSION];
305 analysisServerOptions.enableVerboseFlutterCompletions =
306 results[VERBOSE_FLUTTER_COMPLETIONS];
307
308 // TODO(devoncarew): Replace with the real analytics tool ID.
309 telemetry.Analytics analytics =
310 telemetry.createAnalyticsInstance('UA-001', 'analysis-server');
311 analysisServerOptions.analytics = analytics;
312
313 if (analysisServerOptions.clientId != null) {
314 // Record the client name as the application installer ID.
315 analytics.setSessionValue('aiid', analysisServerOptions.clientId);
316 }
317 if (analysisServerOptions.clientVersion != null) {
318 analytics.setSessionValue('cd1', analysisServerOptions.clientVersion);
319 }
320
321 // TODO(devoncarew): Replace with the real crash product ID.
322 analysisServerOptions.crashReportSender =
323 new CrashReportSender('Dart-analysis-server', analytics);
324
325 if (results.wasParsed(ANALYTICS_FLAG)) {
326 analytics.enabled = results[ANALYTICS_FLAG];
327 print(telemetry.createAnalyticsStatusMessage(analytics.enabled));
289 return null; 328 return null;
290 } 329 }
291 330
331 if (results[HELP_OPTION]) {
332 _printUsage(parser.parser, analytics, fromHelp: true);
333 return null;
334 }
335
292 int port; 336 int port;
293 bool serve_http = false; 337 bool serve_http = false;
294 if (results[PORT_OPTION] != null) { 338 if (results[PORT_OPTION] != null) {
295 try { 339 try {
296 port = int.parse(results[PORT_OPTION]); 340 port = int.parse(results[PORT_OPTION]);
297 serve_http = true; 341 serve_http = true;
298 } on FormatException { 342 } on FormatException {
299 print('Invalid port number: ${results[PORT_OPTION]}'); 343 print('Invalid port number: ${results[PORT_OPTION]}');
300 print(''); 344 print('');
301 _printUsage(parser.parser); 345 _printUsage(parser.parser, analytics);
302 exitCode = 1; 346 exitCode = 1;
303 return null; 347 return null;
304 } 348 }
305 } 349 }
306 350
307 AnalysisServerOptions analysisServerOptions = new AnalysisServerOptions();
308 analysisServerOptions.useAnalysisHighlight2 =
309 results[USE_ANALYSIS_HIGHLIGHT2];
310 analysisServerOptions.fileReadMode = results[FILE_READ_MODE];
311 analysisServerOptions.newAnalysisDriverLog =
312 results[NEW_ANALYSIS_DRIVER_LOG];
313
314 analysisServerOptions.clientId = results[CLIENT_ID];
315 analysisServerOptions.clientVersion = results[CLIENT_VERSION];
316
317 analysisServerOptions.enableVerboseFlutterCompletions =
318 results[VERBOSE_FLUTTER_COMPLETIONS];
319
320 // 351 //
321 // Process all of the plugins so that extensions are registered. 352 // Process all of the plugins so that extensions are registered.
322 // 353 //
323 ServerPlugin serverPlugin = new ServerPlugin(); 354 ServerPlugin serverPlugin = new ServerPlugin();
324 List<Plugin> plugins = <Plugin>[]; 355 List<Plugin> plugins = <Plugin>[];
325 plugins.addAll(AnalysisEngine.instance.requiredPlugins); 356 plugins.addAll(AnalysisEngine.instance.requiredPlugins);
326 plugins.add(serverPlugin); 357 plugins.add(serverPlugin);
327 plugins.add(dartCompletionPlugin); 358 plugins.add(dartCompletionPlugin);
328 plugins.addAll(_userDefinedPlugins); 359 plugins.addAll(_userDefinedPlugins);
329 ExtensionManager manager = new ExtensionManager(); 360 ExtensionManager manager = new ExtensionManager();
(...skipping 24 matching lines...) Expand all
354 new FileInstrumentationServer(logFilePath); 385 new FileInstrumentationServer(logFilePath);
355 instrumentationServer = instrumentationServer != null 386 instrumentationServer = instrumentationServer != null
356 ? new MulticastInstrumentationServer( 387 ? new MulticastInstrumentationServer(
357 [instrumentationServer, fileBasedServer]) 388 [instrumentationServer, fileBasedServer])
358 : fileBasedServer; 389 : fileBasedServer;
359 } 390 }
360 InstrumentationService instrumentationService = 391 InstrumentationService instrumentationService =
361 new InstrumentationService(instrumentationServer); 392 new InstrumentationService(instrumentationServer);
362 instrumentationService.logVersion( 393 instrumentationService.logVersion(
363 _readUuid(instrumentationService), 394 _readUuid(instrumentationService),
364 results[CLIENT_ID], 395 analysisServerOptions.clientId,
365 results[CLIENT_VERSION], 396 analysisServerOptions.clientVersion,
366 AnalysisServer.VERSION, 397 AnalysisServer.VERSION,
367 defaultSdk.sdkVersion); 398 defaultSdk.sdkVersion);
368 AnalysisEngine.instance.instrumentationService = instrumentationService; 399 AnalysisEngine.instance.instrumentationService = instrumentationService;
369 400
370 _DiagnosticServerImpl diagnosticServer = new _DiagnosticServerImpl(); 401 _DiagnosticServerImpl diagnosticServer = new _DiagnosticServerImpl();
371 402
403 // Ping analytics with our initial call.
404 analytics.sendScreenView('home');
405
372 // 406 //
373 // Create the sockets and start listening for requests. 407 // Create the sockets and start listening for requests.
374 // 408 //
375 socketServer = new SocketServer( 409 socketServer = new SocketServer(
376 analysisServerOptions, 410 analysisServerOptions,
377 new DartSdkManager(defaultSdkPath, true), 411 new DartSdkManager(defaultSdkPath, true),
378 defaultSdk, 412 defaultSdk,
379 instrumentationService, 413 instrumentationService,
380 diagnosticServer, 414 diagnosticServer,
381 serverPlugin, 415 serverPlugin,
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
445 parser.addFlag(ENABLE_INSTRUMENTATION_OPTION, 479 parser.addFlag(ENABLE_INSTRUMENTATION_OPTION,
446 help: "enable sending instrumentation information to a server", 480 help: "enable sending instrumentation information to a server",
447 defaultsTo: false, 481 defaultsTo: false,
448 negatable: false); 482 negatable: false);
449 parser.addFlag(HELP_OPTION, 483 parser.addFlag(HELP_OPTION,
450 help: "print this help message without starting a server", 484 help: "print this help message without starting a server",
451 abbr: 'h', 485 abbr: 'h',
452 defaultsTo: false, 486 defaultsTo: false,
453 negatable: false); 487 negatable: false);
454 parser.addOption(INSTRUMENTATION_LOG_FILE, 488 parser.addOption(INSTRUMENTATION_LOG_FILE,
455 help: 489 help: "write instrumentation data to the given file");
456 "the path of the file to which instrumentation data will be written" );
457 parser.addFlag(INTERNAL_PRINT_TO_CONSOLE, 490 parser.addFlag(INTERNAL_PRINT_TO_CONSOLE,
458 help: "enable sending `print` output to the console", 491 help: "enable sending `print` output to the console",
459 defaultsTo: false, 492 defaultsTo: false,
460 negatable: false); 493 negatable: false);
461 parser.addOption(NEW_ANALYSIS_DRIVER_LOG, 494 parser.addOption(NEW_ANALYSIS_DRIVER_LOG,
462 help: "set a destination for the new analysis driver's log"); 495 help: "set a destination for the new analysis driver's log");
463 parser.addFlag(VERBOSE_FLUTTER_COMPLETIONS, 496 parser.addFlag(VERBOSE_FLUTTER_COMPLETIONS,
464 help: "enable verbose code completion for Flutter (experimental)"); 497 help: "enable verbose code completion for Flutter (experimental)");
498 parser.addFlag(ANALYTICS_FLAG,
499 help: 'enable or disable sending analytics information to Google');
465 parser.addOption(PORT_OPTION, 500 parser.addOption(PORT_OPTION,
466 help: "the http diagnostic port on which the server provides" 501 help: "the http diagnostic port on which the server provides"
467 " status and performance information"); 502 " status and performance information");
468 parser.addOption(SDK_OPTION, help: "[path] the path to the sdk"); 503 parser.addOption(SDK_OPTION, help: "[path] the path to the sdk");
469 parser.addFlag(USE_ANALYSIS_HIGHLIGHT2, 504 parser.addFlag(USE_ANALYSIS_HIGHLIGHT2,
470 help: "enable version 2 of semantic highlight", 505 help: "enable version 2 of semantic highlight",
471 defaultsTo: false, 506 defaultsTo: false,
472 negatable: false); 507 negatable: false);
473 parser.addOption(FILE_READ_MODE, 508 parser.addOption(FILE_READ_MODE,
474 help: "an option for reading files (some clients normalize eol " 509 help: "an option for reading files (some clients normalize eol "
(...skipping 15 matching lines...) Expand all
490 PhysicalResourceProvider.INSTANCE; 525 PhysicalResourceProvider.INSTANCE;
491 FolderBasedDartSdk sdk = new FolderBasedDartSdk( 526 FolderBasedDartSdk sdk = new FolderBasedDartSdk(
492 resourceProvider, resourceProvider.getFolder(defaultSdkPath)); 527 resourceProvider, resourceProvider.getFolder(defaultSdkPath));
493 sdk.useSummary = useSummaries; 528 sdk.useSummary = useSummaries;
494 return sdk; 529 return sdk;
495 } 530 }
496 531
497 /** 532 /**
498 * Print information about how to use the server. 533 * Print information about how to use the server.
499 */ 534 */
500 void _printUsage(ArgParser parser) { 535 void _printUsage(ArgParser parser, telemetry.Analytics analytics,
536 {bool fromHelp: false}) {
501 print('Usage: $BINARY_NAME [flags]'); 537 print('Usage: $BINARY_NAME [flags]');
502 print(''); 538 print('');
503 print('Supported flags are:'); 539 print('Supported flags are:');
504 print(parser.usage); 540 print(parser.usage);
541
542 // Print analytics status and information.
543 if (fromHelp) {
544 print('');
545 print(telemetry.analyticsNotice);
546 }
547 print('');
548 print(telemetry.createAnalyticsStatusMessage(analytics.enabled,
549 command: ANALYTICS_FLAG));
505 } 550 }
506 551
507 /** 552 /**
508 * Read the UUID from disk, generating and storing a new one if necessary. 553 * Read the UUID from disk, generating and storing a new one if necessary.
509 */ 554 */
510 String _readUuid(InstrumentationService service) { 555 String _readUuid(InstrumentationService service) {
511 File uuidFile = new File(PhysicalResourceProvider.INSTANCE 556 File uuidFile = new File(PhysicalResourceProvider.INSTANCE
512 .getStateLocation('.instrumentation') 557 .getStateLocation('.instrumentation')
513 .getChild('uuid.txt') 558 .getChild('uuid.txt')
514 .path); 559 .path);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
561 606
562 _DiagnosticServerImpl(); 607 _DiagnosticServerImpl();
563 608
564 @override 609 @override
565 Future<int> getServerPort() => httpServer.serveHttp(); 610 Future<int> getServerPort() => httpServer.serveHttp();
566 611
567 Future startOnPort(int port) { 612 Future startOnPort(int port) {
568 return httpServer.serveHttp(port); 613 return httpServer.serveHttp(port);
569 } 614 }
570 } 615 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698