mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 10:49:00 +00:00
[dds] Support logging VM Service traffic to the client from DAP
Change-Id: Id9f6b2158dcf1603468b989ed2f900b390b9b259 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/209546 Reviewed-by: Ben Konyi <bkonyi@google.com> Commit-Queue: Ben Konyi <bkonyi@google.com>
This commit is contained in:
parent
52e94d1bbb
commit
7a4fbdf88f
6 changed files with 52 additions and 19 deletions
|
@ -176,6 +176,8 @@ abstract class DartDebugAdapter<T extends DartLaunchRequestArguments>
|
|||
/// VM Service closing).
|
||||
bool _hasSentTerminatedEvent = false;
|
||||
|
||||
late final sendLogsToClient = args.sendLogsToClient ?? false;
|
||||
|
||||
DartDebugAdapter(
|
||||
ByteStreamServerChannel channel, {
|
||||
this.ipv6 = false,
|
||||
|
@ -305,8 +307,7 @@ abstract class DartDebugAdapter<T extends DartLaunchRequestArguments>
|
|||
|
||||
logger?.call('Connecting to debugger at $uri');
|
||||
sendOutput('console', 'Connecting to VM Service at $uri\n');
|
||||
final vmService =
|
||||
await _vmServiceConnectUri(uri.toString(), logger: logger);
|
||||
final vmService = await _vmServiceConnectUri(uri.toString());
|
||||
logger?.call('Connected to debugger at $uri!');
|
||||
|
||||
// TODO(dantup): VS Code currently depends on a custom dart.debuggerUris
|
||||
|
@ -1313,6 +1314,13 @@ abstract class DartDebugAdapter<T extends DartLaunchRequestArguments>
|
|||
}
|
||||
}
|
||||
|
||||
void _logTraffic(String data) {
|
||||
logger?.call(data);
|
||||
if (sendLogsToClient) {
|
||||
sendEvent(RawEventBody(data), eventType: 'dart.log');
|
||||
}
|
||||
}
|
||||
|
||||
/// Performs some setup that is common to both [launchRequest] and
|
||||
/// [attachRequest].
|
||||
Future<void> _prepareForLaunchOrAttach() async {
|
||||
|
@ -1352,17 +1360,15 @@ abstract class DartDebugAdapter<T extends DartLaunchRequestArguments>
|
|||
|
||||
/// A wrapper around the same name function from package:vm_service that
|
||||
/// allows logging all traffic over the VM Service.
|
||||
Future<vm.VmService> _vmServiceConnectUri(
|
||||
String wsUri, {
|
||||
Logger? logger,
|
||||
}) async {
|
||||
Future<vm.VmService> _vmServiceConnectUri(String wsUri) async {
|
||||
final socket = await WebSocket.connect(wsUri);
|
||||
final controller = StreamController();
|
||||
final streamClosedCompleter = Completer();
|
||||
final logger = this.logger;
|
||||
|
||||
socket.listen(
|
||||
(data) {
|
||||
logger?.call('<== [VM] $data');
|
||||
_logTraffic('<== [VM] $data');
|
||||
controller.add(data);
|
||||
},
|
||||
onDone: () => streamClosedCompleter.complete(),
|
||||
|
@ -1372,6 +1378,7 @@ abstract class DartDebugAdapter<T extends DartLaunchRequestArguments>
|
|||
controller.stream,
|
||||
(String message) {
|
||||
logger?.call('==> [VM] $message');
|
||||
_logTraffic('==> [VM] $message');
|
||||
socket.add(message);
|
||||
},
|
||||
log: logger != null ? VmServiceLogger(logger) : null,
|
||||
|
|
|
@ -167,10 +167,10 @@ abstract class BaseDebugAdapter<TLaunchArgs extends LaunchRequestArguments> {
|
|||
|
||||
/// Sends an event, lookup up the event type based on the runtimeType of
|
||||
/// [body].
|
||||
void sendEvent(EventBody body) {
|
||||
void sendEvent(EventBody body, {String? eventType}) {
|
||||
final event = Event(
|
||||
seq: _sequence++,
|
||||
event: eventTypes[body.runtimeType]!,
|
||||
event: eventType ?? eventTypes[body.runtimeType]!,
|
||||
body: body,
|
||||
);
|
||||
_channel.sendEvent(event);
|
||||
|
|
|
@ -2,12 +2,35 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'dart:convert';
|
||||
|
||||
/// A base class for (spec-generated) classes that represent the `body` of a an
|
||||
/// event.
|
||||
abstract class EventBody {
|
||||
static bool canParse(Object? obj) => obj is Map<String, Object?>?;
|
||||
}
|
||||
|
||||
/// A generic event body class that just supplies an object directly.
|
||||
///
|
||||
/// Used to support custom events sent by the debug adapter such as 'dart.log'.
|
||||
///
|
||||
/// The supplied [body] must be convertable to JSON.
|
||||
class RawEventBody extends EventBody {
|
||||
final Object body;
|
||||
|
||||
RawEventBody(this.body)
|
||||
: assert(() {
|
||||
try {
|
||||
jsonEncode(body);
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}(), 'body should be JSON encodable');
|
||||
|
||||
Object toJson() => body;
|
||||
}
|
||||
|
||||
/// A generic arguments class that just supplies the arguments map directly.
|
||||
///
|
||||
/// Used to support custom requests that may be provided by other implementing
|
||||
|
|
|
@ -53,7 +53,6 @@ class InProcessDapTestServer extends DapTestServer {
|
|||
}) async {
|
||||
return InProcessDapTestServer._([
|
||||
...?additionalArgs,
|
||||
if (logger != null) '--verbose',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -107,12 +106,7 @@ class OutOfProcessDapTestServer extends DapTestServer {
|
|||
|
||||
final _process = await Process.start(
|
||||
Platform.resolvedExecutable,
|
||||
[
|
||||
dapServerScript,
|
||||
'dap',
|
||||
...?additionalArgs,
|
||||
if (logger != null) '--verbose'
|
||||
],
|
||||
[dapServerScript, 'dap', ...?additionalArgs],
|
||||
);
|
||||
|
||||
return OutOfProcessDapTestServer._(_process, logger);
|
||||
|
|
|
@ -23,6 +23,13 @@ import 'test_server.dart';
|
|||
/// simplified in VS Code by using a launch config with custom CodeLens links).
|
||||
final useInProcessDap = Platform.environment['DAP_TEST_INTERNAL'] == 'true';
|
||||
|
||||
/// Whether to print all protocol traffic to stdout while running tests.
|
||||
///
|
||||
/// This is useful for debugging locally or on the bots and will include both
|
||||
/// DAP traffic (between the test DAP client and the DAP server) and the VM
|
||||
/// Service traffic (wrapped in a custom 'dart.log' event).
|
||||
final verboseLogging = Platform.environment['DAP_TEST_VERBOSE'] == 'true';
|
||||
|
||||
/// A [RegExp] that matches the `path` part of a VM Service URI that contains
|
||||
/// an authentication token.
|
||||
final vmServiceAuthCodePathPattern = RegExp(r'^/[\w_\-=]{5,15}/ws$');
|
||||
|
@ -141,8 +148,11 @@ foo() {
|
|||
|
||||
static Future<DapTestSession> setUp({List<String>? additionalArgs}) async {
|
||||
final server = await _startServer(additionalArgs: additionalArgs);
|
||||
final client =
|
||||
await DapTestClient.connect(server, captureVmServiceTraffic: true);
|
||||
final client = await DapTestClient.connect(
|
||||
server,
|
||||
captureVmServiceTraffic: verboseLogging,
|
||||
logger: verboseLogging ? print : null,
|
||||
);
|
||||
return DapTestSession._(server, client);
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,6 @@ class DapCommand extends Command {
|
|||
static const argIpv6 = 'ipv6';
|
||||
static const argDds = 'dds';
|
||||
static const argAuthCodes = 'auth-codes';
|
||||
static const argVerbose = 'verbose';
|
||||
|
||||
final Stream<List<int>> _inputStream;
|
||||
final StreamSink<List<int>> _outputSink;
|
||||
|
|
Loading…
Reference in a new issue