资讯中心

智能运维的 ChatOps 实践——用自然语言查询日志、指标和调用链

📅 2026/7/25 6:06:18
智能运维的 ChatOps 实践——用自然语言查询日志、指标和调用链
智能运维的 ChatOps 实践——用自然语言查询日志、指标和调用链一、运维效率的现实困境作为架构师我经常在凌晨被值班电话叫醒。问题通常是订单接口响应慢了帮看看是什么原因 排查问题的标准流程是打开 Grafana 看指标 → 打开 Kibana 搜日志 → 打开 Jaeger 查调用链 → 关联分析 → 定位根因。这个过程熟练的工程师需要15-20分钟不熟悉系统的同事可能需要半小时以上。有没有可能让运维人员用自然语言直接提问由系统自动完成跨系统的数据查询和分析这就是 ChatOps 在运维领域的核心价值。二、ChatOps 运维系统的整体架构系统的核心是意图识别与路由——准确判断用户的自然语言提问属于哪种数据类型日志、指标、调用链或知识问答然后调用对应的查询引擎获取原始数据最终由LLM汇总分析生成答案。三、意图识别与路由实现/** * ChatOps意图识别与路由服务 * 将用户的自然语言问题分类路由到对应的数据查询引擎 */ Service public class IntentRouterService { /** 定义支持的意图类型 */ public enum IntentType { METRICS_QUERY, // 指标查询如CPU使用率多少 LOG_SEARCH, // 日志搜索如最近5分钟有哪些ERROR日志 TRACE_QUERY, // 调用链查询如订单接口的调用耗时分布 KNOWLEDGE_QA, // 知识问答如订单超时应该怎么排查 DIAGNOSTIC // 综合诊断如订单服务为什么变慢了 } private final AiServiceClient aiClient; private final MetricsQueryEngine metricsEngine; private final LogSearchEngine logEngine; private final TraceQueryEngine traceEngine; private final KnowledgeService knowledgeService; public IntentRouterService( AiServiceClient aiClient, MetricsQueryEngine metricsEngine, LogSearchEngine logEngine, TraceQueryEngine traceEngine, KnowledgeService knowledgeService) { this.aiClient aiClient; this.metricsEngine metricsEngine; this.logEngine logEngine; this.traceEngine traceEngine; this.knowledgeService knowledgeService; } /** * 处理用户提问——识别意图并路由到对应引擎 */ public ChatResponse handleQuery(String userQuestion) { // 步骤1: 使用LLM识别意图 IntentType intent classifyIntent(userQuestion); // 步骤2: 根据意图调用对应的查询引擎 String rawData; switch (intent) { case METRICS_QUERY - rawData metricsEngine.query(userQuestion); case LOG_SEARCH - rawData logEngine.search(userQuestion); case TRACE_QUERY - rawData traceEngine.query(userQuestion); case KNOWLEDGE_QA - rawData knowledgeService.search(userQuestion); case DIAGNOSTIC - rawData performFullDiagnosis(userQuestion); default - throw new IllegalArgumentException(不支持的意图类型: intent); } // 步骤3: 由LLM汇总分析并生成最终回复 return buildFinalResponse(userQuestion, intent, rawData); } /** * 综合诊断——同时查询多个数据源并关联分析 */ private String performFullDiagnosis(String question) { // 并行查询所有数据源 CompletableFutureString metricsFuture CompletableFuture.supplyAsync(() - metricsEngine.query(question)); CompletableFutureString logFuture CompletableFuture.supplyAsync(() - logEngine.search(question)); CompletableFutureString traceFuture CompletableFuture.supplyAsync(() - traceEngine.query(question)); // 等待所有查询完成 CompletableFuture.allOf(metricsFuture, logFuture, traceFuture).join(); StringBuilder combined new StringBuilder(); try { combined.append(【指标数据】\n).append(metricsFuture.get()).append(\n\n); combined.append(【日志摘要】\n).append(logFuture.get()).append(\n\n); combined.append(【调用链数据】\n).append(traceFuture.get()); } catch (InterruptedException | ExecutionException e) { Thread.currentThread().interrupt(); throw new DiagnosticException(综合诊断数据收集失败, e); } return combined.toString(); } }四、自然语言到 PromQL 的转换将自然语言转换为 Prometheus 查询语句PromQL是 ChatOps 的核心能力之一。我们采用 few-shot prompt Schema Injection 的方案来实现。/** * 自然语言到PromQL的转换引擎 * 将运维人员的日常问法转换为结构化的PromQL查询 */ Component public class NaturalLanguageToPromQLConverter { private final AiServiceClient aiClient; /** Prometheus监控指标Schema帮助LLM理解有哪些指标可用 */ private static final String METRICS_SCHEMA 可用指标列表 - http_server_requests_seconds_count{uri, method, status} : HTTP请求总数 - http_server_requests_seconds_sum{uri, method, status} : HTTP请求总耗时 - jvm_memory_used_bytes{area} : JVM内存使用量 - jvm_gc_pause_seconds_count{action, cause} : GC停顿次数 - jvm_gc_pause_seconds_sum{action, cause} : GC停顿总时间 - system_cpu_usage : 系统CPU使用率 - tomcat_threads_current{name} : Tomcat当前线程数 ; public NaturalLanguageToPromQLConverter(AiServiceClient aiClient) { this.aiClient aiClient; } /** * 将自然语言问题转换为PromQL * param question 如订单接口过去5分钟的平均响应时间是多少 * return PromQL语句 */ public String convert(String question) { String prompt 你是一个PromQL专家请将以下自然语言问题转换为PromQL查询语句。 %s 【转换示例】 问题CPU使用率是多少 PromQL: 100 - (avg(rate(node_cpu_seconds_total{modeidle}[5m])) * 100) 问题最近5分钟的错误请求数 PromQL: sum(rate(http_server_requests_seconds_count{status~5..}[5m])) 请仅输出PromQL语句不要包含任何解释。 问题%s PromQL .formatted(METRICS_SCHEMA, question); String promQL aiClient.chat(prompt); // 清洗输出移除可能的markdown代码块标记 return promQL.replaceAll(promql|, ).trim(); } }五、结果的关联分析ChatOps 最有价值的场景是综合诊断——当用户提出订单服务为什么变慢了这类开放性问题时系统需要同时查询多个数据源并进行关联分析。/** * 多源数据关联分析服务 * 将分散的日志、指标、调用链数据关联起来推导根因 */ Service public class CrossSourceCorrelationAnalyzer { private final AiServiceClient aiClient; public CrossSourceCorrelationAnalyzer(AiServiceClient aiClient) { this.aiClient aiClient; } /** * 多源数据关联分析 * param metricsData Prometheus指标数据 * param logData Elasticsearch日志摘要 * param traceData Jaeger调用链数据 * param timeRange 时间范围 * return 关联分析报告 */ public String analyze(String metricsData, String logData, String traceData, String timeRange) { String prompt 你是一名资深运维专家请根据以下多维度监控数据 分析系统可能存在的问题并按可能性从高到低给出根因推断。 【时间范围】%s 指标数据 %s 日志摘要 %s 调用链数据 %s 请按以下格式输出分析结果 1. 异常现象总结一句话 2. 可能根因列表按可能性排序每条50字以内 3. 建议排查步骤3-5步 4. 是否需要立即告警是/否 .formatted(timeRange, metricsData, logData, traceData); return aiClient.chat(prompt); } }六、安全与权限控制运维数据涉及系统敏感信息ChatOps 必须做好权限控制。我们设计了三层权限校验第一层用户身份认证。与企业的SSO系统集成只有通过认证的用户才能使用ChatOps服务。第二层数据权限控制。不同角色的用户查询范围不同。开发人员只能查询开发环境的指标值班运维可以查询生产环境。第三层操作审计。所有查询请求都记录审计日志包含查询人、查询时间、查询内容和返回结果摘要。七、实践数据与反思在我们的实践中ChatOps上线三个月后的核心数据平均故障排查时间从18分钟降低到7分钟减少61%凌晨值班的查询请求占比45%说明在人力覆盖不足的时段价值最大意图识别准确率87%主要的误识别集中在MEM vs CPU这类有歧义的缩写上当前方案最大的不足是对于涉及多系统、多时间段的复杂故障LLM的关联推理能力还不够经常把相关关系误判为因果关系。这是我们下一步优化的重要方向。七、ChatOps 的权限与审计深化运维数据涉及系统敏感信息ChatOps 必须做好权限控制。我们设计了三层权限校验第一层用户身份认证。与企业的SSO系统集成只有通过认证的用户才能使用ChatOps服务。第二层数据权限控制。不同角色的用户查询范围不同。开发人员只能查询开发环境的指标值班运维可以查询生产环境。第三层操作审计。所有查询请求都记录审计日志包含查询人、查询时间、查询内容和返回结果摘要。在实际应用中我们发现权限控制的粒度设计非常关键。过于粗粒度的权限如运维角色可以查所有数据会导致敏感信息泄露风险过于细粒度如每个指标都单独授权则会让系统变得难用。我们的实践经验是采用环境服务的二级权限模型先按环境开发/测试/预发布/生产做粗粒度隔离再按服务线做细粒度隔离。这样既能保证安全性又不会过度增加使用成本。ChatOps 不是要替代运维工程师而是让工程师从重复的查询操作中解放出来将精力聚焦在架构优化和故障预防上。工具服务于人这个定位不能变。