今天来看一个专门用于 Erlang/OTP 系统的命令行观测工具 observer_cli。对于正在开发或运维 Erlang/Elixir 应用的工程师来说,这个工具能让你在终端里直接查看 BEAM 虚拟机的运行时状态,包括监督树结构、进程详情、内存分配等关键指标。
observer_cli 由 zhongwencool 开发维护,目前 GitHub 上有 1.5k star,支持 Erlang/OTP 26-29 版本。它提供了两种使用方式:命令行接口(CLI)适合自动化脚本和运维场景,文本用户界面(TUI)适合交互式探索。两种方式都基于 Erlang 分布式连接,可以远程诊断生产环境节点。
最核心的价值是:你不需要图形界面,直接在 SSH 会话中就能完成全面的运行时诊断。对于服务器运维、CI/CD 流水线集成、AI 代理工作流等场景特别实用。本文将带你完成从安装部署到实际使用的完整流程,重点演示如何查看监督树和进程状态。
1. 核心能力速览
| 能力项 | 说明 |
|---|---|
| 项目类型 | Erlang/Elixir 运行时诊断工具 |
| 开源地址 | github.com/zhongwencool/observer_cli |
| 主要功能 | 进程监控、内存分析、调度器状态、监督树可视化、网络活动追踪 |
| 支持平台 | Linux, macOS, Windows (需要 Erlang 环境) |
| 运行要求 | Erlang/OTP 26-29,无需图形界面 |
| 连接方式 | Erlang 分布式节点连接 |
| 输出格式 | 文本、Erlang 术语、JSON(OTP 27+) |
| 适合场景 | 生产环境诊断、自动化运维、性能调优、教学演示 |
2. 适用场景与使用边界
observer_cli 主要面向以下几类用户:
Erlang/Elixir 开发者:在开发过程中实时查看应用状态,调试监督树结构,分析进程间通信。
DevOps 工程师:在生产环境通过 SSH 连接诊断问题,无需图形界面访问权限。
SRE 团队:集成到监控告警系统中,定期采集运行时指标。
教学培训:演示 OTP 应用架构和 BEAM 虚拟机工作原理。
使用边界需要注意:
- 仅支持 Erlang/Elixir 的 BEAM 虚拟机环境
- 需要节点间的网络连通性和正确的 cookie 配置
- 不适合非 Erlang 生态的技术栈
- 生产环境使用需确保网络安全性
3. 环境准备与前置条件
在开始安装 observer_cli 之前,需要确认基础环境:
Erlang/OTP 版本要求:
- 最低支持 OTP 26.x
- 推荐使用 OTP 27+ 以获得 JSON 输出支持
- 最高支持 OTP 29.x
检查当前 Erlang 版本:
erl -version # 或者 erl +V系统路径配置: 确保erl、escript等 Erlang 工具在 PATH 中:
which erl which escript网络和权限:
- 如果连接远程节点,需要网络连通性
- 知道目标节点的名称和分布式 cookie
- 有权限在目标节点安装 observer_cli 依赖
磁盘空间: 工具本身很小,但需要足够的空间编译 Erlang 依赖。
4. 安装部署与启动方式
observer_cli 提供多种安装方式,根据你的使用场景选择。
4.1 快速安装(推荐)
对于大多数用户,使用官方安装脚本是最简单的方式:
# 安装最新稳定版 curl -fsSL https://raw.githubusercontent.com/zhongwencool/observer_cli/v2.0.0/install.sh | sh安装完成后,根据提示将$HOME/.local/bin加入 PATH:
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc source ~/.bashrc验证安装:
observer_cli --version4.2 作为依赖集成到项目中
如果你需要在目标节点永久安装,可以将其加入项目依赖。
Erlang 项目(rebar.config):
{deps, [ {observer_cli, "2.0.0"} ]}.然后编译:
rebar3 compileElixir 项目(mix.exs):
defp deps do [ {:observer_cli, "2.0.0"} ] end编译:
mix deps.get mix compile4.3 从源码构建
如果需要特定版本或自定义修改,可以从源码构建:
VERSION=2.0.0 git clone --branch "v${VERSION}" --depth 1 \ https://github.com/zhongwencool/observer_cli.git cd observer_cli # 使用 rebar3 构建 rebar3 escriptize cp _build/default/bin/observer_cli ~/.local/bin/ # 或使用 mix 构建(Elixir 环境) mix deps.get mix escript.build cp observer_cli ~/.local/bin/5. 连接目标节点配置
在使用 observer_cli 之前,需要配置与目标节点的连接。
5.1 设置连接信息
安全起见,建议使用环境变量存储 cookie:
export OBSERVER_CLI_COOKIE='your_node_cookie_here'建立连接配置:
observer_cli connect \ --node myapp@server-host \ --cookie-env OBSERVER_CLI_COOKIE这个命令会保存连接配置,后续命令无需重复指定节点信息。
5.2 验证连接状态
# 检查连接状态 observer_cli status # 运行基础诊断 observer_cli diagnose # 断开连接(清理配置) observer_cli disconnect重要安全提醒:分布式的 cookie 具有完整节点访问权限,不是只读凭证。仅连接可信节点,并在可信网络中使用。
6. 监督树可视化实战
监督树是 OTP 应用的核心架构,observer_cli 可以清晰展示其层次结构。
6.1 启动 TUI 界面
observer_cli tui myapp@server-host启动后会进入交互式界面,使用方向键导航。
6.2 查看应用监督树
在 TUI 中:
- 按
a键进入 Applications 页面 - 选择你要查看的应用
- 按
Enter进入详情页 - 选择 "Supervision Tree" 视图
你会看到类似这样的结构:
my_app_sup ├── worker_1 ├── worker_2 └── dynamic_sup ├── dyn_worker_1 └── dyn_worker_26.3 理解监督树信息
监督树视图显示的关键信息:
- 进程ID:每个监督者和工作进程的唯一标识
- 重启策略:one_for_one、one_for_all、rest_for_one
- 子进程规格:worker 或 supervisor
- 状态:运行中、已终止、重启中
6.4 命令行方式获取监督树
对于自动化场景,可以使用 CLI 命令:
observer_cli inspect --type supervision myapp@server-host输出会以结构化文本或 JSON 格式展示监督树。
7. 进程状态监控与分析
除了监督树,observer_cli 提供详细的进程级监控。
7.1 进程排名视图
在 TUI 中按p进入进程页面,可以看到按各种指标排序的进程列表:
- 内存占用:找出内存泄漏的进程
- 消息队列长度:发现消息积压问题
- Reductions:识别 CPU 密集型进程
- 堆大小:监控内存使用模式
7.2 单个进程详情
选择特定进程后可以查看详细信息:
- 进程状态:running、waiting、garbage collecting
- 当前函数:进程正在执行的代码位置
- 堆栈跟踪:最近的函数调用历史
- 消息队列内容:等待处理的消息数量
- 内存分配详情:二进制数据、ETS 表引用等
7.3 进程跟踪功能
对于问题诊断,可以启用有界函数跟踪:
observer_cli trace --pid "<0.123.0>" --function "my_module:my_fun" --duration 5000这个功能需要节点全局同意,适合调试生产环境问题。
8. 系统级性能指标
observer_cli 不仅关注进程级指标,还提供系统级视角。
8.1 内存分配器分析
在 TUI 中按m进入内存页面,查看:
- 总内存使用:包括进程、ETS、原子表等
- 分配器统计:每个分配器的区块大小和数量
- 二进制数据:引用和堆二进制分布
- 系统内存:与操作系统内存的关联
8.2 调度器监控
按s查看调度器状态:
- 调度器利用率:每个调度器的忙碌程度
- 负载均衡:检查工作是否均匀分布
- 端口调度:I/O 端口的活动情况
8.3 网络和分布式监控
对于分布式系统,网络活动很关键:
- 节点连接:当前连接的远程节点
- 消息流量:节点间消息传输统计
- 端口活动:网络端口的读写操作
9. 自动化与集成应用
observer_cli 的 CLI 模式非常适合自动化场景。
9.1 定期健康检查
创建监控脚本:
#!/bin/bash # health_check.sh output=$(observer_cli diagnose --node myapp@server-host --format json) # 解析 JSON 输出,检查关键指标 error_count=$(echo "$output" | jq '.findings | map(select(.severity == "error")) | length') if [ "$error_count" -gt 0 ]; then echo "CRITICAL: Found $error_count issues" exit 1 else echo "OK: System healthy" exit 0 fi9.2 CI/CD 集成
在部署流程中加入诊断:
# 部署后验证 observer_cli diagnose --node new_deploy@server-host # 检查特定指标 observer_cli inspect --metric memory_usage --threshold 809.3 API 集成示例
虽然 observer_cli 本身是命令行工具,但可以包装成 HTTP API:
import subprocess import json def get_system_health(node_name): try: result = subprocess.run([ 'observer_cli', 'diagnose', '--node', node_name, '--format', 'json' ], capture_output=True, text=True, timeout=30) if result.returncode == 0: return json.loads(result.stdout) else: return {'error': result.stderr} except Exception as e: return {'error': str(e)}10. 高级功能与插件系统
observer_cli 支持插件扩展,可以自定义监控页面。
10.1 内置插件使用
当前版本包含多个有用的插件:
- ETS 表监控:查看所有 ETS 表的状态和内存使用
- Mnesia 表分析:监控分布式数据库表
- 端口监控:跟踪外部端口通信
- 套接字统计:网络连接详情
10.2 自定义插件开发
创建自定义监控页面:
-module(my_plugin). -behaviour(observer_cli_plugin). -export([hierarchy/0, sheet/2]). hierarchy() -> [#{id => my_metrics, title => "My Metrics"}]. sheet(my_metrics, _Node) -> Data = get_my_custom_metrics(), observer_cli_plugin:sheet([ #{title => "Custom Metrics", columns => [ #{title => "Metric", width => 20}, #{title => "Value", width => 10} ], rows => Data} ]).11. 性能优化与最佳实践
在生产环境使用 observer_cli 时,遵循这些最佳实践。
11.1 资源使用优化
observer_cli 本身很轻量,但连接诊断时要注意:
- 诊断频率:避免过高频率的自动诊断影响性能
- 数据量控制:使用
--limit参数限制返回数据量 - 超时设置:为自动化脚本设置合理的超时时间
11.2 安全配置建议
- 网络隔离:仅在可信网络中使用分布式连接
- Cookie 管理:使用环境变量而非硬编码
- 访问控制:限制可连接节点的 IP 范围
- 日志安全:注意日志可能包含敏感信息
11.3 监控策略设计
建立有效的监控策略:
- 分层监控:系统级、应用级、进程级分层采集
- 基线建立:记录正常状态下的指标基线
- 告警阈值:基于基线设置合理的告警阈值
- 趋势分析:关注指标的变化趋势而非绝对值
12. 常见问题与排查方法
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| 连接被拒绝 | Cookie 不匹配或网络不通 | 检查节点状态和 cookie | 验证 cookie 配置,检查防火墙 |
| 命令执行超时 | 节点负载过高或网络延迟 | 检查节点资源使用情况 | 增加超时时间,优化节点性能 |
| TUI 显示乱码 | 终端编码不支持 | 检查 TERM 环境变量 | 设置export TERM=xterm-256color |
| 内存信息不准确 | 节点版本不兼容 | 验证 OTP 版本兼容性 | 升级到支持的 OTP 版本 |
| 插件加载失败 | 插件编译错误或版本不匹配 | 检查插件依赖和编译日志 | 重新编译插件,检查版本兼容性 |
12.1 连接问题深度排查
# 1. 验证节点是否可访问 ping server-host # 2. 检查 Erlang 分布式连接 erl -sname test -setcookie MyCookie # 在 Erlang shell 中尝试连接 net_adm:ping('myapp@server-host'). # 3. 验证 observer_cli 配置 observer_cli status12.2 性能数据异常分析
当发现性能指标异常时:
- 确认数据真实性:多次采样验证趋势
- 关联分析:结合系统监控数据交叉验证
- 根因分析:从系统级到进程级逐层下钻
- 影响评估:确定问题对业务的影响程度
13. 与传统图形界面对比
observer_cli 与 Erlang 自带的 observer GUI 工具相比各有优势:
observer_cli 优势:
- 无需图形界面,纯命令行操作
- 适合远程服务器和自动化场景
- 资源消耗更小
- 输出格式标准化,易于解析
图形界面 observer 优势:
- 可视化更直观,适合初学者
- 实时刷新,交互体验更好
- 图表展示,趋势更明显
选择建议:
- 生产环境运维:优先选择 observer_cli
- 开发调试:根据习惯选择,两者都可
- 自动化集成:必须使用 observer_cli
14. 实际案例:诊断内存泄漏问题
通过一个真实场景展示 observer_cli 的实际价值。
14.1 问题现象
应用运行一段时间后内存持续增长,最终被 OOM Killer 终止。
14.2 诊断步骤
# 1. 连接问题节点 observer_cli connect --node problematic@server-host # 2. 运行全面诊断 observer_cli diagnose --format json > diagnosis.json # 3. 分析内存排名 observer_cli inspect --type processes --sort memory --limit 1014.3 发现根本原因
通过进程内存排名发现某个进程的消息队列堆积了大量消息,进一步分析发现是消息处理逻辑存在缺陷,导致消息无法被及时消费。
14.4 解决方案
修复消息处理逻辑,增加流控机制,问题得到解决。
observer_cli 为 Erlang/Elixir 开发者提供了强大的命令行诊断能力,特别适合生产环境运维和自动化场景。通过本文的实践指南,你可以快速掌握其核心功能,并将其应用到实际工作中。建议从连接本地开发环境开始练习,逐步扩展到测试和生产环境的使用。