导语

  • ELK-MCP 是一个面向工作流集成的日志查询后端,兼容 Elasticsearch 6.5.4 查询 DSL,强调“字段精简 + 分页上限 + 长消息截断”的稳健策略,解决跨系统调用的响应体过大问题,为 Dify 工作流提供稳定、可扩展的日志检索能力。
  • 项目支持多租户与权限预留、严格的安全与性能红线,并在部署与调用层面给出清晰路径与实践建议。

ELK-MCP体验地址

  • github:https://github.com/magicCzc/ELK-MCP
  • gitee:https://gitee.com/magicCzc/ELK-MCP

1. 为什么做这个项目

  • 背景:工作流平台(如 Dify)对单次响应大小有上限(常见阈值约 1MB)。传统日志查询常返回大量字段与大页数据,容易触发 “Text size is too large”,导致链路不稳定。
  • 目标:将后端响应控制在安全范围内,优先保障调用成功率;分层抽象与规范接口,便于在工作流实现分页与时间切片;兼容 ES 6.5.4,方便存量系统接入;遵守安全与性能红线。

2. 架构与目录概览

在这里插入图片描述

graph TD
  A[Dify 工作流] -->|HTTP POST /api/logs/query| B[elk-MCP 后端]
  B --> C[ES 查询适配器 (es/query_adapter.py)]
  B --> D[日志归一化与截断 (logs/normalizer.py)]
  B --> E[路由与模型 (routes/, models/)]
  C --> F[(Elasticsearch 6.5.4)]
  • 后端(Python,PEP8 & black 行宽 88):
    • backend/app/es/:ES 查询适配器与 DSL 构造
    • backend/app/logs/:日志归一化与字段截断(normalizer.py
    • backend/app/routes/:接口路由(如 /api/logs/query
    • backend/app/models/:Pydantic 模型(输入校验)
    • backend/app/config.py:环境配置集中管理
  • 文档:backend/docs/(API、部署、架构、运维)
  • TypeScript schemas:schemas-ts/(Airbnb ESLint 规范)

3. 关键特性与设计取舍

  • ES6 DSL 兼容:query_adapter 适配查询语法与分页。
  • 精简字段:DSL 使用 _source.includes 仅返回必要字段,避免冗余导致响应过大。
  • 分页上限:通过 MAX_PAGE_SIZE 控制单页最大条数(建议 20),稳定响应大小。
  • 长消息截断:MAX_MESSAGE_LEN 默认 4096 字符,对超长 message 进行安全截断。
  • 国际化预留:前端与文档遵循 i18n key 约束;后端不硬编码中文文案(接口返回为数据字段)。
  • 安全与性能:不在前端硬编码敏感信息;后端输入二次校验;遵循冷启动与 p95 指标。

4. 快速开始与环境配置

安装依赖(建议虚拟环境)

pip install -r backend/requirements.txt

配置环境变量

  • 复制 backend/.env.examplebackend/.env 并按需填写:
ES_HOSTS=http://localhost:9200
DEFAULT_INDEX=logs-*
TIMESTAMP_FIELD=@timestamp
MAX_PAGE_SIZE=20
MAX_MESSAGE_LEN=4096
LOG_DOC_TYPE=

启动后端

python backend/app/main.py

健康检查与接口调用

  • 健康检查:GET /health
  • 查询接口:POST /api/logs/query

5. 响应体大小控制“三件套”

  • 精简字段:在 ES DSL 中设置 _source.includes 为必要字段(如 _id, @timestamp, level, service, message)。
  • 分页上限:后端将 page_size 限制到 MAX_PAGE_SIZE,避免单页过大。
  • 长消息截断:在 normalize() 中对 message 超长部分进行截断,保留关键信息与标记。
    在这里插入图片描述
flowchart LR
  Q[Query 请求] --> S[DSL 构造: _source.includes]
  S --> P[分页上限: MAX_PAGE_SIZE]
  P --> N[归一化: message 截断]
  N --> R[响应返回 (JSON < 1MB)]

6. API 用法与示例

  • 路由:POST /api/logs/query
  • 请求参数(节选):
    • start_time, end_time:时间范围(ISO8601)
    • level, service:过滤条件
    • query_string:全文检索
    • page, page_size:分页参数(由后端上限保护)

请求示例

POST /api/logs/query
Content-Type: application/json

{
  "start_time": "2025-11-15T00:00:00Z",
  "end_time": "2025-11-16T00:00:00Z",
  "level": "ERROR",
  "service": "order-service",
  "query_string": "timeout OR retry failed",
  "page": 1,
  "page_size": 20
}

响应示例(字段精简 + 消息可能截断)

{
  "total": 1245,
  "page": 1,
  "page_size": 20,
  "hits": [
    {
      "_id": "abc123",
      "@timestamp": "2025-11-15T08:43:10Z",
      "level": "ERROR",
      "service": "order-service",
      "message": "Timeout contacting payment gateway... [TRUNCATED]"
    }
  ]
}

7. Dify 工作流集成(分页循环与时间切片)

分页循环(推荐)
在这里插入图片描述

flowchart TD
  A[初始化变量 current_page=1, page_size=20, all_hits=[]] --> B[HTTP 请求 /api/logs/query]
  B --> C{current_page * page_size < total?}
  C -- 是 --> D[累加 all_hits += hits]
  D --> E[递增 current_page += 1]
  E --> B
  C -- 否 --> F[输出 all_hits]

时间切片(大数据量日查询)

  • 将一天切分为 24 小时窗口,对每个窗口执行分页遍历;避免一次响应过大,利于失败重试与并发。
  • 防超限建议:保持 page_size=20,必要时进一步截断展示字符串。

8. 性能与安全红线

  • 性能目标:冷启动 ≤ 2s;接口 p95 ≤ 800ms。
  • 安全约束:
    • 禁止在前端硬编码敏感信息(如 OPENAI_API_KEY)。
    • 所有输入进行二次校验(后端 Pydantic;前端 zod 预留)。
    • 依赖选择避免 GPL/LGPL;新增库需说明理由与包大小估算。

9. 常见问题与排错

  • 响应过大导致调用失败:
    • 缩小 page_size(建议 20),确认 _source.includes 精简字段,开启 message 截断。
  • ES 版本兼容:
    • 本项目针对 ES 6.5.4 适配;升级 ES 版本时需复核 DSL 语法与字段。

10. 未来规划与结语

  • 规划:更细粒度租户隔离与审计、Scroll 滚动查询接口、完整 i18n 方案对接与消息模板体系。
  • 结语:ELK-MCP 在工程策略上“做减法”,以“字段精简 + 分页上限 + 长消息截断”稳定跨系统调用,保障 Dify 工作流的可靠性与可维护性。欢迎通过 Issue 或邮件反馈建议,一起打磨更稳健的日志检索后端。

附:示例命令速查

  • 安装依赖:pip install -r backend/requirements.txt
  • 启动服务:python backend/app/main.py
  • 查询接口:POST /api/logs/query
  • SSH 验证:ssh -T git@github.com
  • 推送到远程:git push -u origin main
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐