tools(devlog): garder le pont VM Service au dépôt
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
This commit is contained in:
parent
054cbfab3c
commit
17b2f03ce0
8
RECAP.md
8
RECAP.md
@ -164,10 +164,10 @@ non. Patrick a piloté à l'écran, l'agent a observé. Une capture par étape d
|
||||
|
||||
`flutter run` **n'imprime pas** les traces `dart:developer log()` — elles partent au VM
|
||||
Service, ni sur stdout ni dans logcat. Tout ce que `NymeaService._log()` journalise était
|
||||
donc invisible. Le pont `scratchpad/vm_logs.dart` s'abonne au flux `Logging` du VM Service
|
||||
et rend la trace. **Sans lui, aucun des constats ci-dessous n'était atteignable.** À
|
||||
récupérer au prochain passage (attention : horodater sur `event.timestamp`, pas à la
|
||||
réception — le VM Service livre l'historique bufférisé d'un coup).
|
||||
donc invisible. Le pont **`tools/devlog/vm_logs.dart`** s'abonne au flux `Logging` du VM
|
||||
Service et rend la trace. **Sans lui, aucun des constats ci-dessous n'était atteignable.**
|
||||
Mode d'emploi en tête du fichier, piège d'horodatage compris (lire `event.timestamp`, pas
|
||||
l'heure de réception : le VM Service livre l'historique bufférisé d'un coup).
|
||||
|
||||
### Critères
|
||||
|
||||
|
||||
58
tools/devlog/vm_logs.dart
Normal file
58
tools/devlog/vm_logs.dart
Normal file
@ -0,0 +1,58 @@
|
||||
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));
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user