☰
Peekaboo pblog 统一日志查看器实战指南:基于 macOS unified logging 的全子系统日志排查方案
2026/10/13 3:04:00 网站建设 项目流程
  • GUI 自动化
  • MCP 服务
  • AI 应用

【免费下载链接】Peekaboo

Peekaboo is a macOS CLI & optional MCP server that enables AI agents to capture screenshots of applications, or the entire system, with optional visual question answering through local or remote AI models.

项目地址:https://gitcode.com/gh_mirrors/peekaboo6/Peekaboo
点击查看免费下载

导读

pblog 是 Peekaboo 项目内置的统一日志查看器,它把 macOS 系统日志(unified logging)中分散在 CLI、主 Mac 应用、Inspector、Playground 测试应用等不同子系统下的日志统一收集、过滤与实时流式输出,是排查 Peekaboo 各类自动化服务(点击、元素检测、菜单、窗口等)运行时问题的一站式入口。读完本文,你将掌握 pblog 的全部命令行选项、默认监控的子系统边界、字面量过滤的语义约束,以及如何用--json、--follow组合出可脚本化的日志采集方案。

pblog 是什么:Peekaboo 多子系统的统一日志入口

Peekaboo 是一个以 macOS 桌面自动化为核心的项目(CLI 工具、MCP 服务器、Inspector 与 Playground 应用等)。它的各个组件统一基于 Apple 的unified logging(os.Logger)记录日志,并在初始化时指定了boo.peekaboo.core等子系统标识,例如 LoggingService.swift 中LoggingService默认使用subsystem: "boo.peekaboo.core",SmartCaptureService.swift、ApplicationService.swift 等核心服务也都以该子系统写入日志。

由于子系统众多,逐个执行log show --predicate 'subsystem == "..."'既繁琐又容易遗漏。pblog.sh就是为消除这一摩擦而生的 bash 封装(约 190 行),它的核心工作是:

  • 内置一份覆盖所有 Peekaboo 子系统的默认谓词,免去手写;
  • 提供-c、-s、--subsystem、-d、-e等快捷过滤参数;
  • 自动追加时间范围(--last)与行数截断(tail -n);
  • 支持-f实时流与--json结构化输出;
  • 通过set -o pipefail保证底层 log 命令的失败不会被 tail 吞掉(见 pblog.sh)。

快速上手

在仓库根目录直接运行脚本即可看到最近日志:

# 查看所有 Peekaboo 子系统最近 50 行、过去 5 分钟的日志 ./scripts/pblog.sh # 连续流式输出(类似 tail -f) ./scripts/pblog.sh -f # 只看错误 ./scripts/pblog.sh -e # 只看某个服务的日志 ./scripts/pblog.sh -c ElementDetectionService # 只看某个子系统的日志 ./scripts/pblog.sh --subsystem boo.peekaboo.core

其中默认时间范围是5m、默认行数是50,这两项都可以通过-l和-n调整。脚本本身的可执行入口与全部选项见./scripts/pblog.sh -h。

支持的子系统(默认监控范围)

pblog 默认监控以下 Peekaboo 子系统,覆盖 CLI、主应用与各类开发工具:

子系统标识对应组件
boo.peekaboo.core核心服务(ClickService、ElementDetectionService 等)
boo.peekaboo.cliCLI 工具
boo.peekaboo.inspectorInspector 应用
boo.peekaboo.playgroundPlayground 测试应用
boo.peekaboo.app主 Mac 应用
boo.peekabooMac 应用通用组件

从源码实现看,pblog.sh 实际构造的默认谓词还额外包含了boo.peekaboo.axorcist(AXorcist 无障碍库的子系统),即:

(subsystem == "boo.peekaboo.core" OR subsystem == "boo.peekaboo.inspector" OR subsystem == "boo.peekaboo.playground" OR subsystem == "boo.peekaboo.app" OR subsystem == "boo.peekaboo" OR subsystem == "boo.peekaboo.axorcist" OR subsystem == "boo.peekaboo.cli")

也就是说,即使文档列表里没有明写,pblog 默认也会抓取 AXorcist 库产生的日志。如果你只想聚焦某一个组件,用--subsystem精确指定即可,脚本会放弃默认谓词、仅按指定子系统查询。

命令行选项全解析

pblog 支持短选项与长选项两种写法,完整选项如下(默认值已标注):

短选项长选项作用默认值
-n--lines NUM显示的日志行数50
-l--last TIME搜索的时间范围5m
-c--category CAT按类别过滤(如 ClickService)全部
-s--search TEXT搜索特定文本无
-o--output FILE将结果输出到文件标准输出
-d--debug显示 debug 级别日志仅 info 及以上
-f--follow连续流式输出查询一次即结束
-e--errors仅显示错误所有级别
-p--private显示私有数据(需要免密 sudo)关闭
--all关闭默认的尾部行数限制最后 50 行
--json以 JSON 格式输出文本
--subsystem NAME按指定子系统过滤全部 Peekaboo 子系统
-h--help显示帮助—

几点值得注意的语义(均有源码与测试佐证):

  • 历史错误查询匹配的是系统日志原生的logType字段。在 pblog.sh 中,-e会在谓词上追加AND logType == "error",并同时携带--info --debug标志读取;与错误无关的事件类型不会被当成日志严重级别。
  • 搜索、类别、子系统取值都是字面文本,不是 shell 命令或谓词表达式。脚本用predicate_literal()对反斜杠与双引号做转义后嵌入谓词(pblog.sh),并建议在 shell 中给参数加引号;该函数会保留撇号、引号、反斜杠与尾部换行,原样传给 macOS unified logging。macOS 会在谓词中拒绝控制字符,脚本不会把它们静默裁剪成另一个查询——宁可失败也不悄悄篡改你的过滤条件。
  • --output FILE会把选中的行写入文件,而--all则关闭默认的尾部限制。
  • 失败的日志查询即使输出被tail截断或已写入文件,退出码仍然非零。因为脚本启用了set -o pipefail(pblog.sh),log命令的退出码会穿透管道。免密 sudo 被拒绝、非法的行数、输出文件写入错误也都属于失败,部分输出绝不代表成功——这是它适合嵌入 CI/脚本的原因。
  • 带值的选项必须跟一个参数。如果一条命令以--search、--lines或其他带值选项结尾而没有提供值,脚本会在读取日志之前向 stderr 输出<option> requires a value并以状态码 2 退出。空字符串或以-开头的参数仍被视为“已提供值”,不算缺参(解析逻辑见 pblog.sh,测试覆盖见 tests/pblog.test.mjs)。

典型用法与组合示例

以下示例均来自文档且可直接复制执行:

# 调试元素检测问题(ElementDetectionService + debug 级别) ./scripts/pblog.sh -c ElementDetectionService -d # 实时监控点击操作 ./scripts/pblog.sh -c ClickService -f # 查看最近 30 分钟的错误 ./scripts/pblog.sh -e -l 30m # 搜索特定文本,显示 100 行 ./scripts/pblog.sh -s "Dialog" -n 100 # 实时监控 Playground 应用日志 ./scripts/pblog.sh --subsystem boo.peekaboo.playground -f

在此基础上可以进一步组合出更精细的排查命令:

# 多条件叠加:ClickService 中既含 "error" 又开 debug,并实时跟踪 ./scripts/pblog.sh -d -c ClickService -s "error" -f # 导出过去 1 小时全部日志为 JSON 文件 ./scripts/pblog.sh -l 1h --all --json -o logs.json # 免密 sudo 下查看带私有数据的 ClickService 会话日志并实时跟踪 ./scripts/pblog.sh -p -c ClickService -s "session" -f # 保存最近 30 分钟全部日志到文件 ./scripts/pblog.sh -l 30m --all -o debug-logs.txt

类别过滤与源码中的日志类别对应

-c过滤的是 unified logging 的category字段。Peekaboo 的类别由 LoggingService.swift 统一定义,包括ScreenCapture、Automation、Windows、Menu、Dock、Dialogs、Snapshots、AI、Performance、Permissions等。但各服务也常直接用服务名作为类别,例如ClickService、ElementDetectionService、SmartCapture、ApplicationService、SnapshotManager、WindowTracker等(见 ApplicationService.swift、SnapshotManager.swift)。因此:

  • 想按服务过滤:-c ClickService、-c ElementDetectionService;
  • 想按功能主题过滤:-c Performance、-c Permissions。

--lines的边界:文本查询、JSON 与实时流的差异

文档明确指出:--lines只限制“已完成的文本查询”。原因是 JSON 记录会跨越多行物理输出,而实时流在结束前没有 EOF 可供tail刷出缓存。对应地,pblog.sh 在--json或--follow生效时强制NO_TAIL=true,跳过行数截断:

# JSON 输出保留生产者(log 命令)的完整 framing,不做物理行截断 ./scripts/pblog.sh --json # follow 模式逐条转发事件,不等流结束 ./scripts/pblog.sh -f --json

由此产生两个关键行为:

  1. 两种模式都绕过物理行数限制,即使你同时传了-n 10也不会把多行 JSON 记录或实时事件截断成残缺输出;
  2. 实时流中的 JSON 不一定是单个独立的 JSON 文档——每条日志事件可能以流式片段到达,直接jq整段解析可能失败,需要按事件边界逐条处理。

这在 tests/pblog.test.mjs 中有明确的测试佐证:JSON 输出在 60 行样例下依然保留完整 JSON 帧,follow模式则验证了“事件在生产者释放前就被转发到 stdout/文件”的实时性。

失败传播:为什么它能安全嵌入自动化脚本

pblog 在脚本语境下最重要的特性是不掩盖失败:

  • 日志查询本身失败(如权限、谓词非法)时,即使结果被tail -n截断或重定向到了文件,进程退出码依然非零;
  • 免密 sudo(-p)被拒绝时同样以非零退出;
  • --lines传入非法数值、--output指向不存在的目录,都属于失败而非“输出部分内容即算成功”。

从测试 tests/pblog.test.mjs 可以看出,脚本对“log 失败”“sudo 拒绝”“输出重定向失败”“行数非法”四类场景均要求非零状态码与非空 stderr。这意味着你可以在 CI、发布流水线或自定义诊断脚本里直接依赖 pblog 的退出码判断日志采集是否真实成功,而不会被“看似有输出”误导。

从<private>到明文:pblog 与隐私脱敏的配合

macOS 默认会对日志中的动态值做隐私脱敏,显示为<private>,例如:

Peekaboo: Clicked element <private> at coordinates <private>

会话 ID、文件路径等关键调试信息因此不可见。pblog 提供-p/--private选项,通过sudo -n log ...提升访问权限(pblog.sh),但需要说明:

  1. 免密 sudo 的配置方式:用sudo visudo添加yourusername ALL=(ALL) NOPASSWD: /usr/bin/log,随后sudo -n log show --last 1s应免密执行;
  2. 更彻底的方案是安装日志配置描述文件:仓库内提供 docs/logging-profiles/EnablePeekabooLogPrivateData.mobileconfig,它为系统日志及boo.peekaboo.core、boo.peekaboo.app、boo.peekaboo.playground、boo.peekaboo.inspector、boo.peekaboo.cli、boo.peekaboo等子系统统一开启Enable-Private-Data,使 macOS 在写入时就保留真实值,安装后 1–2 分钟生效,验证命令为:
./scripts/pblog.sh -c PrivacyTest -l 1m
  1. 面向生产的代码级做法是在 Swift 中用privacy: .public显式标记需要可见的字段,而不是全局关闭隐私。

完整的安装步骤、sudo log config --mode private_data:on的临时替代方案以及安全注意事项,详见 docs/logging-profiles/README.md,此处不再展开。注意:开启私有数据会降低隐私保护,应在调试结束后移除描述文件或恢复sudo log config --reset private_data。

延伸:Playground 也有同款日志查看器

如果你在开发 Peekaboo 的 Playground 测试应用,会发现 Apps/Playground/scripts/playground-log.sh 是一套 pblog 风格的姊妹工具:它固定只查询boo.peekaboo.playground子系统,额外提供--categories列出可用的日志类别(Click、Text、Menu、Window、Scroll、Drag、Keyboard、Focus、Gesture、Control、Space、App、MCP),并在终端输出时按类别着色。它与 pblog 共享同一套谓词转义、pipefail失败传播和 JSON/--follow绕过行数截断的设计,可作为理解 pblog 内部原理的第二份参考实现。

用测试保障行为契约

pblog 的行为不是“经验之谈”,而是被 Node 测试显式锁定为契约的。仓库内 tests/pblog.test.mjs 通过替换PATH中的log/sudo为 mock 脚本,验证了:

  • 字面谓词完整保留撇号、引号、反斜杠与尾部换行,且不会执行$(...)这类 shell 注入(tests/pblog.test.mjs);
  • debug/error 历史查询的--debug/--info标志与 mock-only sudo 的-n前缀正确(tests/pblog.test.mjs);
  • --follow使用stream命令并正确透传 level 与 JSON 参数;
  • 输出到文件与 stdout 在--all/--lines下的行为一致;
  • 各类失败场景的退出码均非零。

仓库的test:log-scripts脚本即同时运行 pblog 与 playground-log 的测试(见 package.json),改动日志脚本后可以一键回归。

结语

pblog 把 Peekaboo 分散在多个 macOS 子系统中的日志收拢成一个命令:默认覆盖全组件、-c/-s/--subsystem精确下钻、-d/-e控制级别、-f/--json面向实时与自动化。配合它对字面量过滤、失败退出码和 JSON 帧的严谨处理,它既适合开发期人肉排查,也适合作为脚本流水线里可靠的日志采集环节。若遇到<private>脱敏问题,优先参考 docs/logging-profiles/README.md 安装描述文件或使用-p免密查看。

  • GUI 自动化
  • MCP 服务
  • AI 应用

【免费下载链接】Peekaboo

Peekaboo is a macOS CLI & optional MCP server that enables AI agents to capture screenshots of applications, or the entire system, with optional visual question answering through local or remote AI models.

项目地址:https://gitcode.com/gh_mirrors/peekaboo6/Peekaboo
点击查看免费下载

相关推荐

上一篇:Mongoose 9.x 迁移完全指南:从 8.x 升级的破坏性变更清单与代码改造方案
下一篇:Karakeep MCP Server 接入指南:让 LLM 直接搜索、创建与管理你的书签库

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询