Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .pubignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,6 @@ wiki/
TODO.md
AGENTS.md
CONTRIBUTING.md

# Local build artifacts (test caches, native assets) — not needed by consumers.
build/
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ An in-app developer console for Flutter: inspect HTTP, WebSocket & gRPC traffic,
[![Dart](https://img.shields.io/badge/Dart-✓-0175C2?logo=dart)](https://dart.dev)
[![Style: effective dart](https://img.shields.io/badge/style-effective_dart-40c4ff.svg)](https://pub.dev/packages/effective_dart)

> **🔔 Upgrade recommended:** This release adds a dedicated **Errors** tab (aggregated `FlutterError` deduped by type/stack, with occurrence count, first/last seen time and collapsible stacks), persists logs / network / errors to a SQLite ring buffer so data survives restarts (plus a full-session archive export), bridges Flutter's official `MemoryAllocations` as a second leak-detection source, fixes FPS being misjudged as low while the app is idle, and splits `InspectorService` into per-category notifiers to narrow rebuild scope. All users are encouraged to upgrade to the latest version (`^1.9.0`).
> **🔔 Upgrade recommended:** This release adds a dedicated **Errors** tab (aggregated `FlutterError` deduped by type/stack, with occurrence count, first/last seen time and collapsible stacks), persists logs / network / errors into its own `zero_inspector_kit.db` database (a disk ring buffer) so data survives restarts (plus a full-session archive export), bridges Flutter's official `MemoryAllocations` as a second leak-detection source, fixes FPS being misjudged as low while the app is idle, and splits `InspectorService` into per-category notifiers to narrow rebuild scope. All users are encouraged to upgrade to the latest version (`^1.9.0`).

🌐 **[Official Website](https://www.zerolabsco.com/)**  ·  📦 **[View on pub.dev](https://pub.dev/packages/zero_inspector_kit)**  ·  🔗 **[View on GitHub](https://github.com/zero-labsco/zero_inspector_kit)**

Expand Down Expand Up @@ -61,7 +61,7 @@ An in-app developer console for Flutter: inspect HTTP, WebSocket & gRPC traffic,
- **WebSocket / gRPC Capture** — Opt-in streaming-protocol capture (off by default, runtime toggle like Memory/FPS); WebSocket frames and gRPC calls appear in the Network list.
- **Logging System** — Auto-captures `print()`, `debugPrint()`, and custom logs across multiple levels; integrates with third-party log libraries; auto-scroll (pausable), regex search, tag filtering and one-tap copy of a single log entry.
- **Error Monitor** — Dedicated Errors tab (since v1.9.0): hooks `FlutterError.onError` + `runZonedGuarded`, aggregates & dedups crashes by type + stack signature with count and first/last seen; a red count badge sits on the Errors tab icon.
- **Session Persistence** — Logs / network / errors flushed to a local SQLite ring buffer (since v1.9.0); on launch logs & errors replay into their tabs; export & share the full session archive from the panel header.
- **Session Persistence** — Logs / network / errors are asynchronously flushed into the inspector's own `zero_inspector_kit.db` (since v1.9.0; a disk ring buffer that also shows up in the Database tab); on launch logs & errors replay into their tabs; export & share the full session archive from the panel header.
- **Database Viewer** — Inspect SQLite and other databases via custom providers.
- **Memory Monitor** — Trend chart, Dart Heap, Native memory breakdown, leak detection, image-cache & storage stats (master switch to avoid overhead). Since v1.9.0 the leak detector also bridges Flutter's official `FlutterMemoryAllocations` to cut false positives.
- **FPS Monitor** — Real-time FPS, jank detection, trend chart, frame records (master switch to avoid overhead).
Expand Down Expand Up @@ -241,7 +241,7 @@ InspectorLogInterceptor.instance.onLogCaptured = (entry) {

### Error Monitor

> Available since v1.9.0 / v1.9.0 起可用
> Available since v1.9.0

The **Errors** tab answers "is the same crash happening repeatedly?" `ErrorService` hooks `FlutterError.onError` (keeping the default red-screen behavior) plus `runZonedGuarded` inside `runAppWithInspector()`, then aggregates each exception by **type + stack signature**: repeated crashes merge into one record with a **×N** count and first/last-seen time. Tap a row to expand the full stack sample, filter by search, and copy individual stacks. A red count badge on the Errors tab icon shows the number of aggregated records while the panel is open.

Expand All @@ -262,9 +262,9 @@ Toggle with `enableErrorCapture` in `init()` (default `true`). Full details on t

### Session Persistence

> Available since v1.9.0 / v1.9.0 起可用
> Available since v1.9.0

Logs, network requests, and aggregated errors are asynchronously flushed to a local SQLite **ring buffer**. On the next launch, **logs and aggregated errors replay into their tabs**; network requests stay archived on disk for later export. Data therefore survives app restarts even if you never opened the panel. Tap the **storage icon** in the panel header to open the **Persisted data** manager: see row counts per category, export the **full session archive** as JSON (share sheet), or clear the disk.
Logs, network requests, and aggregated errors are asynchronously flushed into the inspector's own database file, **`zero_inspector_kit.db`** — a SQLite-backed disk ring buffer that also appears in the **Database** tab. On the next launch, **logs and aggregated errors replay into their tabs**; network requests stay archived on disk for later export. Data therefore survives app restarts even if you never opened the panel. Tap the **storage icon** in the panel header to open the **Persisted data** manager: see row counts per category, export the **full session archive** as JSON (share sheet), or clear the disk.

```dart
// Reading persisted data programmatically (optional)
Expand Down
6 changes: 3 additions & 3 deletions README_zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
[![Dart](https://img.shields.io/badge/Dart-✓-0175C2?logo=dart)](https://dart.dev)
[![Style: effective dart](https://img.shields.io/badge/style-effective_dart-40c4ff.svg)](https://pub.dev/packages/effective_dart)

> **🔔 推荐升级:** 本次更新新增独立的 **Errors(异常聚合)** 标签页(按异常类型 / 堆栈去重,显示出现次数、首末次时间与可折叠堆栈),把日志 / 网络 / 异常落盘到 SQLite 环形缓冲(跨重启不丢,并支持导出本次会话完整存档),桥接 Flutter 官方 `MemoryAllocations` 作为泄漏检测第二来源,修复 App 空闲时 FPS 被误判为性能问题,并将 `InspectorService` 拆分为分类 notifier 缩小重建范围。建议所有用户升级到最新版本(`^1.9.0`)。
> **🔔 推荐升级:** 本次更新新增独立的 **Errors(异常聚合)** 标签页(按异常类型 / 堆栈去重,显示出现次数、首末次时间与可折叠堆栈),把日志 / 网络 / 异常落盘到插件自有的 `zero_inspector_kit.db` 数据库(磁盘环形缓冲,跨重启不丢,并支持导出本次会话完整存档),桥接 Flutter 官方 `MemoryAllocations` 作为泄漏检测第二来源,修复 App 空闲时 FPS 被误判为性能问题,并将 `InspectorService` 拆分为分类 notifier 缩小重建范围。建议所有用户升级到最新版本(`^1.9.0`)。

🌐 **[官方网站](https://www.zerolabsco.com/)**  ·  📦 **[在 pub.dev 查看](https://pub.dev/packages/zero_inspector_kit)**  ·  🔗 **[查看 GitHub 仓库](https://github.com/zero-labsco/zero_inspector_kit)**

Expand Down Expand Up @@ -60,7 +60,7 @@
- **WebSocket / gRPC 抓取**:可选的流式协议抓取(默认关闭,运行时开关,与 Memory/FPS 一致);WebSocket 帧与 gRPC 调用出现在 Network 列表中。
- **日志系统**:自动捕获 `print()`、`debugPrint()` 及自定义日志,支持多级别与第三方日志库集成;自动滚动(可暂停)、正则搜索、按标签过滤与单条日志一键复制。
- **异常监控**:独立的 Errors 标签页(v1.9.0 起):接管 `FlutterError.onError` + `runZonedGuarded`,按类型 + 堆栈签名去重聚合崩溃,记录次数与首末次时间;Errors 标签图标带红色计数。
- **会话持久化**:日志 / 网络 / 异常异步落盘到本地 SQLite 环形缓冲(v1.9.0 起);启动时日志与异常回放入各自标签页,网络请求留档供导出;可从面板头部导出完整会话存档并分享。
- **会话持久化**:日志 / 网络 / 异常异步写入插件自有的 `zero_inspector_kit.db` 数据库(v1.9.0 起;磁盘环形缓冲,也会出现在 Database 标签页);启动时日志与异常回放入各自标签页,网络请求留档供导出;可从面板头部导出完整会话存档并分享。
- **数据库查看器**:支持 SQLite 及其他数据库,可自定义提供者。
- **内存监控**:趋势图、Dart Heap、Native 内存分项、泄漏检测、图片缓存与存储统计(总开关避免开销)。v1.9.0 起泄漏检测额外桥接 Flutter 官方 `FlutterMemoryAllocations`,降低误报。
- **FPS 监控**:实时帧率、掉帧检测、趋势图、帧记录(总开关避免开销)。
Expand Down Expand Up @@ -263,7 +263,7 @@ ErrorService.instance.clear();

> v1.9.0 起可用

日志、网络请求与聚合异常会被异步写入本地 SQLite **环形缓冲**。**下次启动时,日志与聚合异常会回放入各自标签页**;网络请求保留在磁盘存档,供之后导出。因此即使从未打开过面板,数据也能跨重启保留。点击面板头部的**存储图标**打开 **Persisted data** 管理弹层:查看各类别行数、导出**完整会话存档** JSON(系统分享)或清空磁盘。
日志、网络请求与聚合异常会被异步写入插件自有的数据库文件 **`zero_inspector_kit.db`**——一个基于 SQLite 的磁盘环形缓冲,也会出现在 **Database** 标签页中。**下次启动时,日志与聚合异常会回放入各自标签页**;网络请求保留在磁盘存档,供之后导出。因此即使从未打开过面板,数据也能跨重启保留。点击面板头部的**存储图标**打开 **Persisted data** 管理弹层:查看各类别行数、导出**完整会话存档** JSON(系统分享)或清空磁盘。

```dart
// 编程方式读取持久化数据(可选)
Expand Down
2 changes: 1 addition & 1 deletion docs/404.html
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><title>404: This page could not be found</title><meta name="next-head-count" content="3"/><link rel="preload" href="/zero_inspector_kit/_next/static/css/df9fc72061aac7da.css" as="style"/><link rel="stylesheet" href="/zero_inspector_kit/_next/static/css/df9fc72061aac7da.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/zero_inspector_kit/_next/static/chunks/polyfills-42372ed130431b0a.js"></script><script src="/zero_inspector_kit/_next/static/chunks/webpack-ad90bb3f37d3ab33.js" defer=""></script><script src="/zero_inspector_kit/_next/static/chunks/framework-64ad27b21261a9ce.js" defer=""></script><script src="/zero_inspector_kit/_next/static/chunks/main-f5dfbda958d94c6d.js" defer=""></script><script src="/zero_inspector_kit/_next/static/chunks/pages/_app-ec27bf27c476d146.js" defer=""></script><script src="/zero_inspector_kit/_next/static/chunks/pages/_error-7a92967bea80186d.js" defer=""></script><script src="/zero_inspector_kit/_next/static/kaoZsUOFM1gb934rEE05N/_buildManifest.js" defer=""></script><script src="/zero_inspector_kit/_next/static/kaoZsUOFM1gb934rEE05N/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div style="line-height:48px"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">This page could not be found<!-- -->.</h2></div></div></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"statusCode":404}},"page":"/_error","query":{},"buildId":"kaoZsUOFM1gb934rEE05N","assetPrefix":"/zero_inspector_kit","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
<!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><title>404: This page could not be found</title><meta name="next-head-count" content="3"/><link rel="preload" href="/zero_inspector_kit/_next/static/css/df9fc72061aac7da.css" as="style"/><link rel="stylesheet" href="/zero_inspector_kit/_next/static/css/df9fc72061aac7da.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/zero_inspector_kit/_next/static/chunks/polyfills-42372ed130431b0a.js"></script><script src="/zero_inspector_kit/_next/static/chunks/webpack-ad90bb3f37d3ab33.js" defer=""></script><script src="/zero_inspector_kit/_next/static/chunks/framework-64ad27b21261a9ce.js" defer=""></script><script src="/zero_inspector_kit/_next/static/chunks/main-f5dfbda958d94c6d.js" defer=""></script><script src="/zero_inspector_kit/_next/static/chunks/pages/_app-ec27bf27c476d146.js" defer=""></script><script src="/zero_inspector_kit/_next/static/chunks/pages/_error-7a92967bea80186d.js" defer=""></script><script src="/zero_inspector_kit/_next/static/5xlj4W9hOwjCugd1ovAY-/_buildManifest.js" defer=""></script><script src="/zero_inspector_kit/_next/static/5xlj4W9hOwjCugd1ovAY-/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div style="line-height:48px"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">This page could not be found<!-- -->.</h2></div></div></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"statusCode":404}},"page":"/_error","query":{},"buildId":"5xlj4W9hOwjCugd1ovAY-","assetPrefix":"/zero_inspector_kit","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
2 changes: 1 addition & 1 deletion docs/404/index.html
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><title>404: This page could not be found</title><meta name="next-head-count" content="3"/><link rel="preload" href="/zero_inspector_kit/_next/static/css/df9fc72061aac7da.css" as="style"/><link rel="stylesheet" href="/zero_inspector_kit/_next/static/css/df9fc72061aac7da.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/zero_inspector_kit/_next/static/chunks/polyfills-42372ed130431b0a.js"></script><script src="/zero_inspector_kit/_next/static/chunks/webpack-ad90bb3f37d3ab33.js" defer=""></script><script src="/zero_inspector_kit/_next/static/chunks/framework-64ad27b21261a9ce.js" defer=""></script><script src="/zero_inspector_kit/_next/static/chunks/main-f5dfbda958d94c6d.js" defer=""></script><script src="/zero_inspector_kit/_next/static/chunks/pages/_app-ec27bf27c476d146.js" defer=""></script><script src="/zero_inspector_kit/_next/static/chunks/pages/_error-7a92967bea80186d.js" defer=""></script><script src="/zero_inspector_kit/_next/static/kaoZsUOFM1gb934rEE05N/_buildManifest.js" defer=""></script><script src="/zero_inspector_kit/_next/static/kaoZsUOFM1gb934rEE05N/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div style="line-height:48px"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">This page could not be found<!-- -->.</h2></div></div></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"statusCode":404}},"page":"/_error","query":{},"buildId":"kaoZsUOFM1gb934rEE05N","assetPrefix":"/zero_inspector_kit","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
<!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><title>404: This page could not be found</title><meta name="next-head-count" content="3"/><link rel="preload" href="/zero_inspector_kit/_next/static/css/df9fc72061aac7da.css" as="style"/><link rel="stylesheet" href="/zero_inspector_kit/_next/static/css/df9fc72061aac7da.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/zero_inspector_kit/_next/static/chunks/polyfills-42372ed130431b0a.js"></script><script src="/zero_inspector_kit/_next/static/chunks/webpack-ad90bb3f37d3ab33.js" defer=""></script><script src="/zero_inspector_kit/_next/static/chunks/framework-64ad27b21261a9ce.js" defer=""></script><script src="/zero_inspector_kit/_next/static/chunks/main-f5dfbda958d94c6d.js" defer=""></script><script src="/zero_inspector_kit/_next/static/chunks/pages/_app-ec27bf27c476d146.js" defer=""></script><script src="/zero_inspector_kit/_next/static/chunks/pages/_error-7a92967bea80186d.js" defer=""></script><script src="/zero_inspector_kit/_next/static/5xlj4W9hOwjCugd1ovAY-/_buildManifest.js" defer=""></script><script src="/zero_inspector_kit/_next/static/5xlj4W9hOwjCugd1ovAY-/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div style="line-height:48px"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">This page could not be found<!-- -->.</h2></div></div></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"statusCode":404}},"page":"/_error","query":{},"buildId":"5xlj4W9hOwjCugd1ovAY-","assetPrefix":"/zero_inspector_kit","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
4 changes: 2 additions & 2 deletions docs/Alerts/index.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/Configuration/index.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/Custom-Database-Provider/index.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/Database-Viewer/index.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/Errors/index.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/FAQ/index.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/FPS-Viewer/index.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/Getting-Started/index.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/Installation/index.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/Log-Viewer/index.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/Memory-Viewer/index.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/Network-Inspector/index.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/Route-Tracker/index.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/Usage/index.html

Large diffs are not rendered by default.

Loading
Loading