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 配置块的结构以及三种输出目标的数据流向:

Access Log 配置块结构与输出目标 Access Log 配置块 name: 扩展名称 filter: 过滤条件 typed_config: 输出配置 三种输出目标 file 输出 本地文件 /var/log/envoy/*.log stdout 输出 /dev/stdout 容器标准输出 gRPC 输出 远程日志聚合服务 格式字符串(Format String) 使用 %FIELD_NAME% 占位符定义日志字段顺序 示例: [%START_TIME%] "%REQ(:METHOD)% %REQ(PATH)% %PROTOCOL%" %RESPONSE_CODE%

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 配置部署到生产环境前,建议执行以下验证步骤:

  1. 配置语法检查: 使用 envoy --mode validate -c <config.yaml> 验证配置合法性。
  2. 本地测试输出: 先配置 stdout 输出,在本地启动 Envoy 并发送测试请求,观察日志格式是否符合预期。
  3. gRPC 连通性测试: 使用 grpcurl 工具测试 gRPC 日志服务是否可达。
  4. 日志轮转配置: 对于 file 输出,建议配合 logrotate 或 Envoy 内置的日志轮转参数(如 max_log_files、max_log_size)防止磁盘写满。
快速调试命令: 使用 curl -v http://localhost:10000/ 发送测试请求,然后通过 tail -f /var/log/envoy/access.log 实时观察日志输出,验证格式字符串是否正确。