3. Envoy日志体系:访问日志、管理日志、运行时日志的区别
在服务网格故障排查中,Envoy 的日志体系是定位问题的核心数据源。Envoy 主要输出三类日志:访问日志(Access Log)、管理日志(Admin Log) 和 运行时日志(Runtime Log)。三者用途、粒度、存储位置和排查场景截然不同。混淆使用会导致排查效率低下,甚至遗漏关键线索。
3.1 三类日志的核心定位
下表从数据来源、记录内容、典型用途和性能影响四个维度进行对比:
| 维度 | 访问日志(Access Log) | 管理日志(Admin Log) | 运行时日志(Runtime Log) |
|---|---|---|---|
| 数据来源 | 每个请求的生命周期(L7/L4) | Envoy 管理接口(Admin API) | Envoy 内部组件(线程、连接池、路由) |
| 记录内容 | 请求/响应元数据(方法、路径、状态码、延迟、上游地址) | 配置转储、统计信息、集群状态、日志级别设置 | DEBUG/INFO/WARN/ERROR 级别的内部事件 |
| 典型用途 | 流量拓扑还原、延迟分析、错误率监控、审计 | 动态配置检查、证书过期排查、统计指标导出 | Envoy 内部异常诊断(崩溃、内存泄漏、连接池耗尽) |
| 性能影响 | 高(每个请求都触发 I/O,需谨慎配置采样率) | 低(按需调用,不持续写入) | 中到高(DEBUG 级别会大量输出,生产环境应关闭) |
排查口诀:“访问日志看流量,管理日志看配置,运行时日志看内部”。遇到请求失败时,先查访问日志确认错误码和上游;若访问日志无记录,再查运行时日志看 Envoy 是否崩溃或拒绝连接。
3.2 访问日志(Access Log)——流量排查的第一现场
访问日志是 Envoy 为每个经过的请求生成的记录,是服务网格流量拓扑最直接的证据。它通常以结构化格式(JSON 或 gRPC)输出到文件、标准输出或第三方日志平台。
3.2.1 典型字段与排查价值
- %START_TIME%:请求开始时间,用于计算端到端延迟。
- %REQ(:METHOD)%:HTTP 方法(GET/POST/PUT),判断请求类型。
- %REQ(X-REQUEST-ID)%:链路追踪 ID,关联上下游调用链。
- %RESPONSE_CODE%:上游返回的状态码(200/503/504),直接反映服务健康度。
- %UPSTREAM_HOST%:实际处理请求的上游 Pod IP 和端口,用于验证负载均衡策略。
- %DURATION%:请求总耗时(毫秒),区分客户端等待时间和上游处理时间。
3.2.2 配置示例(JSON 格式输出到文件)
admin:
access_log:
- name: envoy.access_loggers.file
typed_config:
"@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
path: /var/log/envoy/access.log
log_format:
json_format:
start_time: "%START_TIME%"
method: "%REQ(:METHOD)%"
path: "%REQ(X-ENVOY-ORIGINAL-PATH?)%"
response_code: "%RESPONSE_CODE%"
upstream_host: "%UPSTREAM_HOST%"
duration: "%DURATION%"
bytes_received: "%BYTES_RECEIVED%"
bytes_sent: "%BYTES_SENT%"
生产建议:访问日志的 I/O 开销不可忽视。在 Istio 中,默认每个 Sidecar 都会记录所有入站和出站请求。建议按需开启采样(如 1% 或 10%),或使用 gRPC 日志服务(ALS)将日志异步发送到远端,避免磁盘写满导致 Envoy 进程异常。
3.3 管理日志(Admin Log)——配置与状态的“控制面板”
管理日志并非持续写入的日志文件,而是通过 Envoy 的 Admin API(默认端口 15000)按需获取的配置、统计和状态信息。它不记录请求,而是记录 Envoy 自身的“元数据”。
3.3.1 常用 Admin 端点与排查场景
| 端点 | 返回内容 | 典型排查场景 |
|---|---|---|
/config_dump |
当前生效的完整配置(Listener、Cluster、Route) | 验证配置是否按预期下发,排查路由规则未生效问题 |
/stats |
所有计数器、仪表盘、直方图 | 查看连接数、请求成功率、上游健康状态 |
/clusters |
上游集群的端点列表及健康状态 | 确认上游 Pod 是否被标记为 unhealthy,排查负载均衡异常 |
/logging |
查看/修改各组件的运行时日志级别 | 临时开启 DEBUG 级别日志,定位内部错误 |
/certs |
证书信息(过期时间、SAN) | 排查 mTLS 握手失败是否由证书过期引起 |
3.3.2 动态调整日志级别(临时排查)
# 将 router 和 upstream 组件的日志级别临时调整为 debug
curl -X POST http://localhost:15000/logging?router=debug&upstream=debug
# 查看当前所有组件的日志级别
curl http://localhost:15000/logging
注意:通过 Admin API 修改的日志级别在 Envoy 重启后会丢失。如需持久化,应在启动参数或配置文件中设置
--log-level。
3.4 运行时日志(Runtime Log)——Envoy 内部的“黑匣子”
运行时日志是 Envoy 内部组件(如连接池、线程池、路由引擎、TLS 握手)输出的调试/错误信息。它直接反映 Envoy 进程自身的运行状态,而非业务请求。
3.4.1 日志级别与生产配置
- trace / debug:最详细,包含每个连接建立、每个定时器触发等事件。生产环境严禁开启,否则会瞬间写满磁盘并拖垮 CPU。
- info:常规信息,如配置加载成功、集群成员变更。生产环境可开启,但建议输出到独立文件。
- warn / error:异常事件,如连接池耗尽、证书验证失败、上游连接断开。生产环境必须开启,是排查 Envoy 自身故障的第一入口。
- critical:致命错误,如内存分配失败、断言失败,通常会导致 Envoy 崩溃。
3.4.2 典型运行时日志片段解读
[2025-03-21 10:15:32.123][7][warning][upstream] [source/common/upstream/cluster_manager_impl.cc:1234]
cluster 'service-a.default.svc.cluster.local' health check failed: host 10.0.1.5:8080
-> unhealthy (active failure rate: 0.75)
这条日志表明:service-a 集群中的某个端点健康检查失败,被标记为不健康。结合访问日志中该上游返回 503 的记录,可以快速定位到是后端 Pod 本身的问题,而非 Envoy 配置错误。
3.5 三类日志的协同排查流程
下图展示了在典型故障场景下,如何按顺序使用三类日志进行分层排查:
3.6 避坑指南:三类日志的常见误用
- 误用运行时日志代替访问日志:运行时日志不记录请求元数据,无法用于流量拓扑分析。不要试图从运行时日志中提取请求路径或状态码。
- 生产环境开启 DEBUG 级别运行时日志:会导致 Envoy 每秒输出数万行日志,磁盘 I/O 飙升,进程 OOM 风险增加。仅在测试环境或临时排查时使用,且必须通过 Admin API 动态开启,用完即关。
- 忽略管理日志中的统计信息:访问日志显示 503 时,直接去查上游 Pod 日志,却忽略了
/stats中upstream_rq_503计数器和cluster.health_check.failure指标。管理日志的统计信息往往能更快定位是全局问题还是单点问题。 - 访问日志格式过于简单:只记录
%RESPONSE_CODE%和%UPSTREAM_HOST%,缺少%DURATION%和%BYTES_SENT%,导致无法区分是上游处理慢还是网络传输慢。
最佳实践:在 Istio 环境中,建议将访问日志输出到 stdout(由容器运行时收集),管理日志通过 Prometheus 抓取
/stats 指标,运行时日志仅保留 warn/error 级别并输出到独立文件。三类日志配合使用,才能构建完整的可观测性视图。