3. Access Log 配置基础:配置块结构、输出目标与基本格式字符串
Envoy 的访问日志(Access Log)是网关可观测性的核心数据源。本节将深入解析 Access Log 的配置块结构、三种输出目标(file、stdout、grpc)以及格式字符串的编写方法,为后续变更门禁的日志审计打下基础。
3.1 Access Log 配置块结构
Access Log 的配置位于 Envoy 的 HTTP 连接管理器(HttpConnectionManager)中,通过 access_log 字段定义。每个 Access Log 配置块由三个核心部分组成:
| 配置层级 | 字段 | 说明 | 必填 |
|---|---|---|---|
| 顶层 | name |
访问日志扩展名称,如 envoy.access_loggers.file |
是 |
| 过滤 | filter |
可选,决定哪些请求被记录(如只记录错误、只记录特定路由) | 否 |
| 配置 | typed_config |
具体输出目标的配置,包含路径、格式、gRPC 服务等 | 是 |
以下是一个典型的 Access Log 配置块 YAML 示例:
access_log:
- name: envoy.access_loggers.file
filter:
not_health_check: true
typed_config:
"@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
path: /var/log/envoy/access.log
format: "[%START_TIME%] \"%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%\" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %UPSTREAM_HOST% \"%REQ(USER-AGENT)%\"\n"
关键点: 每个
access_log 数组元素代表一个独立的日志输出流。你可以同时配置多个输出目标,例如同时写入本地文件和发送到 gRPC 服务。
3.2 输出目标:file、stdout、grpc
Envoy 支持三种主要的 Access Log 输出目标,每种适用于不同的运维场景:
| 输出目标 | 扩展名称 | 典型场景 | 配置要点 |
|---|---|---|---|
| file | envoy.access_loggers.file |
本地持久化存储、日志轮转、离线分析 | 需指定 path 字段;支持异步写入 |
| stdout | envoy.access_loggers.file(路径设为 /dev/stdout) |
容器化部署、Kubernetes 日志收集、快速调试 | 路径固定为 /dev/stdout 或 /dev/stderr |
| gRPC | envoy.access_loggers.grpc |
集中式日志平台、实时流处理、变更门禁审计 | 需配置 common_config 指定 gRPC 服务地址 |
stdout 配置示例(适用于容器环境):
access_log:
- name: envoy.access_loggers.file
typed_config:
"@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
path: /dev/stdout
format: "[%START_TIME%] %REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %RESPONSE_CODE%\n"
gRPC 配置示例(适用于变更门禁审计):
access_log:
- name: envoy.access_loggers.grpc
typed_config:
"@type": type.googleapis.com/envoy.extensions.access_loggers.grpc.v3.HttpGrpcAccessLogConfig
common_config:
log_name: "change_audit_log"
grpc_service:
envoy_grpc:
cluster_name: log_aggregator_cluster
additional_request_headers_to_log:
- "x-change-request-id"
- "x-change-approver"
变更门禁建议: 在变更门禁场景中,推荐同时配置 file(本地备份)和 gRPC(实时审计)两个输出目标,确保日志不丢失且可实时分析。
3.3 基本格式字符串
格式字符串(Format String)定义了每条日志的字段排列方式。Envoy 使用 %FIELD_NAME% 占位符来引用请求/响应属性。以下是常用的格式字段分类:
| 类别 | 字段示例 | 说明 |
|---|---|---|
| 时间 | %START_TIME% |
请求开始时间,格式可自定义 |
| 请求行 | %REQ(:METHOD)%、%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%、%PROTOCOL% |
HTTP 方法、路径、协议版本 |
| 响应 | %RESPONSE_CODE%、%RESPONSE_FLAGS% |
HTTP 状态码、Envoy 响应标志(如 UH、UF、DC) |
| 流量 | %BYTES_RECEIVED%、%BYTES_SENT% |
接收/发送字节数 |
| 延迟 | %DURATION%、%UPSTREAM_RQ_DURATION% |
总耗时、上游请求耗时(毫秒) |
| 上游 | %UPSTREAM_HOST%、%UPSTREAM_CLUSTER% |
上游主机地址、集群名称 |
| 自定义头 | %REQ(USER-AGENT)%、%RESP(X-CUSTOM-HEADER)% |
请求/响应中的任意 HTTP 头 |
标准格式字符串示例:
format: "[%START_TIME%] \"%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%\" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %UPSTREAM_HOST% \"%REQ(USER-AGENT)%\"\n"
该格式输出示例:
[2025-03-21T10:30:45.123Z] "GET /api/v1/deployments HTTP/1.1" 200 - 0 1234 15.678 10.0.1.5:8080 "curl/7.68.0"
注意: 格式字符串末尾必须包含
\n 换行符,否则所有日志将挤在同一行。对于 JSON 格式的日志,应使用 format: '{"start_time":"%START_TIME%","method":"%REQ(:METHOD)%",...}\n' 并确保 JSON 结构完整。
3.4 Access Log 配置块与输出目标关系图
下图展示了 Access Log 配置块的结构以及三种输出目标的数据流向:
3.5 格式字符串高级用法:条件与自定义
除了基本字段,Envoy 还支持条件格式和自定义格式扩展:
- 条件格式: 使用
%...%配合?true:false语法,例如%RESPONSE_CODE%?%UPSTREAM_HOST%:-表示当响应码存在时才记录上游主机,否则记录-。 - JSON 格式: 将格式字符串写为 JSON 对象,便于日志系统直接解析:
format: '{"timestamp":"%START_TIME%","method":"%REQ(:METHOD)%","path":"%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%","status":%RESPONSE_CODE%,"duration":%DURATION%}\n' - 自定义头注入: 在变更门禁场景中,常通过
%REQ(X-CHANGE-ID)%和%REQ(X-CHANGE-APPROVER)%记录变更请求的审计追踪信息。
变更门禁最佳实践: 建议在格式字符串中始终包含
%RESPONSE_FLAGS% 字段,该字段能标记请求是否被 Envoy 拒绝(如 RL 表示限流、UR 表示上游拒绝),是变更门禁策略生效的直接证据。
3.6 配置验证与调试
在将 Access Log 配置部署到生产环境前,建议执行以下验证步骤:
- 配置语法检查: 使用
envoy --mode validate -c <config.yaml>验证配置合法性。 - 本地测试输出: 先配置
stdout输出,在本地启动 Envoy 并发送测试请求,观察日志格式是否符合预期。 - gRPC 连通性测试: 使用
grpcurl工具测试 gRPC 日志服务是否可达。 - 日志轮转配置: 对于 file 输出,建议配合
logrotate或 Envoy 内置的日志轮转参数(如max_log_files、max_log_size)防止磁盘写满。
快速调试命令: 使用
curl -v http://localhost:10000/ 发送测试请求,然后通过 tail -f /var/log/envoy/access.log 实时观察日志输出,验证格式字符串是否正确。