Hermes Agent日志监控实战:从ELK采集到OTLP导出
【免费下载链接】hermes-agentThe agent that grows with you项目地址: https://gitcode.com/GitHub_Trending/he/hermes-agent
本文交付一套可运行的Hermes Agent 日志监控方案:用项目自带的日志文件与脱敏模块,把会话日志收进 Elasticsearch 做集中查询,再通过 OTLP 把网关健康信号导到你自己的可观测平台。读者需会 Docker 和命令行,已跑过 Hermes Agent,目标是搭出集中式日志检索与告警。
前置条件:日志在哪里、需要哪些工具
Hermes Agent 运行后会在用户主目录留下两类核心数据,先确认它们存在:
- 会话数据:
~/.hermes/sessions/下的 JSON 文件,每个文件是一次完整会话的交互记录 - 运行日志:
~/.hermes/logs/下的agent.log(INFO 及以上)和errors.log(WARNING 及以上),已内置轮转
在此基础上做集中监控有两条路线,按团队现状二选一即可:
| 对比项 | 路线 A:ELK Stack | 路线 B:OTLP 导出 |
|---|---|---|
| 采集对象 | 本地日志文件(agent.log / errors.log / sessions) | 网关健康事件(内存事件,不落盘) |
| 额外组件 | Elasticsearch + Logstash + Kibana | 任意 OTel Collector / DataDog 等 |
| 适合谁 | 没有现成可观测平台,想自建 | 已有 OTel、DataDog 等统一平台 |
| 接入成本 | 高(要跑 3 个容器) | 低(装一个可选依赖 + 改配置) |
如果你们公司已经有统一监控栈,优先走路线 B,别重复造一套 Kibana。下面的实操按两个路线分开推进。
场景一:把日志文件收进 Elasticsearch
这条路线的本质是一条"传送带":Logstash 盯住日志目录,新写入的行解析后推给 Elasticsearch,Kibana 负责展示。
最小可用的 Logstash 管道
# logstash-hermes.conf —— 采集日志文件并写入 ES input { file { path => ["/HOME/.hermes/logs/*.log"] start_position => "beginning" codec => "plain" } } filter { date { match => ["timestamp", "ISO8601"] } } output { elasticsearch { hosts => ["http://localhost:9200"] index => "hermes-logs-%{+YYYY.MM.dd}" } }这段配置做三件事:盯住~/.hermes/logs/目录、把 ISO8601 时间戳提出来做索引字段、按天滚动索引名。注意start_position => "beginning"只在首次部署时用,之后 Logstash 靠 sincedb 记住读到哪里,避免重复采集。
用 Docker Compose 拉起 ELK
# docker-compose.yml —— 单机版 ELK 三件套 services: elasticsearch: image: elasticsearch:8.11.3 environment: - discovery.type=single-node - ES_JAVA_OPTS=-Xms512m -Xmx512m ports: ["9200:9200"] logstash: image: logstash:8.11.3 volumes: - ./logstash-hermes.conf:/usr/share/logstash/pipeline/logstash.conf depends_on: [elasticsearch] kibana: image: kibana:8.11.3 ports: ["5601:5601"] depends_on: [elasticsearch]这段 YAML 只暴露两个端口:9200 给 Logstash 写入,5601 给人看 Kibana。ES_JAVA_OPTS 按 512MB 起步,日志量大再往上调。
Kibana 里看什么
建四个核心面板就够日常使用:
- 活跃会话数:对
hermes-logs-*按会话字段做 distinct count - 错误率:
errors.log来源的行数 / 总行数,按小时聚合 - 响应时间分布:API 调用延迟的 P50/P95 直方图
- 资源消耗:宿主机 CPU、内存、磁盘(可用 Filebeat 或节点 exporter 补,不展开)
场景二:网关健康信号走 OTLP 进自有平台
会话管理界面上能看到每个会话的来源与状态(侧边栏按 Cron、Telegram、Discord、Webui 分组,150 个会话里 884 个归档可见):
但会话面板解决不了"网关本身健不健康"的问题——进程有没有卡住、事件循环有没有堆积、诊断信息如何批量上报。这部分由 网关监控模块 承担,它是项目内置的一条独立出口:
emitter:进程内事件总线,生产者把类型化事件丢进队列,OTLP 订阅者异步消费,导出失败不会阻塞网关热路径otlp_exporter:把gateway_health/gateway_diagnostic事件映射为 OTel span,发到运维配置的端点,本地不持久化任何监控数据policy/redaction:决定哪些事件可导出、导出前如何脱敏
接入只需两步:
# 安装可选依赖(OTel SDK 是 lazy 导入,不用就不需要) pip install 'hermes-agent[otlp]'这段命令装 OpenTelemetry SDK 和 OTLP HTTP exporter。然后在~/.hermes/config.yaml中配置导出端点,关键字段只有三个:
# config.yaml 中监控导出配置(字段名以实际配置项为准) monitoring: export: otlp: endpoint: "http://otel-collector:4318/v1/traces" headers_env: # header 名 -> 环境变量名,值从不落盘 Authorization: "OTLP_AUTH_TOKEN"这段 YAML 指向你的 Collector 端点;headers_env的设计值得注意——它只存"哪个环境变量名",真正的 token 在导出时才从环境读取,天然避免凭证出现在配置文件里。
选路线 B 后,DataDog 或 Kibana(接 OTel 的场景)里就能直接查 span 级别的网关健康度,不用维护本地日志采集链路。
进阶与调优
脱敏:别让凭证流进日志管道
日志一集中,风险也从单台机器扩散到整个检索平台。项目默认开启了正则脱敏,逻辑在 日志脱敏模块:
- 短于 18 字符的 token整段打码
- 更长的 token 保留前 6 位和后 4 位,兼顾排查
- 覆盖 URL query 参数(
access_token、signature等 17 个键名)和请求体中的敏感字段,精确匹配避免误伤session_id这类正常字段 - 开关在进程启动时快照(
HERMES_REDACT_SECRETS,默认 true),会话中途无法被代码或 LLM 生成命令关闭——这是防提示注入的关键设计
验证方法很简单:往agent.log里喂一条含api_key=sk-xxxx的模拟请求,确认落盘后只剩前后几位。如果你确实需要关闭脱敏(比如你在改脱敏器本身),改security.redact_secrets: false,启动时会有明确的降级告警。
索引生命周期与容量
按天滚动索引(hermes-logs-%{+YYYY.MM.dd})后,给 ES 配 ILM 策略即可控住磁盘:
- 热阶段 7 天:正常查询、副本 1
- 温阶段 30 天:只读、副本 0
- 冷阶段 90 天:转对象存储或快照
- 365 天后删除
会话 JSON 文件体积增长快,历史数据可用项目自带轨迹压缩思路处理:轨迹生成模块 和 上下文压缩 提供了把长会话压成训练用摘要的现成代码,比直接堆原始 JSON 省空间。
查询性能
- 给
hermes-logs-*建一个别名hermes-logs,Kibana 查询只打别名,ILM 滚索引时查询不用改 - 单机 ES 分片数保持默认(1 主分片),日增量低于 50GB 时不要手动加分片
- 高频面板只查时间窗内数据,
datefilter 放在查询最前面
避坑与答疑
日志没进 ES:按顺序查三处——Logstash 容器日志里有没有Could not open the file(路径和权限问题,确认容器能读到宿主目录);curl localhost:9200是否返回 200;logstash-hermes.conf用bin/logstash --config.test_and_exit先做语法检查。
OTLP 导出报OTLPUnavailable:这是可选依赖没装,pip install 'hermes-agent[otlp]'即可。如果环境禁止懒安装(security.allow_lazy_installs关闭),安装会静默失败并回落到这个异常,属于预期行为。
Kibana 时间轴错乱:Logstash 没配datefilter 时会用采集时间而不是日志时间。确认filter段的match里时间戳格式和agent.log实际格式一致,不一致时先用一条真实日志样本调试。
告警误报多:错误率告警别用绝对阈值,改成"5 分钟窗口内 errors.log 行数超过历史同窗口 P95 的 2 倍"。样本期至少覆盖一个完整工作日,周末和周中错误模式差异大,分桶统计再设阈值。
~/.hermes/logs/权限报错:Logstash 容器内是 root,但挂载卷的属主要对得上;compose 里给 logstash 加user: "1000:1000"(对应宿主机运行 Hermes 的 UID)通常能直接解决。
交付清单
对照自检,全部勾完才算这条监控链路可用:
~/.hermes/logs/下agent.log、errors.log正常增长且轮转生效- Logstash 容器连续运行 24 小时无
sincedb越界或重复采集 - ES 中日滚动索引正常生成,别名
hermes-logs可查 - Kibana 四个面板(会话数 / 错误率 / 延迟分布 / 资源)有数据
- 脱敏验证:模拟含密钥的请求,落盘日志中只剩前后几位
- 若走 OTLP 路线:Collector 端收到
gateway_healthspan,且导出失败实验不拖慢网关 - ILM 策略生效:热→温阶段自动迁移,磁盘无无限增长
- 端到端延迟抽测:日志产生到 Kibana 可查,间隔在分钟级以内(Logstash 批量刷盘)
下一步建议:把错误率面板接到你们的值班通道(Webhook 即可),并挑一个真实排障场景走一遍"告警 → 检索 → 定位会话 JSON"的闭环,跑通后这套体系才算真正落地。
【免费下载链接】hermes-agentThe agent that grows with you项目地址: https://gitcode.com/GitHub_Trending/he/hermes-agent
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考