- 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.
导读
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.cli | CLI 工具 |
boo.peekaboo.inspector | Inspector 应用 |
boo.peekaboo.playground | Playground 测试应用 |
boo.peekaboo.app | 主 Mac 应用 |
boo.peekaboo | Mac 应用通用组件 |
从源码实现看,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由此产生两个关键行为:
- 两种模式都绕过物理行数限制,即使你同时传了
-n 10也不会把多行 JSON 记录或实时事件截断成残缺输出; - 实时流中的 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),但需要说明:
- 免密 sudo 的配置方式:用
sudo visudo添加yourusername ALL=(ALL) NOPASSWD: /usr/bin/log,随后sudo -n log show --last 1s应免密执行; - 更彻底的方案是安装日志配置描述文件:仓库内提供 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- 面向生产的代码级做法是在 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.
相关推荐
Peekaboo pblog 日志查看器:macOS 统一日志过滤、隐私脱敏与调试实战指南
Peekaboo pblog 日志查看器:macOS 统一日志过滤、隐私脱敏与调试实战指南 pblog 是 Peekaboo 项目内置的日志查看工具,一个封装
GUI 自动化MCP 服务AI 应用三分钟解决C盘爆红:WindowsCleaner开源清理工具实战指南
三分钟解决C盘爆红:WindowsCleaner开源清理工具实战指南 你是不是也经常遇到C盘突然变红,系统提示"磁盘空间不足"的烦恼?电脑越用越慢,浏览器卡顿,
GUI 自动化MCP 服务AI 应用miracle-wm无障碍功能详解:让每个人都能高效使用
miracle wm无障碍功能详解:让每个人都能高效使用 miracle wm 是一款可定制的 Wayland 窗口管理器,不仅提供高效的窗口管理体验,还内置了
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考