Files
flutter_lua_runtime/lib/runtime/diagnostics/runtime_diagnostics.dart
2026-06-09 16:26:37 +08:00

142 lines
3.1 KiB
Dart

import 'dart:convert';
class RuntimeDiagnostics {
RuntimeDiagnostics({this.maxEntries = 100});
final int maxEntries;
final List<RuntimeDiagnosticEntry> _entries = [];
List<RuntimeDiagnosticEntry> get entries => List.unmodifiable(_entries);
Map<String, Object?> toDebugJson() {
return {
'maxEntries': maxEntries,
'count': _entries.length,
'entries': _entries.map((entry) => entry.toDebugJson()).toList(),
};
}
String dumpText() {
if (_entries.isEmpty) {
return 'RuntimeDiagnostics: no entries';
}
final buffer = StringBuffer(
'RuntimeDiagnostics (${_entries.length}/$maxEntries)',
);
for (final entry in _entries) {
buffer
..writeln()
..write(entry.dumpText());
}
return buffer.toString();
}
void record({
required RuntimeDiagnosticType type,
required String message,
Object? error,
Map<String, Object?> context = const {},
}) {
if (_entries.length >= maxEntries) {
_entries.removeAt(0);
}
_entries.add(
RuntimeDiagnosticEntry(
type: type,
message: message,
error: error,
context: context,
timestamp: DateTime.now(),
),
);
}
void clear() {
_entries.clear();
}
}
class RuntimeDiagnosticEntry {
const RuntimeDiagnosticEntry({
required this.type,
required this.message,
required this.timestamp,
this.error,
this.context = const {},
});
final RuntimeDiagnosticType type;
final String message;
final DateTime timestamp;
final Object? error;
final Map<String, Object?> context;
Map<String, Object?> toDebugJson() {
return {
'timestamp': timestamp.toIso8601String(),
'type': type.name,
'message': message,
if (error != null) 'error': error.toString(),
if (context.isNotEmpty) 'context': _toDebugValue(context),
};
}
String dumpText() {
final buffer = StringBuffer(
'[${timestamp.toIso8601String()}] ${type.name}: $message',
);
if (error != null) {
buffer
..writeln()
..write(' error: $error');
}
if (context.isNotEmpty) {
buffer
..writeln()
..write(' context: ${_formatDebugValue(context)}');
}
return buffer.toString();
}
}
Object? _toDebugValue(Object? value) {
if (value == null || value is String || value is num || value is bool) {
return value;
}
if (value is DateTime) {
return value.toIso8601String();
}
if (value is Map) {
final entries = value.entries.toList()
..sort((a, b) => a.key.toString().compareTo(b.key.toString()));
return {
for (final entry in entries)
entry.key.toString(): _toDebugValue(entry.value),
};
}
if (value is Iterable) {
return value.map(_toDebugValue).toList();
}
return value.toString();
}
String _formatDebugValue(Object? value) {
try {
return jsonEncode(_toDebugValue(value));
} catch (_) {
return value.toString();
}
}
enum RuntimeDiagnosticType {
luaLog,
luaEventError,
diffApplyError,
packageActivationError,
resourceLoadError,
commandError,
networkError,
hostBridgeError,
}