Log Viewer / 日志查看器
Overview / 概述
The Log Viewer automatically captures logs from multiple sources with zero configuration.
日志查看器自动从多个来源捕获日志,无需配置。
Log Sources / 日志来源
| Source | Capture Method |
|---|---|
print() | Zone specification override / Zone 规范覆盖 |
debugPrint() | debugPrint override / debugPrint 覆盖 |
| Flutter errors | FlutterError.onError hook / 接管 FlutterError.onError |
| Unhandled exceptions | runZonedGuarded / runZonedGuarded 捕获 |
| Third-party libraries | Via print() capture / 通过 print() 捕获 |
Since v1.9.0, Flutter framework errors and unhandled exceptions are also aggregated & deduplicated in the dedicated Errors tab (keyed by type + stack signature) — while this Log Viewer keeps showing them as error-level lines in the chronological stream. Use Errors for “is this crash repeating?”; use Log Viewer for the raw timeline.
自 v1.9.0 起,Flutter 框架异常与未捕获异常会同时进入独立的 Errors 标签页去重聚合(按类型 + 堆栈签名归并);本 Log Viewer 仍会在原始时间流中把它们显示为错误级日志。回答”该崩溃是否反复出现”请用 Errors;查看原始时间线请用 Log Viewer。
Log Levels / 日志级别
| Level | Abbreviation | Color | Description |
|---|---|---|---|
| Verbose | V | Gray | Detailed information / 详细信息 |
| Debug | D | Blue | Debug information / 调试信息 |
| Info | I | Green | General information / 一般信息 |
| Warning | W | Orange | Warning messages / 警告信息 |
| Error | E | Red | Error messages / 错误信息 |
Third-party library logs are categorized as Info level.
第三方日志库的日志统一归类为 Info 级别。
UI Features / UI 功能
Filter Bar / 过滤栏
- All: Show all logs / 使用 All 显示所有日志
- V / D / I / W / E: Filter by level / 按级别过滤
- Tag dropdown: Filter by any captured tag / 按任意已捕获标签过滤
- Single-select mode / 单选模式
Toolbar / 工具栏
- Auto-scroll toggle (default on): Jump to the newest log as new entries arrive; pause to keep history still for inspection / 自动滚动开关(默认开启):新日志到达时自动跳到最新;暂停可稳定查看历史
- Copy as JSON: Copy all currently filtered logs as JSON / 复制为 JSON:将当前过滤后的全部日志复制为 JSON
- Share as Text: Share filtered logs as plain text / 分享为文本:将过滤后的日志以纯文本分享
- Clear: Clear all logs / 清除:清空全部日志
Log List / 日志列表
- Level badge with color / 带颜色的级别徽章
- Timestamp display / 时间戳显示
- Tag display (if available) / 标签显示(如有)
- Error/warning rows have subtle background tint / 错误/警告行有淡色背景
- Left border color indicates level / 左侧边框颜色表示级别
- Tap a row to open the in-view detail page with full message and copy; use the back button to return / 点击行进入详情页(主视图内切换),可查看完整消息并复制,点返回按钮回到列表
- Per-row copy button copies that single log as JSON / 行内复制按钮将该条日志以 JSON 复制
Search / 搜索
- Fuzzy search by message content or tag / 按消息内容或标签模糊搜索
- Toggle regex mode (
. *button) to search withRegExp(case-insensitive); invalid patterns degrade gracefully instead of crashing / 点击 正则模式(. *按钮)使用RegExp搜索(不区分大小写);非法图案优雅降级,不会崩溃 - Combined with level and tag filters / 可与级别、标签过滤组合使用
Manual Logging / 手动记录日志
Quick shorthand (recommended) / 简化写法(推荐) — available since v1.1.2 / v1.1.2 起可用:
InspectorLog.v('Verbose message / 详细消息');
InspectorLog.d('Debug message / 调试消息');
InspectorLog.i('Info message / 信息消息');
InspectorLog.w('Warning message / 警告消息');
InspectorLog.e('Error message / 错误消息');
// With tag / 带标签
InspectorLog.i('User logged in', tag: 'Auth');Full form / 完整写法:
InspectorLogInterceptor.instance.verbose('Verbose message / 详细消息');
InspectorLogInterceptor.instance.debug('Debug message / 调试消息');
InspectorLogInterceptor.instance.info('Info message / 信息消息');
InspectorLogInterceptor.instance.warning('Warning message / 警告消息');
InspectorLogInterceptor.instance.error('Error message / 错误消息');
// With tag / 带标签
InspectorLogInterceptor.instance.info('User logged in', tag: 'Auth');InspectorLog is a static wrapper around InspectorLogInterceptor.instance for shorter log calls.
InspectorLog 是 InspectorLogInterceptor.instance 的静态包装,用于更简短的日志调用。
Third-Party Library Integration / 第三方日志库集成
Auto-Capture (Inbound) / 自动捕获(入站)
No configuration needed. Any library using print() or debugPrint() is automatically captured.
无需配置。任何使用 print() 或 debugPrint() 的库都会被自动捕获。
Bidirectional Sync (Optional) / 双向同步(可选)
To forward inspector logs to your third-party logger:
将检查器日志转发到第三方日志库:
import 'package:logger/logger.dart';
final logger = Logger();
InspectorLogInterceptor.instance.onLogCaptured = (entry) {
logger.log(
_mapLogLevel(entry.level),
'${entry.tag != null ? '[${entry.tag}] ' : ''}${entry.message}',
);
};Note: Do NOT call logging methods inside
onLogCaptured, as this will cause infinite recursion. 注意:不要在onLogCaptured内部调用日志方法,否则会导致无限递归。
Starting the Log Interceptor / 启动日志拦截器
If using runAppWithInspector(), the log interceptor starts automatically. Otherwise:
如果使用 runAppWithInspector(),日志拦截器会自动启动。否则:
InspectorLogInterceptor.instance.start();