作者:来自 Elastic David Hope
生成式 AI 和机器学习正在革新观测技术,但数据孤岛阻碍了它们的真正潜力。本文探讨了如何通过 OpenTelemetry 统一日志、指标和追踪,打破数据孤岛,释放生成式 AI 在自然语言调查、自动根因分析和主动问题解决中的全部能力。
当今观测行业正处于关键时刻。虽然我们的应用产生的遥测数据比以往任何时候都多,但这些丰富的信息通常分散在不同的孤岛工具中,日志、指标和追踪数据各自独立。与此同时,生成式 AI 正如一颗即将撞击行业的巨型小行星,迅猛而至。
作为 SRE(站点可靠性工程师),我们习惯于在排查问题时频繁切换仪表盘、日志聚合器和追踪可视化工具。但如果有更好的方法呢?如果 AI 能整体分析所有观测数据,用自然语言回答复杂问题,并自动识别根因呢?
这就是观测的下一次进化。但要驾驭这股力量,我们必须重新思考如何收集、存储和分析遥测数据。
问题所在:数据孤岛限制了 AI 的效能
传统观测架构将数据分为不同类型:
-
指标(Metrics):随时间变化的数值测量(CPU、内存、请求速率)
-
日志(Logs):带时间戳和上下文的详细事件记录
-
追踪(Traces):分布式系统中的请求路径
-
性能分析(Profiles):代码级执行模式,显示函数或代码行的资源消耗和性能瓶颈
这种分离在过去符合行业发展逻辑,因为不同数据类型的基数、结构、访问模式和数据量各异。但这种方法给 AI 驱动的分析带来了巨大挑战:
Metrics (Prometheus) → "CPU spiked at 09:17:00"
Logs (ELK) → "Exception in checkout service at 09:17:32"
Traces (Jaeger) → "Slow DB queries in order-service at 09:17:28"
Profiles (pyroscope) -> "calculate_discount() is taking 75% of CPU time"
当这些数据源分散在不同系统中时,AI 工具必须:
-
处理不完整的信息(只能看到指标,却无法关联到日志)
-
依赖复杂且脆弱的集成,这常常导致时间不同步的问题
-
迫使开发者手动跨工具进行信息关联
想象一下,你问 AI:“为什么 09:17 时结账延迟激增?”要全面回答,它需要访问日志(查看堆栈信息)、追踪(了解服务调用路径)和指标(识别资源压力)。但由于工具孤岛,AI 只能看到故事的碎片,或者需要执行比故障本身还慢的复杂 ETL 任务。
传统机器学习(ML)的局限
传统的观测机器学习通常只专注于单一数据维度的异常检测。它能告诉你指标何时偏离正常模式,但难以提供上下文或根因分析。
仅用指标训练的 ML 模型可能会检测到延迟激增,但无法关联到日志中的最新部署,也不能识别出问题只影响特定数据库端点(这些信息分别藏在日志和追踪中)。它们就像只看到了部分信息且只能看到特定供应商允许看的有限视角的人类。
这种局限在现代微服务架构中尤为突出,问题常常跨服务蔓延。没有统一视图,传统 ML 只能发现症状,难以找到根本原因。
解决方案:统一数据与丰富日志
这个解决方案看似简单,但却极具变革性:将指标、日志和追踪统一存储,理想状态下是用丰富的日志来实现 —— 每条日志是一个包含请求所有信号的完整 JSON 文档。我们即将看到信号的融合。
传统日志只是简单的文本行:
[2025-05-19 09:17:32] ERROR OrderService - Failed to process checkout for user 12345
而丰富日志不仅包含错误信息,还包括:
-
完整的分布式追踪上下文
-
该时刻相关的指标数据
-
系统环境细节
-
业务上下文(用户 ID、购物车金额等)
这种方式创造了一个整体视图,将同一事件的所有信号并列摆放,非常适合 AI 进行分析。
生成式 AI 带来的改变
生成式 AI 与传统机器学习的根本区别在于它能:
-
处理非结构化数据:理解自由格式的日志消息和错误文本
-
保持上下文关联:连接跨时间和服务的相关事件
-
回答自然语言查询:将人类问题转化为复杂的数据分析
-
生成解释说明:在结论中附带推理过程
-
发现隐藏模式:挖掘日志中难以人工分析或传统查询发现的关联和异常
借助统一的观测数据,生成式 AI 能够分析完整的系统行为模式,关联此前分散的信号。
举例来说,当被问到“为什么我们的结账服务变慢了?”时,拥有统一数据访问权限的生成式 AI 可以:
-
分析统一的丰富日志,找出具体慢的操作及相关的错误或警告
-
查看附带的指标,了解资源利用情况
-
关联部署事件或配置变更等信号
-
用自然语言给出连贯解释,并附带图表和可视化支持
使用 OpenTelemetry 实现统一观测
OpenTelemetry 以其在指标、日志和追踪中的一致模式,为统一观测提供理想基础。以下是如何在 Java 应用中实现丰富日志的示例:
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.api.metrics.DoubleHistogram;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.context.Scope;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import java.lang.management.ManagementFactory;
import java.lang.management.OperatingSystemMXBean;
public class OrderProcessor {
private static final Logger logger = LoggerFactory.getLogger(OrderProcessor.class);
private final Tracer tracer;
private final DoubleHistogram cpuUsageHistogram;
private final OperatingSystemMXBean osBean;
public OrderProcessor(OpenTelemetry openTelemetry) {
this.tracer = openTelemetry.getTracer("order-processor");
Meter meter = openTelemetry.getMeter("order-processor");
this.cpuUsageHistogram = meter.histogramBuilder("system.cpu.load")
.setDescription("System CPU load")
.setUnit("1")
.build();
this.osBean = ManagementFactory.getOperatingSystemMXBean();
}
public void processOrder(String orderId, double amount, String userId) {
Span span = tracer.spanBuilder("processOrder").startSpan();
try (Scope scope = span.makeCurrent()) {
// Add attributes to the span
span.setAttribute("order.id", orderId);
span.setAttribute("order.amount", amount);
span.setAttribute("user.id", userId);
// Populate MDC for structured logging
MDC.put("trace_id", span.getSpanContext().getTraceId());
MDC.put("span_id", span.getSpanContext().getSpanId());
MDC.put("order_id", orderId);
MDC.put("order_amount", String.valueOf(amount));
MDC.put("user_id", userId);
// Record CPU usage metric associated with the current trace context
double cpuLoad = osBean.getSystemLoadAverage();
if (cpuLoad >= 0) {
cpuUsageHistogram.record(cpuLoad);
MDC.put("cpu_load", String.valueOf(cpuLoad));
}
// Log a structured message
logger.info("Processing order");
// Simulate business logic
// ...
span.setAttribute("order.status", "completed");
logger.info("Order processed successfully");
} catch (Exception e) {
span.recordException(e);
span.setAttribute("order.status", "failed");
logger.error("Order processing failed", e);
} finally {
MDC.clear();
span.end();
}
}
}
这段代码演示了如何:
-
创建一个操作的 span
-
添加业务属性
-
添加当前 CPU 使用率
-
使用一致的 ID 进行关联
-
记录后端系统中的异常和结果
当配置了合适的导出器后,这将生成包含应用事件及其完整上下文的丰富日志。
跨原本分离数据的强大查询能力
即使数据尚未被丰富,依然有希望。首先,借助生成式 AI 驱动的摄取,可以提取关键字段来帮助关联数据,比如 session id。这样可以让你的日志获得所需的结构,从而表现得像其他信号一样。下面展示了 Elastic 的自动导入机制,它能自动生成摄取管道,将非结构化日志信息转换成适合分析的结构化格式。
一旦你把这些数据存储到同一个数据存储中,就可以执行以前无法实现的强大关联查询。例如,查找影响特定 API 端点的慢数据库查询:
FROM logs-nginx.access-default
| LOOKUP JOIN .ds-logs-mysql.slowlog-default-2025.05.01-000002 ON request_id
| KEEP request_id, mysql.slowlog.query, url.query
| WHERE mysql.slowlog.query IS NOT NULL
这个查询将 Web 服务器日志与数据库慢查询日志关联起来,使你能够直接关联用户体验性能与数据库操作。
对于 GenAI 界面,这些复杂查询可以从自然语言问题自动生成:
“Show me all checkout failures that coincided with slow database queries - 显示所有与慢数据库查询同时发生的结账失败”
AI 会将这个问题翻译成针对统一数据存储的合适查询,关联应用错误和数据库性能。
真实场景应用与用例
自然语言调查
想象一下,你向你的观测系统提出这样的问题:
“Why did checkout latency spike at 09:17 yesterday? - 为什么昨天 09:17 结账延迟飙升?”
一个基于 GenAI 且数据统一的系统可能会回答:
“Checkout latency increased by 230% at 09:17:32 following deployment v2.4.1 at 09:15. The root cause appears to be increased MySQL query times in the inventory-service. Specifically, queries to the 'product_availability' table are taking an average of 2300ms compared to the normal 95ms. This coincides with a CPU spike on database host db-03 and 24 'Lock wait timeout' errors in the inventory service logs. - 结账延迟在 09:17:32 增加了 230%,紧跟着 09:15 部署的 v2.4.1 版本。根本原因似乎是 inventory-service 中 MySQL 查询时间增加。具体来说,对 ‘product_availability’ 表的查询平均耗时为 2300ms,而正常为 95ms。同时,数据库主机 db-03 的 CPU 出现峰值,并且在 inventory 服务日志中记录了 24 条 ‘Lock wait timeout’ 错误。”
下面是一个示例,展示 Claude Desktop 连接到 Elastic 的 MCP(模型上下文协议)服务器,演示自然语言调查的强大功能。在这里,我们让 Claude “analyze my web traffic patterns - 分析我的网络流量模式”,你可以看到它正确识别这是在我们的演示环境中。
未知问题检测
GenAI 通过关联多个信号,能够发现孤立系统中容易被忽略的细微模式。例如,它可能发现某个特定客户 ID 仅在通过某条特定微服务网络路径时出现在错误日志中,这表明只有特定用户流程受到数据损坏问题的影响。
预测性维护
通过分析统一历史数据中导致过去故障的模式,GenAI 可以在问题导致故障之前识别潜在风险:
“Warning: Current load pattern on authentication-service combined with increasing error rates in user-profile-service matches 87% of the signature that preceded the April 3rd outage. Recommend scaling user-profile-service pods immediately. - 警告:认证服务当前的负载模式,结合用户资料服务中不断上升的错误率,匹配了 87% 先前 4 月 3 日故障前的特征。建议立即扩展用户资料服务的 pod。”
未来展望:用于观测的自主智能代理 AI
下一阶段的前沿是自主智能代理 AI(Agentic AI),这类系统不仅能够分析,还能自动执行操作。
这些 AI 代理可以:
-
持续监控所有观测信号
-
自动调查异常情况
-
针对已知问题模式实施修复
-
从以往干预的效果中学习
举个例子,一个观测代理可能会:
-
发现某个服务的错误率上升
-
分析日志和追踪,确认存在内存泄漏
-
关联最近的代码变更
-
临时增加内存限制
-
创建包含根因分析的详细工单
-
持续监控修复效果
这就是打造能深刻理解应用行为模式,主动维护系统健康的智能系统。Elastic Observability 的截图里展示了这一流程:在根因分析结束时,系统发送邮件总结,但这也可以触发任何自动化操作。
业务成果
统一观测数据以支持 GenAI 分析带来了切实的好处:
-
更快的问题解决时间:过去需要数小时手动关联的问题,现在秒级诊断
-
减少升级次数:初级工程师能利用 AI 调查复杂问题,减少对专家的依赖
-
提升系统可靠性:更早发现并解决潜在问题
-
改善开发者体验:减少在多个工具间切换的时间
-
优化容量规划:更准确预测资源需求
实施步骤
准备好开始观测转型了吗?这里有一份实用路线图:
-
采用 OpenTelemetry:统一使用 OpenTelemetry 采集所有遥测数据,并生成丰富日志
-
选择统一存储方案:选用可高效存储并查询指标、日志、追踪和丰富日志的平台
-
丰富你的遥测数据:更新应用程序的监控代码,加入相关上下文信息
-
创建关联 ID:确保每个请求都有唯一标识符
-
实施语义规范:保持遥测数据的命名一致性
-
从重点场景开始:优先聚焦高价值用例,如结账流程或关键 API
-
利用 GenAI 工具:集成能分析统一数据并支持自然语言查询的 AI 工具
请记住,AI 的智能程度取决于输入数据的质量和完整性。
生成式 AI:观测的演进催化剂
将观测数据统一用于 GenAI 分析,堪比互联网从 1.0 到 2.0 的进化跃迁。早期采用者将通过更快的问题解决、系统可靠性提升和更高效的运营获得显著竞争优势。GAI 是提升观测成熟度、推动团队主动运维的重要一步。
把传统观测比作只能看到心率的医生,统一观测 + GenAI 就是给医生提供了完整的健康数据,包括生命体征、化验结果、病史和基因信息,而且可以通过自然语言对话获取。
作为 SRE,我们正站在观测新时代的门槛上。GenAI 并非威胁,而是变革机遇,推动我们打造更可靠、更易理解的系统。问题不是转型会不会发生,而是谁将引领这场变革。
你准备好了吗?