用 cli-anything-nslogger 将 NSLogger 变为 Agent-Native 日志工具离线解析、过滤导出与 Bonjour/TLS 实时监听全指南【免费下载链接】CLI-AnythingCLI-Anything: Making ALL Software Agent-Native -- CLI-Hub: https://clianything.cc/项目地址: https://gitcode.com/GitHub_Trending/cl/CLI-AnythingNSLogger 是 macOS/iOS 开发中经典的桌面端日志查看器它通过自定义二进制 TCP 协议接收 iOS/macOS 应用发送的日志。本项目CLI-Anything 生态下的cli-anything-nslogger为 NSLogger 提供了一整套纯命令行 harness既能在无 GUI 环境下离线解析、过滤、导出.rawnsloggerdata/.nsloggerdata日志文件也能通过 Bonjour/mDNS 与直接 TCP/TLS 实时监听应用日志并统一输出机器可读的 JSON 供 AI Agent 消费。读完本文你将掌握这套 CLI 的全部子命令、日志等级与 JSON 结构、文件线协议的解析原理并能立刻上手用一条命令完成崩溃会话回溯、指定 Tag/正则过滤、全量导出、live 监听镜像等完整排障工作流。本文以 nslogger/agent-harness/cli_anything/nslogger/skills/SKILL.md 为骨架并结合同仓库的 SOP 文档 nslogger/agent-harness/NSLOGGER.md、CLI 入口 nslogger_cli.py 及core/、utils/、helpers/、tests/下的源码逐一展开。一、这是什么NSLogger × CLI-AnythingNSLogger 本身是 fpillet 开源的一个 macOS 日志查看器配套 iOS/macOS 客户端库把日志发送到桌面端。cli-anything-nslogger把这一能力搬进命令行目标是让所有软件对 Agent 原生可用仓库核心理念 CLI-Anything: Making ALL Software Agent-Native安装后得到一个名为cli-anything-nslogger的二进制命令所有子命令都支持--json输出稳定、可被 LLM/Agent 直接解析的 JSON 结构全部文件解析、过滤逻辑均为纯 Python 实现core/可在无图形界面的 CI/服务器上运行仅 macOS 实时监听需要编译调用平台 Swift 助手helpers/。二、安装与验证在仓库内执行以下命令即可完成可编辑安装对应 SKILL.md 的 Installation 部分安装入口见 nslogger/agent-harness/setup.pycd nslogger/agent-harness pip install -e . # 验证 cli-anything-nslogger --help运行cli-anything-nslogger --help会列出generate / read / filter / export / stats / listen / repl / tail / clients / blocks / merge等全部子命令对任一子命令可用COMMAND -h如cli-anything-nslogger listen -h查看该命令专属参数。三、两个核心文件格式与基础概念先分清两种文件后缀来源README.md 与 NSLOGGER.md后缀含义.rawnsloggerdata裸线协议抓包文件raw wire-protocol captureCLI 原生解析.nsloggerdataNSLogger.app 保存的二进制 plist 归档文件GUI 打开/导出的格式对应核心概念如下概念说明Message单条日志条目携带 sequence、时间戳、level、tag、threadID、type、text 等字段Message Types内容层面有text、image、data三种协议层面另有控制帧Log Level0error、1warning、2info、3debug、4verbose数字越大越吵Connection一条实时客户端连接经 Bonjour 发现或直连 50000 端口 TCPFilter一组限制显示范围的谓词线协议骨架读懂.rawnsloggerdata要理解为何这些命令能凭空读 NSLogger 文件需要知道 NSLogger 自定义二进制协议的基本布局NSLOGGER.md[4-byte big-endian total message length] [2-byte part count] for each part: [1-byte part key] [1-byte part type] [4-byte big-endian data length] # 仅变长部分整型隐式定长 [N bytes data]Part keys字段标识0messageType、1timestamp_s、2timestamp_ms、3timestamp_us、4threadID、5tag、6level、7message、8imageWidth、9imageHeight、10messageSeq、11filename、12lineNumber、13functionName、20clientName、21clientVersion、22osName、23osVersion、24clientModel、25uniqueIDPart types值类型0string(UTF8)、1binary、2int16、3int32、4int64、5imageMessage types帧类型0log、1blockStart、2blockEnd、3clientInfo、4disconnect、255marker。这些常量在源码 core/message.py 中一一对应PART_KEY_*/PART_TYPE_*/MSG_TYPE_*解析器实现在 core/parser.py。值得注意的两点实现细节解析器 parse_file 按后缀自动分流.rawnsloggerdata走逐帧[4字节长度前缀 payload]的裸协议读取其他后缀则先尝试用 Pythonplistlib解析.nsloggerdata二进制 plist读取messages数组失败时回退到裸协议解析因此对两类文件都有较高容错仓库里存在早期本地 fixture 写入了冗余 4 字节定长前缀的历史格式_parse_message采用官方格式优先、旧格式回退的三级解析策略向下兼容见 parser.py 注释。四、命令全景与离线排障主链路SKILL.md 为 Agent 设计的核心工作流是文件级离线分析generate造数 →read总览 →filter精查 →export落盘 →stats汇总必要时再上listen实时监听。4.1generate— 生成测试样本在没有真实抓包文件时可先生成一份可用于练习和验证管道的样本cli-anything-nslogger generate sample.rawnsloggerdata --count 50参数默认值为--count 20nslogger_cli.py。生成器 utils/generate.py 会先写一条msg_type3的client_info帧客户端 SampleApp 1.0.0 / iOS 17.0 / iPhone15,2再写入指定条数的混合日志——标签在Network/UI/Database/Auth/Cache中随机、等级按[0,0,1,1,2,2,2,3,3,4]分布、线程在main/background/network-queue/io-queue中轮转并内置了 timeout、fail、retry 等典型排障文本非常适合直接演示下面的过滤与统计命令。4.2read— 展示文件消息# 全部消息 cli-anything-nslogger read session.rawnsloggerdata # 仅错误level 0 cli-anything-nslogger read session.rawnsloggerdata --level 0 # 按 Tag 与文本搜索过滤 cli-anything-nslogger read session.rawnsloggerdata --tag Network --search timeout # 前 20 条以 JSON 输出 cli-anything-nslogger read session.rawnsloggerdata --limit 20 --jsonread支持的完整参数源码见 nslogger_cli.py参数说明类型/默认file输入文件路径必填须存在位置参数--level, -l最大展示等级0error … 4verboseint默认 None--tag, -t按 Tag 过滤可重复使用multiple--thread按线程 ID 过滤str--search, -s消息文本子串搜索不区分大小写str--limit, -n最多展示条数int--after / --before时间窗过滤HH:MM:SS或YYYY-MM-DDTHH:MM:SS--jsonJSON 数组输出flag时间窗参数统一走_parse_dtnslogger_cli.pyHH:MM:SS会被补为今天并假定为 UTC 时区YYYY-MM-DDTHH:MM:SS直接按 UTC 解析。所有过滤实际委托给统一实现 core/filter.py 的filter_messages()其中 Tag 与子串搜索均做了大小写不敏感处理。4.3filter— 进阶过滤# 仅 error warninglevel ≤ 1 cli-anything-nslogger filter session.rawnsloggerdata --level 1 # 按 Tag 组合Auth 或 Network cli-anything-nslogger filter session.rawnsloggerdata --tag Auth --tag Network # 正则搜索 cli-anything-nslogger filter session.rawnsloggerdata --regex (timeout|failed|error) # 按线程 cli-anything-nslogger filter session.rawnsloggerdata --thread main # JSON 输出 cli-anything-nslogger filter session.rawnsloggerdata --level 0 --jsonfilter是参数最全的查询命令在read之外还支持源码 nslogger_cli.py参数说明--min-level最小等级与--level构成等级区间--regex, -r文本正则编译时加re.IGNORECASE--type按消息类型过滤可选text/image/data/client_info/block_start/block_end可重复--from-seq / --to-seq按 sequence 序号区间过滤闭区间--after / --before时间窗过滤--limit, -n最多条数同一组谓词在 filter.py 中为AND 语义串行生效max_level与min_level分别拦截过噪/过细的消息tags采用小写集合做大小写不敏感匹配text_search是子串包含、text_regex是正则匹配msg_types依据LogMessage.type_name判断该属性在 message.py 中把底层帧类型映射为text/image/data/block_start/block_end/client_info/disconnect/marker最后按limit截断。4.4export— 导出为 text / JSON / CSV# JSON 输出到 stdout cli-anything-nslogger export session.rawnsloggerdata --format json # CSV 写入文件 cli-anything-nslogger export session.rawnsloggerdata --format csv --output logs.csv # 先过滤再以文本导出 cli-anything-nslogger export session.rawnsloggerdata --format text --level 1 --tag Networkexport默认格式为text可选text / json / csv--output缺省时写 stdout文件写路径时进度提示打到 stderr。导出前会先执行--level / --tag / --search / --limit预过滤。实现位于 core/exporter.pyCSV 字段固定为sequence, timestamp, level, level_name, tag, thread_id, type, text八列JSON 复用与--json完全一致的 message dict 结构见下文第七节。4.5stats— 汇总统计# 人类可读汇总 cli-anything-nslogger stats session.rawnsloggerdata # 面向 Agent 的 JSON cli-anything-nslogger stats session.rawnsloggerdata --json文本模式会打印总条数、首/末时间、持续时间、客户端列表并按 level、type、Top 10 tags、Top 5 threads 分组nslogger_cli.py。JSON 形态即 SKILL.md 给出的结构{ total: 342, by_level: {ERROR: 12, WARNING: 34, INFO: 200, DEBUG: 96}, by_tag: {Network: 89, Auth: 45, UI: 120}, by_thread: {main: 200, bg-queue: 142}, by_type: {text: 340, client_info: 1, disconnect: 1}, clients: [MyApp], first_timestamp: 2024-01-01T10:00:0000:00, last_timestamp: 2024-01-01T10:05:3000:00, duration_seconds: 330.0 }注意两处与源码对齐的细节core/stats.pyby_level实际按 level 数值升序排列后以LEVEL_NAMES命名by_tag截取 Top 20、by_thread截取 Top 10、clients去重后字典序排列。对空输入返回{total: 0}。五、listen— 实时监听Bonjour 优先离线命令解决已有文件listen解决现在就在跑的 App。SKILL.md 明确建议给 iOS App 用要先选 Bonjour 模式因为它精确复刻了 NSLogger 桌面 GUI 的自动发现行为——CLI 会以_nslogger-ssl._tcp服务类型发布一个原生 macOSNetService并接受 TLS 加密的 NSLogger 帧只有应用被手动配置了 Mac 主机与端口时才用直连 TCP/TLS 模式。# Bonjour 模式复刻 NSLogger.app GUI 行为iOS 端自动发现 cli-anything-nslogger listen --bonjour --name bazinga --debug # 实时镜像到文本文件stdout 仍照常打印 cli-anything-nslogger listen --bonjour --name bazinga --output app.log # 落盘为机器可读的 JSON Lines cli-anything-nslogger listen --bonjour --name bazinga --output app.jsonl --output-format jsonl # 手动配置客户端的直连 TCP/TLS 模式 cli-anything-nslogger listen --port 50000 --ssl --debug # 监听时仅显示错误并以 JSON 流输出 cli-anything-nslogger listen --bonjour --name bazinga --level 0 --json # 一直运行直到 Ctrl-C cli-anything-nslogger listen --bonjour --name bazingalisten的可调参数比 SKILL.md 示例展示的更多源码 nslogger_cli.py参数默认说明--port, -p50000TCP 监听端口--timeout, -t无运行 N 秒后自动停止默认到 Ctrl-C--level, -l无展示的最高等级做实时过滤--bonjour, -boff通过 Bonjour/mDNS 发布服务iOS 自动发现免配 IP--name, -n系统选名Bonjour 服务名命名后默认带filterClients1TXT对齐 NSLogger GUI--ssloff直连 TCP 模式强制 TLSBonjour 模式默认即 SSL--no-ssloff发布/接受旧版非 SSL Bonjour 服务--bonjour-modesslssl对齐 GUI 默认/auto同时发布 rawSSL/raw仅旧版--bonjour-publishernativenativemacOS NetService/dns-sdmacOS 命令/zeroconf跨平台 Python--output, -o无实时落盘镜像文件--output-formattexttext行或jsonl--appendoff追加而非启动时覆盖--output--debugoff在 stderr 打印每帧长度、TLS 协商、Bonjour 状态等诊断--jsonoff每条消息以 JSON dict 输出到 stdout底层的 TLS 与 Bonjour 实现源码视角监听器的核心是 core/listener.py 中的NSLoggerListenerBonjour 服务类型为_nslogger._tcp.local.legacy 明文与_nslogger-ssl._tcp.local.SSL见 listener.pySSL 证书无需用户手工配证书——代码用openssl现场生成临时自签名证书/密钥并构造仅允许 TLSv1.2 的SSLContextlistener.pyCFStream 服务端场景则额外导出 PKCS#12 身份文件listener.py明文/TLS 自动协商接连接时用MSG_PEEK不消费字节地预读 5 字节按 TLS ClientHello 特征首字节0x16 0x03判定走 TLS 握手还是明文 NSLogger 帧listener.py发布后端三层策略macOS 上默认把 native_bonjour_publisher.swift 通过swiftc现场编译运行用 FoundationNetService发布最贴近 NSLogger.app--bonjour-publisher dns-sd走系统dns-sd -R命令跨平台则退化为进程内zeroconf库listener.py每个客户端连接由独立守护线程处理实时收到的帧与离线解析共用同一个_parse_message保证两种来源的 message 结构完全一致。六、repl— 交互式命令 Shellcli-anything-nslogger repl session.rawnsloggerdata # 或者直接不带子命令运行 cli-anything-nslogger同样会进入 REPLREPL 基于仓库统一的ReplSkinutils/repl_skin.py启动时若传入文件会自动加载并提示消息数。支持的内部命令包括read / filter / tail / stats / clients / blocks / export / merge / generate / listen / load FILE / current / help / quit。load FILE可设置默认文件之后read、filter等文件类命令可省略文件参数见 nslogger_cli.py。无参运行二进制时因为 group 设置了invoke_without_commandTrue也会进入该 REPL。七、日志等级与消息 JSON 结构日志等级表ValueNameUse for用途0ERROR不可恢复的失败1WARNING可恢复的问题2INFO正常运行3DEBUG开发者细节4VERBOSE追踪级噪声来源映射表LEVEL_NAMES见 core/message.py其中还保留了等级 5NOISE的内部映射。单条消息 JSON 形态所有--json输出的单条消息均为统一结构SKILL.md 原样{ sequence: 42, timestamp: 2024-01-01T10:01:2300:00, timestamp_ms: 456, thread_id: main, tag: Network, level: 0, level_name: ERROR, type: text, text: Connection timed out after 30s, image_width: 0, image_height: 0, client_name: MyApp, client_version: 2.1.0, os_name: iOS, os_version: 17.0, machine: iPhone15,2 }该结构由LogMessage.to_dict()生成message.py字段解释如下sequence协议自增序号timestamp为 ISO8601 UTC 字符串、timestamp_ms为毫秒余量level/level_name等级数值与可读名type由type_name派生text/image/data/block_start/block_end/client_info/disconnect/markerthread_id、tag来源线程与业务标签client_name/client_version/os_name/os_version/machine上报方客户端信息通常由文件或会话中的client_info帧填充。八、Agent 实战工作流示例SKILL.md 以分析一次崩溃会话为主线给出了完整五步。假设crash.rawnsloggerdata是崩溃前捕获的会话文件# 1. 先总览会话规模、时间跨度、等级分布、涉及客户端 cli-anything-nslogger stats crash.rawnsloggerdata --json # 2. 找出崩溃前 5 分钟内的所有错误 cli-anything-nslogger filter crash.rawnsloggerdata --level 0 --json # 3. 仅保留网络失败Tag 正则双重收紧 cli-anything-nslogger filter crash.rawnsloggerdata --tag Network --regex fail|timeout|error --json # 4. 全量导出供离线/后续 AI 分析 cli-anything-nslogger export crash.rawnsloggerdata --format json --output crash_log.json # 5. 实时监听某 iOS App 并保留本地副本 cli-anything-nslogger listen --bonjour --name bazinga --output app.log --debug配套 SKILL.md 之外同一套文件级能力还可延伸出三条高频 Agent 子流程命令定义见 nslogger_cli.pytail展示文件末尾 N 条默认 20是崩溃发生前最后发生了什么最直接的查法clients列出文件中所有client_info记录实现于 core/blocks.py 的extract_clients可还原同一会话有几台设备、什么 OS/机型blocks把blockStart/blockEnd帧还原成缩进树默认每层 2 空格用于还原日志中的调用/作用域嵌套结构merge将多个.rawnsloggerdata按时间戳辅以 sequence合并后以 text/json/csv 输出适合把多客户端碎片会话拼成完整时间线blocks.py。九、可信度与测试覆盖仓库在 nslogger/agent-harness/cli_anything/nslogger/tests/ 提供两层测试测试说明见 TEST.md单元测试test_core.py覆盖LogMessage的 level/type 派生与文本行渲染、filter_messages的等级/Tag/线程/子串/正则/limit/组合过滤、compute_stats全部统计键、三种导出格式、线协议 encode→decode 往返、样本生成器与裸文件解析含空文件E2E 测试test_full_e2e.py用真实生成文件 真实子进程跑通generate→read→filter→export→stats管道、--json形状校验以及安装后 entrypoint 的冒烟测试测试报告中注明listen需真实 TCP 客户端、repl交互终端、.nsloggerdata二进制 plist、SSL/TLS 监听不属于自动化覆盖范围分别需要网络夹具、手工验证、真实 NSLogger.app 存档文件。复现测试的命令python3 -m pytest nslogger/agent-harness/cli_anything/nslogger/tests/ -v。十、适用前提与限制小结文件解析read/filter/export/stats/tail/clients/blocks/merge纯 Python、跨平台可在 macOS/Linux CI 上无 GUI 运行listen --bonjour中native NetService路径需要macOS Swift 工具链swiftc其余平台自动降级为zeroconf或dns-sd直连 TCP/TLS 模式下 macOS 客户端一般接受默认临时证书iOS 客户端的 TLS 信任需按 NSLogger 既有机制处理时间参数若只写HH:MM:SS会被视为今天的 UTC 时间跨日分析请使用YYYY-MM-DDTHH:MM:SS完整格式本文所有命令、默认值与输出结构均以当前仓库源码为准主要证据文件NSLOGGER.md 已更正为 nslogger/agent-harness/NSLOGGER.md 所指内容、nslogger_cli.py 及各core/模块升级版本后建议先跑cli-anything-nslogger --help核对。【免费下载链接】CLI-AnythingCLI-Anything: Making ALL Software Agent-Native -- CLI-Hub: https://clianything.cc/项目地址: https://gitcode.com/GitHub_Trending/cl/CLI-Anything创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考