Jacky's blog
首页
  • Android
  • Web
  • Server
  • Python
  • iOS
  • Java
  • Vue
  • 计算机基础
  • AI
  • 全部工具
  • CLI 工具
  • 编辑器
  • 开发工具
  • 构建工具
  • 版本控制
  • 调试工具
  • 网络工具
  • 个人成长
  • 博客
  • 分类
  • 标签
  • 归档
收藏
GitHub (opens new window)

Jack Yang

编程; 随笔
首页
  • Android
  • Web
  • Server
  • Python
  • iOS
  • Java
  • Vue
  • 计算机基础
  • AI
  • 全部工具
  • CLI 工具
  • 编辑器
  • 开发工具
  • 构建工具
  • 版本控制
  • 调试工具
  • 网络工具
  • 个人成长
  • 博客
  • 分类
  • 标签
  • 归档
收藏
GitHub (opens new window)
  • 开发工具

  • 构建工具

  • 版本控制

  • 容器

  • 调试工具

  • 测试工具

  • CLI 工具

  • 网络工具

  • 编辑器

  • 设计工具

  • 多媒体

  • 包管理

  • 平台工具

    • mac 百问记录
    • mac tool
    • macOS log 日志查询与系统故障排查指南
      • 常用命令与过滤方式
      • USB 插拔、掉线与识别失败
      • 通知不显示:从应用追到系统
      • 其他常见场景
      • 留存证据与排查顺序
    • platform
    • unbuntuOnWindows
  • tools
  • platform
Jacky
2026-10-20
目录

macOS log 日志查询与系统故障排查指南

macOS 的 log 命令可以查询统一日志,适合追踪 USB 插拔、通知投递、网络变化和应用错误。排查时先记录复现时间,再从应用追到系统服务;不要一开始就在全天日志中搜索 error。

统一日志不是某个可直接 tail -f 的文本文件,应用自己写入的文件日志也未必进入这里。关于存储机制,参见 Apple Logging 文档 (opens new window)。

# 常用命令与过滤方式

先选历史查询或实时观察

目的 命令 说明
查询最近 10 分钟 /usr/bin/log show --last 10m --style compact 不加级别参数时不包含 Info、Debug
查询指定应用 /usr/bin/log show --last 10m --info --predicate 'process == "ExampleApp"' --style compact 进程名不一定等于 App 显示名称
实时观察指定应用 /usr/bin/log stream --level info --predicate 'process == "ExampleApp"' --style compact 先启动,再复现;按 Control + C 停止
临时包含 Debug /usr/bin/log stream --level debug --predicate 'process == "ExampleApp"' --style compact 用于短时间诊断,输出可能很多
只看 Error、Fault /usr/bin/log show --last 10m --predicate 'logType == "error" OR logType == "fault"' --style compact 容易漏掉正常流程和策略拦截原因
查进程实际名称 pgrep -fl 'ExampleApp' 主进程、helper、内核可能分别记录日志
本机语法帮助 /usr/bin/log help show、/usr/bin/log help stream、/usr/bin/log help predicates 以当前 macOS 提供的参数为准

--last 支持 s、m、h、d。show 用 --info --debug 包含更多级别;stream 可用 --level info 或 --level debug。它们控制本次读取范围,不能补回过去没有保存的记录,也不需要为排查永久开启生产 Debug 日志。

按时间缩小范围

将示例时间替换为实际复现时间,先查前后各一两分钟:

/usr/bin/log show \
  --start '2026-10-20 10:00:00' \
  --end '2026-10-20 10:03:00' \
  --info --debug --style compact \
  --predicate 'process == "ExampleApp"'
1
2
3
4
5

对照日志时注意时区。需要跨机器比较时,可加 --timezone UTC,并在问题记录中写明时间与时区。

谓词速查

谓词整体用 Shell 单引号,内部字符串用双引号;[c] 表示忽略大小写。多个 OR 条件与 AND 组合时加括号。

过滤对象 谓词示例 用途
进程名 process == "ExampleApp" 查询某个进程
PID processIdentifier == 1234 区分同名进程;重启后 PID 会变化
子系统 subsystem == "com.apple.UserNotifications" 查看通知相关记录,不保证覆盖所有通知服务
子系统前缀 subsystem BEGINSWITH "com.apple." 探索相关组件
消息关键词 eventMessage CONTAINS[c] "timeout" 发现超时记录
组合条件 process == "ExampleApp" AND (eventMessage CONTAINS[c] "config" OR eventMessage CONTAINS[c] "reload") 配置修改、加载链路

eventMessage 是常用的消息过滤写法;部分版本的字段帮助列出 composedMessage。若报字段错误,按本机 log help predicates 调整。不要只依赖 App 的 bundle ID 过滤 subsystem,应用可能使用其他子系统,或没有填写子系统。

优先用谓词减少读取量,再用 rg 做二次筛选;rg 需要本机已安装。例如:

/usr/bin/log show --last 5m --info --style compact \
  --predicate 'process == "ExampleApp"' \
  | rg -i 'config|reload|error|fail'
1
2
3

二次筛选会丢掉上下文,发现关键行后,应回到对应时间段查看未经过关键词筛选的记录。

# USB 插拔、掉线与识别失败

先看系统当前是否识别设备

命令 观察内容 限制
system_profiler SPUSBDataType USB 总线、已识别设备及连接信息 当前快照,不是插拔历史;可能包含序列号
ioreg -p IOUSB -l -w 0 IORegistry 中的 USB 设备树及属性 属性较多,适合比较插拔前后状态
system_profiler SPThunderboltDataType 雷雳设备及拓扑 USB-C 是接口形态,不代表连接协议一定是 USB
diskutil list external 外接存储设备是否成为磁盘 仅用于存储类设备,不能判断键盘、串口等设备

实时观察插拔

先执行下面的命令,再连接设备,记录时间;需要拔出存储设备时先正常推出。这里只把 USB 相关子系统和内核中的 USB 关键词当作发现入口,具体字段和输出会随 macOS、硬件及驱动变化。

/usr/bin/log stream --level info --style compact \
  --predicate 'subsystem CONTAINS[c] "usb" OR (process == "kernel" AND eventMessage CONTAINS[c] "usb")'
1
2

若设备变化但输出很少,可在复现的短时间内改为 --level debug。看到相关进程、子系统或设备标识后,用实际值收窄过滤;不要假定所有设备都会记录统一的 attach / detach 消息。

查询刚才的事件

/usr/bin/log show --last 10m --info --debug --style compact \
  --predicate 'subsystem CONTAINS[c] "usb" OR (process == "kernel" AND eventMessage CONTAINS[c] "usb")'
1
2

先保留连接前后的记录,再重点找 disconnect、reset、enumerat、timeout、overcurrent、power 等线索。这些只是检索词,不能凭单条关键词就认定设备损坏;反复重置和掉线也可能来自线材、扩展坞、供电或驱动。

按故障层次判断下一步

现象 下一步
USB 树里完全没有设备 对比插拔前后快照;换支持数据传输的线、换接口、绕过扩展坞,并检查配件连接授权
能识别,但反复断开、重置 对齐日志时间,逐项替换线材、端口、扩展坞和供电条件,比较是否仍复现
USB 树中存在,但应用找不到 查对应驱动或应用日志;USB 枚举成功不代表上层协议和权限都正常
外接磁盘已在 diskutil 中,Finder 不显示 继续检查卷是否挂载、文件系统及 Finder 显示设置,不直接格式化
出现“USB 设备已停用”或电量不足 直连 Mac、换端口,检查有源扩展坞电源;参见 Apple USB 供电排查 (opens new window)

在支持配件安全控制的 Mac 上,也要留意解锁后是否出现允许连接提示,参见 Apple 配件连接授权说明 (opens new window)。命令能看到什么,与设备连接协议和系统授权有关,不能把“USB 日志为空”直接等同于“没有插拔”。

# 通知不显示:从应用追到系统

案例:ClashX Meta 没有配置变化、系统代理变化提示

现象是 App 已允许通知,但配置修改和代理变化时看不到提醒。排查重点是区分三步:应用是否检测到变化、是否成功提交通知、系统是否允许展示。最终系统日志出现 DND 延迟投递记录,结合手机“工作”专注模式同步到 Mac 的状态,以及关闭后的恢复结果,确认通知被专注模式抑制。

先看 App 侧提交行为:

/usr/bin/log show --last 10m --info --debug --style compact \
  --predicate 'process == "ClashX Meta" AND (subsystem CONTAINS[c] "UserNotifications" OR eventMessage CONTAINS[c] "noti")'
1
2

再看通知服务;这里的消息字段匹配的是日志中出现的应用标识,不等于按进程名查询:

/usr/bin/log show --last 10m --info --debug --style compact \
  --predicate '(process == "usernoted" OR process == "NotificationCenter") AND eventMessage CONTAINS[c] "com.metacubex.clashx.meta"'
1
2

bundle ID 可从应用包内读取;其他 App 替换路径和上述标识即可:

/usr/libexec/PlistBuddy -c 'Print :CFBundleIdentifier' \
  '/Applications/ClashX Meta.app/Contents/Info.plist'
1
2

若按 bundle ID 查不到,不要立即判断没有投递。服务后续行可能只保留通知请求 ID;从应用的提交记录取出该次请求 ID,在相同时间段追踪它,并核实所属 App,避免仅凭短 ID 匹配到别的通知。

下面是简化并脱敏的日志片段,省略时间、线程和随机标识,仅用于解释含义;具体文案随系统版本变化:

Added notification request: [ hasError: 0 hasCompletionHandler: 1 ]
interruptionSuppression: delay delivery
muted by DND suppression: delay
1
2
3
证据 可以判断什么 不能据此判断什么
hasError: 0 该次通知提交未报错 用户一定看到了横幅
DND suppression: delay 该次通知被专注模式/勿扰策略延迟 App 文件监听失效
removeAllDeliveredNotifications App 请求清除此前已投递通知 新通知必然被清除,或这是本次根因
内核接口响应正常 查询时内核仍可用 系统代理始终开启、图标从未置灰

处理时检查当前专注模式的 App 放行规则,以及是否开启“在设备之间共享”。若不想电脑跟随手机,可在 Mac 关闭共享,再关闭当前专注模式;共享开关与当前模式开关分别处理。参见 Apple 专注模式选项说明 (opens new window)。

代理图标置灰需要另外取证

scutil --proxy
pgrep -fl 'Clash|mihomo'
1
2

在故障出现时记录系统代理是否仍指向预期本地端口、主进程和内核是否存在。scutil --proxy 是当前状态快照,不能据此追溯哪个进程修改过代理;TUN、PAC 等模式也不能只看 HTTPEnable。专注模式能解释提示缺失,不能单独解释图标为什么置灰。

# 其他常见场景

先用以下范围找到相关进程或子系统,再围绕复现时间收窄;进程名和日志文案可能因版本不同而变化。

问题 查询入口 配合检查
配置保存后没生效 process == "ExampleApp" AND (eventMessage CONTAINS[c] "config" OR eventMessage CONTAINS[c] "reload") 当前选中配置、修改时间、解析错误;有检测通知不代表已重载
网络或代理异常 process == "configd" OR process == "networkserviceproxy" scutil --proxy、scutil --dns;这些服务不覆盖所有网络问题
DNS 解析异常 process == "mDNSResponder" scutil --dns,结合失败请求时间,留意域名可能被隐去
睡眠后设备掉线 process == "powerd" pmset -g log,比较睡眠、唤醒与设备掉线时间
蓝牙断连 process == "bluetoothd" 先复现,记录设备和连接方式,不直接推断无线干扰
应用退出或崩溃 process == "ExampleApp" OR process == "ReportCrash" 在“控制台”查看崩溃报告;统一日志不能替代崩溃栈

# 留存证据与排查顺序

保存可回查的记录

文本输出保留时间戳,适合对照操作步骤。下面只导出指定应用最近 5 分钟的日志:

/usr/bin/log show --last 5m --info --debug --style compact \
  --predicate 'process == "ExampleApp"' > ./app-diagnostic.txt
1
2

需要保留可重新筛选的系统日志时,再收集短时间归档;此操作可能需要管理员权限,且范围比单应用文本更大:

sudo /usr/bin/log collect --last 10m --output ./incident.logarchive
/usr/bin/log show --archive ./incident.logarchive \
  --info --debug --style compact \
  --predicate 'process == "ExampleApp"'
1
2
3
4

日志分享前先脱敏

系统日志、USB 快照和归档可能包含用户名、个人路径、设备序列号、网络地址、文件名、请求 URL 或凭据。原始采集文件只在本地保留,不提交到博客仓库;分享时另取必要片段,将标识替换成一致的占位符,同时保留时间顺序和错误信息。系统自动生成的 <private> 不代表整份日志已完成隐私清理。

遇到问题按这个顺序走

  1. 记录现象、准确时间、时区及触发动作,先保留现场。
  2. 查当前状态:进程、设备树、系统代理等,区分 App 界面与实际系统状态。
  3. 开始 log stream,只复现一次;保存故障前后的时间窗口。
  4. 先查应用,再追到它依赖的系统服务,用时间与请求 ID 对齐记录。
  5. 根据证据一次改变一个条件,例如关闭专注模式或更换 USB 线,再重复同样动作验证。
  6. 记录“已确认的原因”和“尚未解释的现象”,不要让一个结论覆盖所有症状。
查询障碍 处理方式
没有结果 依次检查时间、进程名、过滤条件和级别;短时实时复现,必要时改查应用文件日志
输出太多 缩短到几分钟,优先按进程、子系统过滤,再加关键词
提示权限不足 在本机终端对确有权限要求的读取命令加 sudo;它不会恢复未保存或已脱敏的历史字段
提示 Cannot run while sandboxed 由执行环境授予相应权限,或在普通本机终端运行;不能简单认定需要关闭系统安全功能
只有 <private> 用仍可见的时间、进程、请求 ID 关联,不把隐藏字段当作空值
Info/Debug 历史缺失 提高查询级别不会补回记录;先开实时观察再复现
想用图形界面 打开“控制台(Console)”,选择本机并开始流传输,再搜索进程或消息

参数参考以本机 /usr/bin/log help、man log 为准;统一日志概念参见 Apple Logging (opens new window)。

#macOS#Shell#debug#guide
上次更新: 2026/10/20, 20:29:28
mac tool
platform

← mac tool platform→

最近更新
01
Codex 使用与会话管理指南
10-17
02
Tailscale 入门:让自己的设备跨网络互联
10-15
03
GitHub CLI(gh)工作流与 CI 排查
10-08
更多文章>
Theme by Vdoing | Copyright © 2019-2026 Jacky | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式