feat:设备日志模块
feat:定时任务 feat:设置页面用路由重构
This commit is contained in:
1 parent
1033f403b1
commit
2efa7a3c19
60 files changed
+6560
-643
No files matched your search
@@ -43,6 +43,53 @@ Future<AppLogCatalog> listAppLogFiles() async {
|
||||
return _consoleOutput.listLogFiles();
|
||||
}
|
||||
|
||||
/// 上传当前日志前刷新文件写入队列,保证快照边界包含调用前已经产生的日志。
|
||||
Future<void> flushCurrentAppLog() async {
|
||||
await logger.init;
|
||||
await _consoleOutput.flushCurrentLog();
|
||||
}
|
||||
|
||||
/// 逐行生成脱敏副本,上传工具不会把原始日志文件直接交给网络层。
|
||||
Future<void> sanitizeAppLogFile({
|
||||
required File source,
|
||||
required File target,
|
||||
int? maxSourceBytes,
|
||||
}) async {
|
||||
final sourceLength = await source.length();
|
||||
final limit = maxSourceBytes == null
|
||||
? sourceLength
|
||||
: maxSourceBytes.clamp(0, sourceLength);
|
||||
final input = await source.open();
|
||||
IOSink? output;
|
||||
try {
|
||||
output = target.openWrite(mode: FileMode.writeOnly);
|
||||
var position = 0;
|
||||
var pending = '';
|
||||
const chunkSize = 64 * 1024;
|
||||
while (position < limit) {
|
||||
final length = (limit - position).clamp(0, chunkSize);
|
||||
final bytes = await input.read(length);
|
||||
if (bytes.isEmpty) break;
|
||||
position += bytes.length;
|
||||
pending += utf8.decode(bytes, allowMalformed: true);
|
||||
final lines = pending.split('\n');
|
||||
pending = lines.removeLast();
|
||||
for (final line in lines) {
|
||||
output.writeln(sanitizeAppLogContent(line));
|
||||
}
|
||||
}
|
||||
if (pending.isNotEmpty) output.write(sanitizeAppLogContent(pending));
|
||||
await output.flush();
|
||||
} finally {
|
||||
await input.close();
|
||||
await output?.close();
|
||||
}
|
||||
}
|
||||
|
||||
/// 日志预览和上传共用同一套脱敏规则,避免两个入口出现隐私边界漂移。
|
||||
String sanitizeAppLogContent(String content) =>
|
||||
_sanitizePreviewContent(content);
|
||||
|
||||
class AppLogCatalog {
|
||||
const AppLogCatalog({
|
||||
required this.rootPath,
|
||||
@@ -113,6 +160,9 @@ class ConsoleOutput extends LogOutput {
|
||||
return _queue;
|
||||
}
|
||||
|
||||
/// 排在既有写入队列末尾刷新当前文件,完成后调用方可取得一致的文件大小快照。
|
||||
Future<void> flushCurrentLog() => _enqueue(() async => _sink?.flush());
|
||||
|
||||
/// 读取当前日志文件尾部,并在返回 UI 前移除终端颜色码和常见敏感字段。
|
||||
Future<AppLogPreview> readPreview({
|
||||
String? path,
|
||||
|
||||
Reference in new issue
Block a user