Token导航 LogoToken导航TokenDH.com
log pilot logo
开发工具未说明官方级别未说明来源级核验

log pilot

MCP Server

LogPilot是一款专为Flutter应用设计的日志工具,支持实时日志查询、过滤和AI代理访问,适用于开发调试和错误跟踪。

工具数

8

提示词数

0

GitHub Stars

4

资源数

0
日志记录JavaScriptClaude开发工具ClaudeCursorWindsurf

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

作者 / 组织

MojtabaTavakkoli

提供方

MojtabaTavakkoli

最后核验

2026/5/17 20:22

快速接入

先看主来源和安装命令,再打开仓库或文档;下面只保留这个条目的关键接入事实。

详细介绍

LogPilot

](https://pub.dev/packages/log_pilot) ![license](LICENSE) ![Dart](https://dart.dev) ![Flutter](https://flutter.dev)

第一个为AI代理构建的Flutter日志包。

LogPilot为AI编码代理(Cursor、Claude Code、Windsurf、Copilot、, Gemini CLI)通过 MCP服务器DevTools扩展 --没有手动复制粘贴,没有过时的终端输出。 代理可以在运行时查询、过滤、监视和更改日志级别,而您 代码。

它还可以完成您对记录器的所有期望——非常漂亮的控制台输出, 结构化元数据、接收器、文件日志记录、面包屑——但 差异化因素是 代理优先架构:您的AI助手会看到 您的应用程序实时看到的内容。

LogPilot Banner

void main() {
  LogPilot.init(child: const MyApp());
}

// Anywhere in your app:
LogPilot.info('User signed in', metadata: {'userId': '123'});
LogPilot.error('Payment failed', error: e, stackTrace: st);

______________________________________________________________________

对于AI代理

如果您是AI编码代理,请阅读此自述文件,本节给出 你需要的一切。README的其余部分是为人类开发人员准备的。

设置

该应用程序已经依赖于 log_pilot.使用 LogPilot 对于所有日志记录,从不 原始 print()debugPrint().

import 'package:log_pilot/log_pilot.dart';

日志API

LogPilot.verbose('Starting sync...');
LogPilot.debug('Cache key: user_42');
LogPilot.info('Order placed', metadata: {'orderId': 'ORD-456', 'total': 29.99});
LogPilot.warning('Retry attempt 3/5');
LogPilot.error('Checkout failed', error: e, stackTrace: st);
LogPilot.fatal('Database corrupted');

每种方法都接受可选 error, stackTrace, metadata (地图),以及 tag (字符串)。总是通过 error + stackTrace 一起出错/致命。

范围记录仪

class AuthService {
  static const _log = LogPilotLogger('AuthService');

  Future signIn(String email) async {
    _log.info('Attempting sign in', metadata: {'email': email});
    try {
      await _auth.signIn(email);
      _log.info('Sign in successful');
    } catch (e, st) {
      _log.error('Sign in failed', error: e, stackTrace: st);
    }
  }
}

查询日志(进程中)

LogPilot.history;                                       // all records
LogPilot.historyWhere(level: LogLevel.error);            // filter by level
LogPilot.historyWhere(tag: 'http', hasError: true);      // filter by tag + error
LogPilot.export(format: ExportFormat.json);              // NDJSON export
LogPilot.exportForLLM(tokenBudget: 2000);                // compressed for LLM context
LogPilot.snapshot();                                     // structured diagnostic summary
LogPilot.setLogLevel(LogLevel.verbose);                  // increase verbosity at runtime

查询日志(通过MCP)

如果配置了LogPilot MCP服务器,您可以直接调用这些工具:

MCP工具它的作用
get_snapshot会话ID、配置、错误计数、最近日志、活动计时器
query_logs按级别、标签、消息、跟踪ID、错误存在、元数据键进行筛选
export_logs完整历史记录为文本或NDJSON
export_for_llm针对您的上下文窗口优化的压缩摘要
set_log_level在运行时更改冗长程度,而无需重新启动
get_log_level读取当前最低电平
clear_logs清除内存历史记录
watch_logs将新条目作为推送通知流式传输(可过滤)
stop_watch停止活动观察者

设置MCP服务器

您必须完成以下所有步骤。 MCP服务器将不会出现在 直到开发人员完成步骤4。不要跳过前面-- 在完全完成设置之前,您无法使用LogPilot MCP工具。

先决条件: 应用程序必须调用 LogPilot.init()LogPilot.configure() --两者都在MCP中注册服务扩展 服务器需要。如果使用 configure() (例如,用于Firebase/异步启动), MCP的工作方式完全相同。

步骤1-3是您(代理)执行的操作。步骤4需要 开发者——你必须问他们并等待。

  1. 安装MCP服务器。 两个选项——选择一个:

选项1——全局激活(推荐,适用于所有地方):

   dart pub global activate log_pilot_mcp

选项2——开发人员依赖关系(仅限于您的应用程序):

   dart pub add --dev log_pilot_mcp
  1. 确保Flutter应用程序在调试模式下运行。 自动发现

要求应用程序正在运行,以便它可以写入VM服务URI。 如果应用程序未运行,请让开发人员运行 flutter run 第一。 开 安卓/iOS,无法从设备自动发现-- 使用 --project-root 在MCP配置中或要求开发人员运行 log_pilot_mcp write-uri 从主机。

> 代理:更喜欢全局激活。 它避免了工作目录 > 问题-- dart run log_pilot_mcp 仅在目录中工作 > 里面有包裹 pubspec.yaml,但IDE可能会启动MCP > 来自不同目录的服务器。

  1. 在调试模式下运行Flutter应用程序 (如果尚未运行):
   flutter run

应用程序必须正在运行,以便LogPilot可以写入VM服务URI。 对于 Flutter Web,注意 ws://... 调试中打印的URI 控制台——您将在步骤3中需要它。

  1. 编写MCP配置文件。

检测IDE并写入正确的位置:

IDE配置文件
光标.cursor/mcp.json 在工作区根目录中
VS代码(副本).vscode/mcp.json 在工作区根目录中
风帆冲浪~/.codeium/windsurf/mcp_config.json
克劳德代码~/.claude/mcp.json
Gemini CLI~/.gemini/settings.json

使用以下逻辑构建JSON:

命令: 关于macOS/Linux的使用 "log_pilot_mcp"。在Windows上使用 绝对路径 "C:\\Users\\\\AppData\\Local\\Pub\\Cache\\bin\\log_pilot_mcp.bat". 如果您使用开发依赖项而不是全局激活,请使用 "dart"["run", "log_pilot_mcp"] 作为args。

Args——只添加需要的内容:

- 窗户: 添加 "--project-root=" - Flutter Web: 添加 "--vm-service-uri=" (每次重新启动时都会更改) - 开发人员依赖关系不在工作区根目录: 添加 "cwd": " " 在服务器级别

典型结果(全局激活,Windows):

   {
     "mcpServers": {
       "LogPilot": {
         "command": "C:\\Users\\you\\AppData\\Local\\Pub\\Cache\\bin\\log_pilot_mcp.bat",
         "args": ["--project-root=C:/Users/you/my-flutter-app"]
       }
     }
   }

典型结果(全局激活,macOS/Linux):

   {
     "mcpServers": {
       "LogPilot": {
         "command": "log_pilot_mcp",
         "args": []
       }
     }
   }

如果配置文件已存在,请合并到现有 mcpServers --做 覆盖其他服务器。

  1. 要求开发人员重新加载IDE窗口并启用LogPilot。

IDE在重新加载之前不会发现新的MCP服务器。请问 开发人员重新加载窗口,在MCP设置中打开LogPilot,如果 需要,并确认绿色/连接指示器。然后打电话 get_snapshot 以验证连接。

代理人规则

  • 总是通过 error + stackTrace 错误/致命呼叫。
  • 使用 tag: 对于每个域(Auth, Cart, API, DB, Nav等等)。
  • 更喜欢 metadata: 映射字符串插值。
  • 使用 const LogPilotLogger('Tag') 在自动标记的课堂上。
  • 永远不要用空的catch块来消除错误——记录它们。

将此块复制到项目的代理指令文件中(例如。 AGENTS.md, GEMINI.md, CLAUDE.md,或IDE的规则目录) 为了正确的代理行为。

______________________________________________________________________

目录

______________________________________________________________________

MCP服务器

log_pilot_mcp 该软件包是一个独立的MCP服务器,为AI编码代理提供实时服务, 双向访问正在运行的Flutter应用程序的日志。无终端 抓取——代理通过模型上下文协议调用结构化工具。 全局安装(dart pub global activate log_pilot_mcp)或作为a dev依赖性(dart pub add --dev log_pilot_mcp).

运作原理

+----------------+                    +------------------+
|  Flutter App   | -- VM Service ---> |  log_pilot_mcp   |
|  (debug mode)  | +------------------+
  1. 当你的Flutter应用程序在调试模式下启动时, LogPilot.init()

LogPilot.configure() 寄存器 ext.LogPilot.* 服务扩展 在Dart VM上,并将VM服务URI写入 .dart_tool/log_pilot_vm_service_uri.

  1. MCP服务器监视该文件,自动发现URI并连接。
  2. AI代理调用MCP工具(get_snapshot, query_logs等等)

服务器转换为正在运行的应用程序上的服务扩展调用。

  1. 在热重启时,VM扩展重新注册,服务器

自动重新连接。完全重新启动时,URI文件会更新,服务器也会更新 几秒钟内重新连接,无需手动操作。

设置

  1. 安装: dart pub global activate log_pilot_mcp (或 dart pub add --dev log_pilot_mcp)
  2. 运行您的应用程序: flutter run
  3. 将LogPilot添加到IDE的MCP配置中
  4. 重新加载IDE窗口并打开LogPilot

对于 根据IDE说明进行详细说明 (光标、VS代码、风帆、克劳德代码、, 反重力,Gemini CLI),请参阅 log_pilot_mcp 自述文件.

自动发现

LogPilot将Dart VM WebSocket URI写入 .dart_tool/log_pilot_vm_service_uri 每次你的应用程序在调试中启动时 模式。MCP服务器:

  • 启动时读取文件
  • 监视更改(文件系统监视器)
  • 如果文件还不存在(服务器在应用程序之前启动),则等待它

出现

  • 热重启时:隔离回收、扩展重新注册、服务器检测

隔离事件,并在下次工具调用时重新解析

  • 完全重启时:URI更改、文件更新,服务器检测到更改

在观察间隔内重新连接

不需要手动复制URI 在正常的桌面工作流程中。

安卓/iOS: 该应用程序在设备上运行,无法写入主机的 .dart_tool 目录。在主机上使用以下方法之一:

  1. write-uri 命令 --复制 ws://... 来自调试控制台的URI

并运行: log_pilot_mcp write-uri ws://127.0.0.1:PORT/TOKEN=/ws (添加 --project-root= 如果需要)。MCP服务器的文件 监视器检测到更改并自动重新连接。

  1. --project-root --添加 --project-root=

MCP服务器args,以便它知道在哪里监视URI文件。

Flutter Web: 自动发现在web上不起作用(否 dart:io).你 必须手动传递VM服务URI——它在每次应用程序重启时都会发生变化。 最简单的方法是复制 ws://... Flutter调试中的URI 控制台并更新 --vm-service-uri MCP配置中的参数。

log_pilot_mcp 仓库 提供了可选的帮助脚本(bash+PowerShell),可以自动执行此操作 解析捕获 flutter run 输出。 注: 这些脚本取决于 Flutter控制台输出的确切格式,可能需要调整 跨Flutter SDK版本。

如果桌面上的自动发现失败 (例如。, .dart_tool 不在 预期位置,或应用程序的工作目录与项目不同 Windows上的root),您有两个回退选项:

  1. 传递项目根 --添加

--project-root=args 数组因此 服务器知道在哪里可以找到 .dart_tool/log_pilot_vm_service_uri.

  1. 手动传递URI --复制 ws://... Flutter的URI

调试控制台并添加 --vm-service-uri=ws://127.0.0.1:PORT/TOKEN=/wsargs 数组in mcp.json.

代理人可以做什么

工具它做什么
get_snapshot结构化摘要:会话ID、配置、历史计数、最近错误、活动计时器。支持 group_by_tag 用于每个标签的细分。
query_logs按级别、标记、消息文本、跟踪ID、错误存在、元数据键进行筛选。 deduplicate: true 折叠重复的条目,同时保留不同的呼叫站点。
export_logs完整历史记录为人类可读文本或NDJSON。
export_for_llm针对LLM上下文窗口优化的压缩摘要--对错误进行优先级排序、重复数据消除、截断冗长条目。
set_log_level / get_log_level在运行时更改或读取详细信息。曲柄转动至 verbose 对于调试,请返回 warning 当完成时。
clear_logs擦除内存历史记录。
watch_logs将新条目作为MCP推送通知进行流式传输。按标签和级别过滤。
stop_watch停止观察并获取交付摘要。
资源内容
LogPilot://config当前LogPilotConfig为JSON格式
LogPilot://session会话ID和活动跟踪ID
LogPilot://tail来自活动观察者的最新批次(可订阅)

代理调试工作流

  1. get_snapshot --查看发生了什么(错误、配置、计时器)
  2. set_log_level(level: "verbose") --增加细节
  3. *重现该问题*
  4. query_logs(level: "error", deduplicate: true) --找出根本原因
  5. export_for_llm(token_budget: 2000) --获取压缩上下文进行分析
  6. set_log_level(level: "warning") --恢复安静模式

克劳德代码/终端使用

Flutter Web 没有 dart:io,所以自动发现不可用——你 必须通过 --vm-service-uri 手动。请参阅 log_pilot_mcp Flutter Web文档 有关详细信息和辅助脚本。

如果自动发现在本机上失败 (例如Windows cwd不匹配),添加 --project-root= 到MCP服务器args,或传递 --vm-service-uri 直接。

问题解决方案
服务器在IDE的MCP设置中显示“已禁用”切换开关 手动。大多数IDE默认禁用新服务器。
服务器未出现在MCP设置中创建/编辑MCP配置文件后重新加载IDE窗口。
Could not find package "log_pilot_mcp"快跑 dart pub add --dev log_pilot_mcp 首先在应用程序的目录中。
Failed to connect to VM service应用程序未在调试模式下运行,或者URI已过时。先启动应用程序。
未创建自动发现文件在Windows上,应用程序的工作目录可能与项目根目录不匹配。在Android/iOS上,设备无法写入主机。通过 --project-root=,使用 log_pilot_mcp write-uri ,或 --vm-service-uri 手动。
热重启后工具失败下次调用时自动恢复。如果这种情况持续存在,则VM端口发生了变化(完全重新启动)——URI文件监视器会处理这一点。
服务器已连接,但工具返回错误应用程序必须 import 'package:log_pilot/log_pilot.dart' 因此,库已加载。

请参阅 log_pilot_mcp 自述文件 完整的MCP工具参考、参数表、调试工作流程, 以及故障排除指南。

______________________________________________________________________

DevTools扩展

DevTools Extension

零配置 --添加 log_pilot 作为依赖和a LogPilot 标签 自动出现在Dart DevTools中。

  • 带有颜色编码级别徽章、标签、时间戳和呼叫者位置的实时日志表
  • 液位过滤器 下拉菜单+ 标签过滤器 下拉菜单+自由文本搜索
  • 自动滚动,手动超控
  • 工具栏:刷新、清除、设置日志级别、导出(文本/JSON)、快照
  • 详细视图:完整消息、元数据JSON树、错误+堆栈跟踪、错误ID、面包屑时间线,并复制到剪贴板
  • 适用于所有平台,包括Flutter Web(使用VM服务扩展,而不是表达式求值)

|按级别+标签筛选|包含元数据和面包屑的详细信息| |:-:|:-:| | DevTools Table | DevTools Detail |

______________________________________________________________________

应用内日志查看器

In-App Log Viewer

MaterialApp(
  builder: (context, child) => LogPilotOverlay(child: child!),
  home: const MyHome(),
)

A. 可拖动、可调整大小的底板 具有完整的调试功能:

  • 在25%、50%、75%和全屏时捕捉点
  • 液位过滤器芯片 (全部、详细、调试、信息、警告、错误、致命)
  • 标签过滤器芯片 --从记录的记录中动态生成
  • 跨消息、标签和级别的文本搜索
  • 记录详细视图 --点击任何条目以获取完整元数据、错误、堆栈跟踪,

面包屑、调用者、会话/跟踪/错误ID,并复制到剪贴板

  • 自动滚动切换
  • 将完整历史记录复制为文本或NDJSON
  • 清除历史记录按钮

汽车正在生产中。覆盖 LogPilotOverlay(enabled: true). 控制FAB位置: LogPilotOverlay(entryButtonAlignment: Alignment.bottomLeft).

|叠加列表视图|记录详细信息视图| |:-:|:-:| | Overlay List | Overlay Detail |

______________________________________________________________________

LLM出口

压缩日志历史记录以适应LLM的上下文窗口:

final summary = LogPilot.exportForLLM(tokenBudget: 2000);

该算法对错误进行优先级排序,对连续的相同错误进行重复数据消除 消息,截断详细条目,并用以下内容填充剩余预算 最近的记录。默认预算为4000个令牌(约16k个字符)。

也可通过MCP获得: export_for_llm 工具接受 token_budget 参数,并将压缩的摘要直接返回给代理。

______________________________________________________________________

快速开始

安装

dependencies:
  log_pilot: ^1.1.0-beta.1

选择您的设置级别

LogPilot提供四种设置选项。 选择一个:

设置功能您调用 runApp()MCP/DevTools?
选项A: LogPilot.init()完整设置——错误区域、错误捕获、日志记录。 替换 runApp().没有-- init() 称之为
选项B: LogPilot.configure()配置+服务扩展。 没有错误区域,没有自动错误捕获。
选项C: Firebase/异步启动configure() 在你自己的 runZonedGuarded最适合之前使用异步初始化的应用程序 runApp()
选项D: Zero setupNo init--在调试模式下使用默认值。

init() 对比 configure()

能力init()configure()
控制台日志记录
配置预设(.debug(), .production()等)
日志历史记录/环形缓冲区
服务扩展(MCP+DevTools)
用于自动发现的VM URI文件
日志汇
面包屑
FlutterError.onError 处理程序 --你管理它
PlatformDispatcher.onError 处理程序 --你管理它
runZonedGuarded (未捕获的异步错误) --你管理它
错误级联抑制
onError 回调(适用于Crashlytics/Sentry) --使用水槽或自己的区域
选项D(零点设置) 仅为您提供默认的控制台日志记录-- 没有服务扩展、历史记录、接收器或面包屑。

______________________________________________________________________

选项A: LogPilot.init() --完整设置 *(建议用于简单应用程序)*

init() 电话 runApp() 内部。 也称为 runApp() --这样做会导致双重初始化错误。
import 'package:flutter/material.dart';
import 'package:log_pilot/log_pilot.dart';

void main() {
  LogPilot.init(child: const MyApp());
}

此自动捕获每个Flutter错误、平台错误和未捕获区域 例外情况。它还为DevTools和MCP注册服务扩展。

随着崩溃报告转发:

void main() {
  LogPilot.init(
    config: LogPilotConfig.debug(),
    onError: (error, stack) {
      FirebaseCrashlytics.instance.recordError(error, stack);
    },
    child: const MyApp(),
  );
}
限制: init() 电话 WidgetsFlutterBinding.ensureInitialized()runApp() 在自己的区域内。如果你需要运行异步代码 之前 runApp() (例如。 Firebase.initializeApp()),使用选项B 或者改为C。

选项B: LogPilot.configure() --配置+扩展,您可以处理错误

需要时使用此功能 LogPilot 日志记录和MCP/DevTools,但希望 自己管理错误处理。 configure() 注册服务 扩展名和VM URI文件,但确实如此 设置错误区域, FlutterError.onError,或 PlatformDispatcher.onError.
void main() {
  WidgetsFlutterBinding.ensureInitialized();
  LogPilot.configure(config: LogPilotConfig(logLevel: LogLevel.info));
  runApp(const MyApp());
}

选项C:Firebase/Crashlytics/异步启动 *(建议用于生产应用程序)*

这是最常见的生产模式——调用 Firebase.initializeApp(),设置Crashlytics,或执行其他异步工作 之前 runApp().使用 configure() 在你自己的 runZonedGuarded.
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
import 'package:log_pilot/log_pilot.dart';

void main() {
  runZonedGuarded>(() async {
    WidgetsFlutterBinding.ensureInitialized();

    // Configure LogPilot first — registers service extensions for
    // MCP and DevTools, and writes the VM URI for auto-discovery.
    LogPilot.configure(config: LogPilotConfig.debug());

    await Firebase.initializeApp();
    await FirebaseCrashlytics.instance
        .setCrashlyticsCollectionEnabled(!kDebugMode);

    FlutterError.onError = (details) {
      LogPilot.error(
        'Flutter error: ${details.summary}',
        error: details.exception,
        stackTrace: details.stack,
      );
      FirebaseCrashlytics.instance.recordFlutterError(details);
    };

    runApp(const MyApp());
  }, (error, stack) {
    LogPilot.error('Uncaught', error: error, stackTrace: stack);
    FirebaseCrashlytics.instance.recordError(error, stack);
  });
}
为什么 configure() 而不是 init()? init() 电话 ensureInitialized()runApp() 在它自己的区域内——你不能 跑 await Firebase.initializeApp() 在两者之间。 configure() 给予 您可以完全控制绑定初始化、异步设置、错误区域, 和 runApp() 定时,同时仍在注册服务扩展 MCP和DevTools所需。

选项D:零设置

LogPilot.info('Hello world'); // no init needed in debug mode
注: Zero设置仅提供基本的控制台日志记录。服务 扩展(MCP工具和DevTools所需)、日志历史、接收器、, 面包屑都需要 LogPilot.init()LogPilot.configure().

______________________________________________________________________

控制台输出

LogPilot将每个日志包装在一个带有级别、时间戳、, 可点击的呼叫者位置和您的消息:

Console Output — Pretty Format

有三种输出模式可供选择:

模式用例示例
OutputFormat.prettyIDE中的人(默认)框边,彩色
OutputFormat.plainAI代理/CI`[INFO] [auth] User signed in \{"userId": "123"}`
OutputFormat.json结构化管道{"level":"INFO","timestamp":"...","message":"..."}

|漂亮|普通| NDJSON| |:-:|:-:|:-:| | Pretty | Plain | NDJSON |

______________________________________________________________________

日志消息

每种方法都支持可选 error, stackTrace, metadata,以及 tag:

LogPilot.verbose('Starting sync...');
LogPilot.debug('Cache key: user_42');
LogPilot.info('Order placed', metadata: {'orderId': 'ORD-456', 'total': 29.99});
LogPilot.warning('Retry attempt 3/5');
LogPilot.error('Checkout failed', error: e, stackTrace: st);
LogPilot.fatal('Database corrupted');

|详细|信息+元数据| |:-:|:-:| | Verbose | Info |

|错误+堆栈跟踪+面包屑|致命| |:-:|:-:| | Error | Fatal |

______________________________________________________________________

JSON漂亮打印

LogPilot.json('{"users": [{"id": 1, "name": "Alice"}]}');

关键帧和值以不同的颜色渲染。自定义 jsonKeyColorjsonValueColor 在配置中。

JSON Highlighting

______________________________________________________________________

作用域实例记录器

创建一个 LogPilotLogger 对于类级日志记录,每个日志都是自动生成的 标记:

class AuthService {
  // LogPilotLogger has a const constructor for compile-time constant loggers:
  static const _log = LogPilotLogger('AuthService');
  // Or use the convenience factory: LogPilot.create('AuthService')

  Future signIn(String email) async {
    _log.info('Attempting sign in', metadata: {'email': email});
    try {
      await _auth.signIn(email);
      _log.info('Sign in successful');
    } catch (e, st) {
      _log.error('Sign in failed', error: e, stackTrace: st);
    }
  }
}

所有实例方法都接受可选 tag: override——提供时 替换该单个调用的实例标签。这使得静态和 实例API完全兼容: _log.info('msg', tag: 'http') 作用于 两者都没有代码更改。

作用域记录器还为计时器标签添加前缀: _log.time('query') 生产 AuthService/query.

______________________________________________________________________

网络日志记录

超文本传输协议 拦截器内置于已发布的包中:

import 'package:log_pilot/log_pilot.dart';

final client = LogPilotHttpClient();
final response = await client.get(Uri.parse('https://api.example.com/users'));

Network Logging

响应日志级别由HTTP状态代码设置:5xx-> error,4xx-> warning,2xx/3xx-> info.

LogPilotHttpClient(
  logRequestHeaders: true,
  logRequestBody: true,
  logResponseHeaders: false,
  logResponseBody: true,        // opt-in (default: false)
  maxResponseBodySize: 4 * 1024, // truncate after 4 KB
  injectSessionHeader: true,     // adds X-LogPilot-Session / X-LogPilot-Trace
  createRecords: true,           // creates LogPilotRecord entries in history
)

根据状态代码覆盖级别:

LogPilotHttpClient(
  logLevelForStatus: (status) =>
      status == 429 ? LogLevel.error : LogPilotHttpClient.defaultLogLevelForStatus(status),
)

从历史记录中查询网络错误:

final httpErrors = LogPilot.historyWhere(tag: 'http', hasError: true);
Dio、Chopper、GraphQL和BLoC集成将无法导入 如果 你是从pub.dev安装的。这些桶是 .pubignored只有 存在于 源代码仓库. 现在使用它们: 将源文件从仓库复制到项目中 (例如。 lib/src/network/log_pilot_dio_interceptor.dart).独立 包裹(log_pilot_dio, log_pilot_bloc等等)。

______________________________________________________________________

原木水槽

将日志记录与控制台输出一起路由到任何目标:

LogPilot.init(
  config: LogPilotConfig(
    sinks: [
      CallbackSink((record) {
        FirebaseCrashlytics.instance.log(record.message ?? '');
      }),
    ],
  ),
  child: const MyApp(),
);

灭火 即使控制台输出关闭 (enabled: false),制造 它们非常适合生产。实施 LogSink 对于自定义水槽:

class RemoteSink implements LogSink {
  @override
  void onLog(LogPilotRecord record) {
    httpClient.post(apiUrl, body: record.toJsonString());
  }

  @override
  void dispose() {}
}

选择合适的水槽

警告: CallbackSink 火灾 同步地 日志内部 调度管道。如果您的回拨更新了 ValueNotifier 或致电 setState(),您将在构建过程中使用“setState()”崩溃 BufferedCallbackSink 用于UI状态或将回调包裹在 scheduleMicrotask().
水槽交货最适合
CallbackSink同步,逐记录即发即弃:崩溃记者,分析
AsyncLogSink微任务批处理昂贵的I/O:HTTP上传、文件写入
BufferedCallbackSink定时器+基于大小的批处理UI状态——避免 setState-期间-build
// Microtask-batched
AsyncLogSink(flush: (records) {
  for (final r in records) { analyticsService.track(r.message ?? ''); }
})

// Timer + size-based
BufferedCallbackSink(
  maxBatchSize: 50,
  flushInterval: Duration(milliseconds: 500),
  onFlush: (batch) { setState(() => logRecords.addAll(batch)); },
)

每个水槽 onLog 一个破碎的水槽无法让管道安静下来。

______________________________________________________________________

文件记录

FileSink 自动旋转写入本地文件。 移动/桌面 仅 (要求 dart:io):

import 'dart:io';
import 'package:log_pilot/log_pilot.dart';
import 'package:log_pilot/log_pilot_io.dart';

final fileSink = FileSink(
  directory: Directory('/path/to/logs'),
  maxFileSize: 2 * 1024 * 1024,  // 2 MB per file
  maxFileCount: 5,
  format: FileLogFormat.text,     // or .json for NDJSON
  baseFileName: 'LogPilot',
);

LogPilot.init(
  config: LogPilotConfig(sinks: [fileSink]),
  child: const MyApp(),
);

// Export all logs for bug reports:
final allLogs = await fileSink.readAll();

______________________________________________________________________

配置预设

LogPilotConfig.debug()       // verbose, all details, colors on
LogPilotConfig.staging()     // info+, compact, 5s dedup window
LogPilotConfig.production(   // console off, warning+, sinks only
  sinks: [myCrashlyticsSink],
)
LogPilotConfig.web()         // info+, plain output, no caller capture, 5s dedup
工厂日志级别呼叫者详细信息重复数据删除历史记录/面包屑最适合
LogPilotConfig()verbose关闭500/20默认
.debug()verbose关闭500/20IDE开发
.staging()信息5s500/20QA构建
.production()警告5s500/20释放(控制台关闭)
.web()info5s200/10Flutter Web(也: stackTraceDepth: 4, maxPayloadSize: 4096)

______________________________________________________________________

标记日志和聚焦模式

LogPilot.info('Starting payment', tag: 'checkout');

// Only show specific tags during development:
LogPilotConfig(onlyTags: {'checkout', 'auth'})

______________________________________________________________________

速率限制/重复数据删除

在时间窗口内折叠相同的消息:

LogPilotConfig(deduplicateWindow: Duration(seconds: 5))

当相同的消息+级别重复时,只打印第一个。之后 在窗口中,将显示摘要:

│ RenderFlex overflowed by 42.0 pixels
│ ... repeated 47 times

重复数据删除适用于控制台输出和接收器调度。这 在记忆中,历史仍然会接收每一条记录。

______________________________________________________________________

日志历史记录/环形缓冲区

final records = LogPilot.history;
final errors  = LogPilot.historyWhere(level: LogLevel.error);
final text    = LogPilot.export();
final json    = LogPilot.export(format: ExportFormat.json);

LogPilot.clearHistory();

historyWhere 支持丰富的过滤功能——所有参数均与AND结合使用 逻辑。 level 参数是最小严重性筛选器,不是 完全匹配-- LogLevel.warning 返回警告、错误和致命信息:

LogPilot.historyWhere(
  level: LogLevel.warning,
  tag: 'http',
  messageContains: 'timeout',
  traceId: 'req-abc',
  hasError: true,
  after: DateTime.now().subtract(const Duration(minutes: 5)),
  before: DateTime.now(),
  metadataKey: 'statusCode',
);

配置缓冲区大小(默认值500,设置为0禁用):

LogPilotConfig(maxHistorySize: 1000)

______________________________________________________________________

会话和跟踪ID

每次应用程序启动都会获得一个唯一的会话UUID:

print(LogPilot.sessionId); // "a1b2c3d4-e5f6-4a7b-..."

对于每个请求的相关性,请使用作用域助手:

await LogPilot.withTraceId('req-12345', () async {
  await processPayment();   // all logs carry traceId 'req-12345'
  await sendReceipt();
});
// traceId is null here — even if processPayment threw

同步变体也可用:

final total = LogPilot.withTraceIdSync('calc-1', () => computeTotal(cart));

网络拦截器自动注入 X-LogPilot-SessionX-LogPilot-Trace 标题。

______________________________________________________________________

导航日志

自动记录每次路线转换:

MaterialApp(
  navigatorObservers: [LogPilotNavigatorObserver()],
)

定制:

LogPilotNavigatorObserver(
  logLevel: LogLevel.info,
  tag: 'Nav',
  logArguments: false, // hide sensitive route arguments
)

______________________________________________________________________

BLoC观察员

尚未发布 --此导入 将失败 如果您已安装 log_pilot 来自pub.dev。BLoC集成在 只有来源。 现在使用它: 复制 lib/src/state/log_pilot_bloc_observer.dart 在您的项目中,调整导入。独立 log_pilot_bloc 计划好了。

记录BLoC/Cubit生命周期事件:

// ⚠ REPO ONLY — this import does not work from the pub.dev package.
// See the note above for how to use this integration today.
import 'package:log_pilot/log_pilot_bloc.dart';

void main() {
  Bloc.observer = LogPilotBlocObserver();
  LogPilot.init(child: const MyApp());
}

定制:

LogPilotBlocObserver(
  tag: 'state',
  logEvents: true,
  logTransitions: true,
  logCreations: false,
  transitionLevel: LogLevel.debug,
)

______________________________________________________________________

性能计时

LogPilot.time('fetchUsers');
final users = await api.fetchUsers();
LogPilot.timeEnd('fetchUsers');  // logs: "fetchUsers: 342ms"

异常安全范围计时:

final users = await LogPilot.withTimer('fetchUsers', work: () => api.getUsers());
final config = LogPilot.withTimerSync('parseConfig', work: () => parse(raw));

多个计时器同时运行。范围记录器自动前缀:

final log = LogPilot.create('DB');
log.time('query');      // label: "DB/query"
log.timeEnd('query');   // logs: "DB/query: 12ms" with tag "DB"

timeCancel 删除计时器而不记录经过的时间。如果没有 匹配计时器存在,a verbose-记录级别提示以帮助检测 标签拼写错误或双重取消。注: timeEnd 日志在 warning 缺少计时器的级别,同时 timeCancel 日志在 verbose --这个 是故意的,因为 timeEnd 表示预期的测量值,即 失踪。

______________________________________________________________________

面包屑错误

每次错误前自动跟踪事件:

LogPilot.info('User tapped checkout', tag: 'UI');
LogPilot.info('Cart validated', tag: 'Cart');
LogPilot.error('Payment failed', error: e, stackTrace: st);
// ↑ Breadcrumbs for the 2 prior events are attached

手动面包屑:

LogPilot.addBreadcrumb('Button tapped', category: 'ui');
LogPilot.addBreadcrumb('Theme changed', category: 'state', metadata: {'theme': 'dark'});

配置: LogPilotConfig(maxBreadcrumbs: 30) (默认值为20,0表示禁用)。

______________________________________________________________________

错误ID

每个错误/致命日志都会收到一个基于哈希的确定性ID:

LogPilot.error('Network timeout', error: TimeoutException('connect'));
// Record includes: errorId: "lk-a1b2c3"

相同的错误签名在会话之间总是产生相同的ID。 数值变化被归一化——“索引5超出范围10”和 “索引3超出范围8”产生相同的ID。

______________________________________________________________________

敏感场遮蔽

LogPilotConfig(
  maskPatterns: [
    'password',              // substring — masks any key containing "password"
    '=accessToken',          // exact — masks only the key "accessToken"
    '~^(refresh|auth)_.*',   // regex — matches keys via RegExp
    'Authorization',
    'secret',
  ],
)
前缀匹配类型示例掩码
*(无)*变电站'token'accessToken, tokenExpiry, refresh_token
=精确密钥'=accessToken'accessToken 只有
~正则表达式'~^api_key$'api_key 只有

递归掩码适用于标头和嵌套的JSON正文。

______________________________________________________________________

错误静音

抑制控制台中已知的嘈杂错误——崩溃记者仍然会收到这些错误:

LogPilotConfig(silencedErrors: {'RenderFlex overflowed', 'HTTP 404'})

______________________________________________________________________

运行时日志级别覆盖

在不编辑代码或重新启动的情况下更改详细程度:

LogPilot.setLogLevel(LogLevel.verbose); // crank up for debugging
// ... reproduce the issue ...
LogPilot.setLogLevel(LogLevel.warning); // quiet down

______________________________________________________________________

延迟消息评估

LogPilot.debug(() => 'Cache: ${cache.entries.map((e) => e.key).join(", ")}');

只有当调试级别处于活动状态时,才会调用闭包。

______________________________________________________________________

仪器助手

使用自动计时、结果记录和错误捕获来包装任何表达式:

final config = LogPilot.instrument('parseConfig', () => parseConfig(raw));
final users = await LogPilot.instrumentAsync('fetchUsers', () => api.getUsers());

关于成功:登录 debug 返回值和经过的时间。 失败时:登录 error 使用异常和堆栈跟踪级别,然后重新抛出。

______________________________________________________________________

自我诊断

监控LogPilot自身的性能并自动降低冗长程度 当吞吐量达到峰值时:

LogPilot.enableDiagnostics(
  autoDegrade: true,
  throughputThreshold: 50, // records per second before degrading
);

final snap = LogPilot.diagnostics?.snapshot;
// LogPilotDiagnosticsSnapshot(records: 142, avgSinkLatency: 34us, ...)

LogPilot.disableDiagnostics();

当吞吐量超过阈值时,最小日志级别为 自动提升至 warning,通过过滤来减少冗长 详细/调试/信息消息。当吞吐量降至一半以下时 阈值,恢复到原始水平。

______________________________________________________________________

Crash Reporter集成

使用 init()s onError 简单应用程序的回调,或 configure() 里面 你自己的 runZonedGuarded 用于Firebase/async-启动。看 选项A选项C 在快速入门中查看完整的代码示例。

______________________________________________________________________

诊断快照

最近LogPilot活动的一个结构化摘要:

final snap = LogPilot.snapshot();
// Returns Map with: sessionId, traceId, config, history counts,
// recentErrors (last 5), recentLogs (last 10), activeTimers

final jsonStr = LogPilot.snapshotAsJson();

按标签对最近的日志进行分组:

final snap = LogPilot.snapshot(groupByTag: true, perTagLimit: 3);
// snap['recentByTag']['Auth'] -> {total: 15, recent: [...last 3...]}

______________________________________________________________________

网络平台

地心末日 package:log_pilot/log_pilot.dart 完全与网络兼容--零 dart:io 附属国。所有功能都适用于Flutter Web:

  • 控制台输出、日志历史、导航观察器、计时
  • 应用内日志查看器覆盖
  • 网络日志记录 LogPilotHttpClient
  • DevTools扩展
  • BLoC观察者(仅限回购——请参阅 包装进口)

文件日志记录需要 dart:io --进口 package:log_pilot/log_pilot_io.dart 仅适用于移动设备/台式机。使用 LogPilotConfig.web() 用于优化web默认设置。

______________________________________________________________________

测试

tearDown(() {
  LogPilot.reset(); // clears config, history, timers, and trace IDs
});

______________________________________________________________________

配置参考

选项类型默认值描述
enabledboolkDebugMode主开关。释放。
logLevelLogLevelverbose打印的最低严重性
outputFormatOutputFormatprettypretty / plain / json
showTimestampbooltrue显示HH:mm:ss。SSS
showCallerbooltrue可点击的源位置
showDetailsbooltrue错误体、堆栈跟踪
colorizebooltrueANSI颜色
maxLineWidthint100框宽度(字符)
stackTraceDepthint8显示的最大堆栈帧数
maxPayloadSizeint10240截断有效载荷(字节)
maskPatternsList['Authorization', 'password', 'token', 'secret']要屏蔽的字段(=exact, ~regex,或子字符串)
jsonKeyColorAnsiColorcyanJSON密钥颜色
jsonValueColorAnsiColorgreenJSON值颜色
silencedErrorsSet{}抑制匹配错误
onlyTagsSet{}仅打印匹配的标签
sinksList[]其他输出目的地
deduplicateWindowDurationDuration.zero折叠相同的消息(控制台+接收器)
maxHistorySizeint500环形缓冲区大小(0=关闭)
maxBreadcrumbsint20面包屑缓冲区(0=关闭)

______________________________________________________________________

包装进口

导入你得到了什么网络安全?出版?
package:log_pilot/log_pilot.dart核心: LogPilot, LogPilotLogger, LogPilotConfig, LogPilotRecord, LogLevel, LogSink, CallbackSink, AsyncLogSink, BufferedCallbackSink, LogHistory, ExportFormat, LogPilotNavigatorObserver, LogPilotOverlay, LogPilotHttpClient,ANSI助手
package:log_pilot/log_pilot_io.dartFileSink, FileLogFormat (要求 dart:io)
package:log_pilot/log_pilot_dio.dartLogPilotDioInterceptor (添加 dio 到pubspec) --仅限回购\*
package:log_pilot/log_pilot_chopper.dartLogPilotChopperInterceptor (添加 chopper) --仅限回购\*
package:log_pilot/log_pilot_graphql.dartLogPilotGraphQLLink (添加 gql, gql_exec, gql_link) --仅限回购\*
package:log_pilot/log_pilot_bloc.dartLogPilotBlocObserver (添加 bloc) --仅限回购\*
\* 这些导入将从pub.dev包中失败。 他们在 源代码仓库,但 .pubignored来自已公布的文件包。复制源 将文件放入项目中,或等待独立包(例如。 log_pilot_dio)在a 未来的释放。

______________________________________________________________________

示例应用程序

一个完整的可运行示例,每个功能都有可点击的按钮 example/:

cd example && flutter run

Example App

______________________________________________________________________

一览特性

功能它的作用
MCP服务器AI代理通过MCP协议查询、过滤、监视和控制实时日志
DevTools扩展Dart DevTools中的实时日志查看器选项卡--零配置
应用内日志查看器LogPilotOverlay 带有过滤器、搜索和实时更新的调试表
LLM出口压缩AI上下文窗口的日志历史记录
单线设置更换 runApp()LogPilot.init() --每个错误都是自动格式化的
漂亮的Flutter错误15+上下文提示、简化堆栈、可点击源位置
基于级别的日志记录verbose / debug / info / warning / error / fatal 具有结构化元数据和标签
范围记录仪const LogPilotLogger('Tag')LogPilot.create('Tag') 用于类级自动标记
原木水槽将记录路由到文件、Crashlytics、Sentry或任何后端
内置文件日志FileSink 按大小、文本或JSON格式自动旋转
懒惰的消息LogPilot.debug(() => expensiveString()) --筛选时跳过工作
网络拦截器http(已发布);Dio、Chopper、GraphQL(回购/未来包)
JSON突出显示自动检测和着色键/值
敏感场屏蔽标头和JSON正文中的递归掩码
配置预设LogPilotConfig.debug(), .staging(), .production(), .web()
速率限制/数据消除在时间窗口内折叠相同的消息
日志历史记录内存环形缓冲区——过滤、导出、附加到错误报告
输出格式pretty, plain, json --人机模式
诊断快照LogPilot.snapshot() --bug报告的一次通话摘要
面包屑错误每次出错前自动跟踪事件
错误ID确定性 lk-XXXXXX 用于跨会话跟踪的哈希
运行时日志级别覆盖在运行时更改冗长程度,而无需重新启动
仪器助手一行计时+任何表达式的错误捕获
会话和跟踪ID自动生成的会话UUID+每个请求的跟踪ID
导航日志自动记录推送/弹出/替换路由名称和参数
BLoC观察者日志创建/关闭、事件、状态更改和错误
性能计时LogPilot.time / LogPilot.timeEnd --喜欢 console.time
网络兼容岩芯筒 dart:io-免费——适用于Flutter Web
轻质核心Flutter SDK之外无需依赖;Dio、Chopper、GraphQL、BLoC集成可用 源代码仓库 (计划提供独立软件包)

______________________________________________________________________

贡献

欢迎捐款。看 贡献.md 为了 架构细节和开发设置。

______________________________________________________________________

许可证

麻省理工学院——见 许可证.

______________________________________________________________________

从plog迁移

如果您正在从升级 plog 包,这是一个快速映射:

ploglog_pilot
import 'package:plog/plog.dart'import 'package:log_pilot/log_pilot.dart'
Plog.init(child: ...)LogPilot.init(child: ...)
Plog.info(...)LogPilot.info(...)
PlogLogger('Tag')LogPilotLogger('Tag') (仍可施工)
Plog.create('Tag')LogPilot.create('Tag')
PlogConfig(...)LogPilotConfig(...)
PlogRecordLogPilotRecord
plog_dio.dartlog_pilot_dio.dart (仅限回购)
plog_bloc.dartlog_pilot_bloc.dart (仅限回购)
PlogNavigatorObserverLogPilotNavigatorObserver
PlogOverlayLogPilotOverlay
PlogHttpClientLogPilotHttpClient

所有API在功能上都是相同的——只是名称发生了变化。A. 项目范围内的查找和替换 PlogLogPilotploglog_pilot 涵盖了绝大多数案件。

目录标签

目录标签

日志记录JavaScriptClaude开发工具本地部署实时查询AI代理错误跟踪

支持客户端

ClaudeCursorWindsurf

接入字段

传输方式(transport,传输协议)

未说明

鉴权方式(authType,认证方式)

token

工具数量(toolCount,工具数)

8

资源数量(resourceCount,资源数)

0

提示词数量(promptCount,提示词数)

0

权限和风险

未说明token部署方式未说明

接入前请确认传输方式、认证方式和部署位置,并根据实际工具能力限制访问范围。

安装前确认

不要直接授予不必要的文件、网络或账号权限;先核对安装命令和配置内容。

仍需确认:installCommand

来源信息

继续浏览同类 MCP