| OLD | NEW |
| 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 library instrumentation; | 5 library analyzer.instrumentation.instrumentation; |
| 6 | 6 |
| 7 import 'dart:async'; |
| 7 import 'dart:convert'; | 8 import 'dart:convert'; |
| 8 | 9 |
| 9 import 'package:analyzer/task/model.dart'; | 10 import 'package:analyzer/task/model.dart'; |
| 10 | 11 |
| 11 /** | 12 /** |
| 12 * A container with analysis performance constants. | 13 * A container with analysis performance constants. |
| 13 */ | 14 */ |
| 14 class AnalysisPerformanceKind { | 15 class AnalysisPerformanceKind { |
| 15 static const String FULL = 'analysis_full'; | 16 static const String FULL = 'analysis_full'; |
| 16 static const String INCREMENTAL = 'analysis_incremental'; | 17 static const String INCREMENTAL = 'analysis_incremental'; |
| 17 } | 18 } |
| 18 | 19 |
| 19 /** | 20 /** |
| 20 * The interface used by client code to communicate with an instrumentation | 21 * The interface used by client code to communicate with an instrumentation |
| 21 * server. | 22 * server. |
| 22 */ | 23 */ |
| 23 abstract class InstrumentationServer { | 24 abstract class InstrumentationServer { |
| 24 /** | 25 /** |
| 26 * Return the identifier used to identify the current session. |
| 27 */ |
| 28 String get sessionId; |
| 29 |
| 30 /** |
| 25 * Pass the given [message] to the instrumentation server so that it will be | 31 * Pass the given [message] to the instrumentation server so that it will be |
| 26 * logged with other messages. | 32 * logged with other messages. |
| 27 * | 33 * |
| 28 * This method should be used for most logging. | 34 * This method should be used for most logging. |
| 29 */ | 35 */ |
| 30 void log(String message); | 36 void log(String message); |
| 31 | 37 |
| 32 /** | 38 /** |
| 33 * Pass the given [message] to the instrumentation server so that it will be | 39 * Pass the given [message] to the instrumentation server so that it will be |
| 34 * logged with other messages. | 40 * logged with other messages. |
| 35 * | 41 * |
| 36 * This method should only be used for logging high priority messages, such as | 42 * This method should only be used for logging high priority messages, such as |
| 37 * exceptions that cause the server to shutdown. | 43 * exceptions that cause the server to shutdown. |
| 38 */ | 44 */ |
| 39 void logWithPriority(String message); | 45 void logWithPriority(String message); |
| 40 | 46 |
| 41 /** | 47 /** |
| 42 * Signal that the client is done communicating with the instrumentation | 48 * Signal that the client is done communicating with the instrumentation |
| 43 * server. This method should be invoked exactly one time and no other methods | 49 * server. This method should be invoked exactly one time and no other methods |
| 44 * should be invoked on this instance after this method has been invoked. | 50 * should be invoked on this instance after this method has been invoked. |
| 45 */ | 51 */ |
| 46 void shutdown(); | 52 Future shutdown(); |
| 47 } | 53 } |
| 48 | 54 |
| 49 /** | 55 /** |
| 50 * The interface used by client code to communicate with an instrumentation | 56 * The interface used by client code to communicate with an instrumentation |
| 51 * server by wrapping an [InstrumentationServer]. | 57 * server by wrapping an [InstrumentationServer]. |
| 52 */ | 58 */ |
| 53 class InstrumentationService { | 59 class InstrumentationService { |
| 54 /** | 60 /** |
| 55 * An instrumentation service that will not log any instrumentation data. | 61 * An instrumentation service that will not log any instrumentation data. |
| 56 */ | 62 */ |
| (...skipping 19 matching lines...) Expand all Loading... |
| 76 * if instrumentation data should not be logged. | 82 * if instrumentation data should not be logged. |
| 77 */ | 83 */ |
| 78 InstrumentationServer _instrumentationServer; | 84 InstrumentationServer _instrumentationServer; |
| 79 | 85 |
| 80 /** | 86 /** |
| 81 * Counter used to generate unique ID's for [logSubprocessStart]. | 87 * Counter used to generate unique ID's for [logSubprocessStart]. |
| 82 */ | 88 */ |
| 83 int _subprocessCounter = 0; | 89 int _subprocessCounter = 0; |
| 84 | 90 |
| 85 /** | 91 /** |
| 86 * Initialize a newly created instrumentation service to comunicate with the | 92 * Initialize a newly created instrumentation service to communicate with the |
| 87 * given [instrumentationServer]. | 93 * given [_instrumentationServer]. |
| 88 */ | 94 */ |
| 89 InstrumentationService(this._instrumentationServer); | 95 InstrumentationService(this._instrumentationServer); |
| 90 | 96 |
| 91 /** | 97 /** |
| 92 * Return `true` if this [InstrumentationService] was initialized with a | 98 * Return `true` if this [InstrumentationService] was initialized with a |
| 93 * non-`null` server (and hence instrumentation is active). | 99 * non-`null` server (and hence instrumentation is active). |
| 94 */ | 100 */ |
| 95 bool get isActive => _instrumentationServer != null; | 101 bool get isActive => _instrumentationServer != null; |
| 96 | 102 |
| 97 /** | 103 /** |
| 104 * Return the identifier used to identify the current session. |
| 105 */ |
| 106 String get sessionId => _instrumentationServer?.sessionId ?? ''; |
| 107 |
| 108 /** |
| 98 * The current time, expressed as a decimal encoded number of milliseconds. | 109 * The current time, expressed as a decimal encoded number of milliseconds. |
| 99 */ | 110 */ |
| 100 String get _timestamp => new DateTime.now().millisecondsSinceEpoch.toString(); | 111 String get _timestamp => new DateTime.now().millisecondsSinceEpoch.toString(); |
| 101 | 112 |
| 102 /** | 113 /** |
| 103 * Log that the given analysis [task] is being performed in the given | 114 * Log that the given analysis [task] is being performed in the given |
| 104 * [context]. | 115 * [context]. |
| 105 */ | 116 */ |
| 106 void logAnalysisTask(String context, dynamic task) { | 117 void logAnalysisTask(String context, AnalysisTask task) { |
| 107 // TODO(brianwilkerson) When the old task model is removed, change the | |
| 108 // parameter type to AnalysisTask. | |
| 109 if (_instrumentationServer != null) { | 118 if (_instrumentationServer != null) { |
| 110 String description = | |
| 111 (task is AnalysisTask) ? task.description : task.toString(); | |
| 112 _instrumentationServer | 119 _instrumentationServer |
| 113 .log(_join([TAG_ANALYSIS_TASK, context, description])); | 120 .log(_join([TAG_ANALYSIS_TASK, context, task.description])); |
| 114 } | 121 } |
| 115 } | 122 } |
| 116 | 123 |
| 117 /** | 124 /** |
| 118 * Log the fact that an error, described by the given [message], has occurred. | 125 * Log the fact that an error, described by the given [message], has occurred. |
| 119 */ | 126 */ |
| 120 void logError(String message) { | 127 void logError(String message) { |
| 121 _log(TAG_ERROR, message); | 128 _log(TAG_ERROR, message); |
| 122 } | 129 } |
| 123 | 130 |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 | 216 |
| 210 /** | 217 /** |
| 211 * Log that a response has been sent to the client. | 218 * Log that a response has been sent to the client. |
| 212 */ | 219 */ |
| 213 void logResponse(String response) { | 220 void logResponse(String response) { |
| 214 _log(TAG_RESPONSE, response); | 221 _log(TAG_RESPONSE, response); |
| 215 } | 222 } |
| 216 | 223 |
| 217 /** | 224 /** |
| 218 * Log the result of executing a subprocess. [subprocessId] should be the | 225 * Log the result of executing a subprocess. [subprocessId] should be the |
| 219 * unique IDreturned by [logSubprocessStart]. | 226 * unique ID returned by [logSubprocessStart]. |
| 220 */ | 227 */ |
| 221 void logSubprocessResult( | 228 void logSubprocessResult( |
| 222 int subprocessId, int exitCode, String stdout, String stderr) { | 229 int subprocessId, int exitCode, String stdout, String stderr) { |
| 223 if (_instrumentationServer != null) { | 230 if (_instrumentationServer != null) { |
| 224 _instrumentationServer.log(_join([ | 231 _instrumentationServer.log(_join([ |
| 225 TAG_SUBPROCESS_RESULT, | 232 TAG_SUBPROCESS_RESULT, |
| 226 subprocessId.toString(), | 233 subprocessId.toString(), |
| 227 exitCode.toString(), | 234 exitCode.toString(), |
| 228 JSON.encode(stdout), | 235 JSON.encode(stdout), |
| 229 JSON.encode(stderr) | 236 JSON.encode(stderr) |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 283 _instrumentationServer | 290 _instrumentationServer |
| 284 .log(_join([TAG_WATCH_EVENT, folderPath, filePath, changeType])); | 291 .log(_join([TAG_WATCH_EVENT, folderPath, filePath, changeType])); |
| 285 } | 292 } |
| 286 } | 293 } |
| 287 | 294 |
| 288 /** | 295 /** |
| 289 * Signal that the client is done communicating with the instrumentation | 296 * Signal that the client is done communicating with the instrumentation |
| 290 * server. This method should be invoked exactly one time and no other methods | 297 * server. This method should be invoked exactly one time and no other methods |
| 291 * should be invoked on this instance after this method has been invoked. | 298 * should be invoked on this instance after this method has been invoked. |
| 292 */ | 299 */ |
| 293 void shutdown() { | 300 Future shutdown() async { |
| 294 if (_instrumentationServer != null) { | 301 if (_instrumentationServer != null) { |
| 295 _instrumentationServer.shutdown(); | 302 await _instrumentationServer.shutdown(); |
| 296 _instrumentationServer = null; | 303 _instrumentationServer = null; |
| 297 } | 304 } |
| 298 } | 305 } |
| 299 | 306 |
| 300 /** | 307 /** |
| 301 * Write an escaped version of the given [field] to the given [buffer]. | 308 * Write an escaped version of the given [field] to the given [buffer]. |
| 302 */ | 309 */ |
| 303 void _escape(StringBuffer buffer, String field) { | 310 void _escape(StringBuffer buffer, String field) { |
| 304 int index = field.indexOf(':'); | 311 int index = field.indexOf(':'); |
| 305 if (index < 0) { | 312 if (index < 0) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 316 buffer.write(field.substring(start)); | 323 buffer.write(field.substring(start)); |
| 317 } | 324 } |
| 318 | 325 |
| 319 /** | 326 /** |
| 320 * Return the result of joining the values of the given fields, escaping the | 327 * Return the result of joining the values of the given fields, escaping the |
| 321 * separator character by doubling it. | 328 * separator character by doubling it. |
| 322 */ | 329 */ |
| 323 String _join(List<String> fields) { | 330 String _join(List<String> fields) { |
| 324 StringBuffer buffer = new StringBuffer(); | 331 StringBuffer buffer = new StringBuffer(); |
| 325 buffer.write(_timestamp); | 332 buffer.write(_timestamp); |
| 326 for (String field in fields) { | 333 int length = fields.length; |
| 334 for (int i = 0; i < length; i++) { |
| 327 buffer.write(':'); | 335 buffer.write(':'); |
| 328 _escape(buffer, field); | 336 _escape(buffer, fields[i]); |
| 329 } | 337 } |
| 330 return buffer.toString(); | 338 return buffer.toString(); |
| 331 } | 339 } |
| 332 | 340 |
| 333 /** | 341 /** |
| 334 * Log the given message with the given tag. | 342 * Log the given message with the given tag. |
| 335 */ | 343 */ |
| 336 void _log(String tag, String message) { | 344 void _log(String tag, String message) { |
| 337 if (_instrumentationServer != null) { | 345 if (_instrumentationServer != null) { |
| 338 _instrumentationServer.log(_join([tag, message])); | 346 _instrumentationServer.log(_join([tag, message])); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 352 | 360 |
| 353 /** | 361 /** |
| 354 * An [InstrumentationServer] that sends messages to multiple instances. | 362 * An [InstrumentationServer] that sends messages to multiple instances. |
| 355 */ | 363 */ |
| 356 class MulticastInstrumentationServer implements InstrumentationServer { | 364 class MulticastInstrumentationServer implements InstrumentationServer { |
| 357 final List<InstrumentationServer> _servers; | 365 final List<InstrumentationServer> _servers; |
| 358 | 366 |
| 359 MulticastInstrumentationServer(this._servers); | 367 MulticastInstrumentationServer(this._servers); |
| 360 | 368 |
| 361 @override | 369 @override |
| 370 String get sessionId => _servers[0].sessionId; |
| 371 |
| 372 @override |
| 362 void log(String message) { | 373 void log(String message) { |
| 363 for (InstrumentationServer server in _servers) { | 374 for (InstrumentationServer server in _servers) { |
| 364 server.log(message); | 375 server.log(message); |
| 365 } | 376 } |
| 366 } | 377 } |
| 367 | 378 |
| 368 @override | 379 @override |
| 369 void logWithPriority(String message) { | 380 void logWithPriority(String message) { |
| 370 for (InstrumentationServer server in _servers) { | 381 for (InstrumentationServer server in _servers) { |
| 371 server.logWithPriority(message); | 382 server.logWithPriority(message); |
| 372 } | 383 } |
| 373 } | 384 } |
| 374 | 385 |
| 375 @override | 386 @override |
| 376 void shutdown() { | 387 Future shutdown() async { |
| 377 for (InstrumentationServer server in _servers) { | 388 for (InstrumentationServer server in _servers) { |
| 378 server.shutdown(); | 389 await server.shutdown(); |
| 379 } | 390 } |
| 380 } | 391 } |
| 381 } | 392 } |
| OLD | NEW |