flutter run n'imprime pas les traces dart:developer log() — elles partent au VM Service, ni sur stdout ni dans logcat. Ce pont est ce qui a rendu le passage sur appareil du 2026-08-25 exploitable ; il ne vivait que dans un scratchpad de session, alors que le RECAP le donnait « à récupérer au prochain passage ». Mode d'emploi en tête, avec le piège déjà payé une fois : le VM Service livre l'historique bufférisé d'un coup au streamListen, donc horodater à la réception écrase toute la chronologie sous une seule seconde. On lit event.timestamp. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XPUo3RMr8SzK6qbFtfBm8H
59 lines
2.1 KiB
Dart
59 lines
2.1 KiB
Dart
import 'dart:async';
|
|
import 'dart:convert';
|
|
import 'dart:io';
|
|
|
|
// Capte les traces `dart:developer log()` de l'app en cours d'exécution.
|
|
//
|
|
// `flutter run` ne les imprime PAS sur stdout (elles partent au VM Service, pas à
|
|
// stdout ni à logcat). Sans ce pont, tout ce que `NymeaService._log()` journalise est
|
|
// invisible depuis le poste — donc les traces de locale, de télémétrie et d'écriture
|
|
// aussi.
|
|
//
|
|
// Usage : dart vm_logs.dart ws://127.0.0.1:PORT/TOKEN=/ws
|
|
Future<void> main(List<String> args) async {
|
|
final uri = args.first;
|
|
final ws = await WebSocket.connect(uri);
|
|
var id = 0;
|
|
void call(String method, [Map<String, dynamic> params = const {}]) {
|
|
ws.add(jsonEncode({
|
|
'jsonrpc': '2.0',
|
|
'id': (++id).toString(),
|
|
'method': method,
|
|
'params': params,
|
|
}));
|
|
}
|
|
|
|
ws.listen((raw) {
|
|
final m = jsonDecode(raw as String) as Map<String, dynamic>;
|
|
if (m['method'] != 'streamNotify') return;
|
|
final ev = (m['params'] as Map)['event'] as Map;
|
|
final kind = ev['kind'];
|
|
// L'heure de l'ENREGISTREMENT, pas celle de la réception : le VM Service livre
|
|
// l'historique bufférisé d'un coup au moment du streamListen, et horodater à la
|
|
// réception écraserait toute la chronologie sous une seule seconde.
|
|
final micros = (ev['timestamp'] as num?)?.toInt();
|
|
final ts = micros == null
|
|
? '--:--:--'
|
|
: DateTime.fromMillisecondsSinceEpoch(micros)
|
|
.toIso8601String()
|
|
.substring(11, 23);
|
|
if (kind == 'Logging') {
|
|
final rec = ev['logRecord'] as Map;
|
|
final name = (rec['loggerName'] as Map?)?['valueAsString'] ?? '';
|
|
final msg = (rec['message'] as Map?)?['valueAsString'] ?? '';
|
|
print('$ts [$name] $msg');
|
|
} else if (kind == 'WriteEvent') {
|
|
final bytes = ev['bytes'] as String?;
|
|
if (bytes != null) {
|
|
stdout.write('$ts [stdout] ${utf8.decode(base64.decode(bytes))}');
|
|
}
|
|
}
|
|
});
|
|
|
|
call('streamListen', {'streamId': 'Logging'});
|
|
call('streamListen', {'streamId': 'Stdout'});
|
|
call('streamListen', {'streamId': 'Stderr'});
|
|
print('--- branché sur $uri ---');
|
|
await Future<void>.delayed(const Duration(hours: 2));
|
|
}
|