可观测性

简要概述

包含 envoy 的访问日志、性能数据、链路跟踪三类数据。

其中 HTTP连接管理、TCP 代理、Thrift 代理还有以下特点:

  1. 可配置任意数量的访问日志模式;
  2. 可自定义访问日志过滤器,将不同类型的请求和响应写入不同的访问日志。

访问日志配置

在监听器中使用

config.listener.v3.Listener 数据结构中以下几个参数:

{
  ......
  "access_log": [],
  ......
}

配置示例:

static_resources:
  listeners:
  - name: listener_0

    access_log:
    - name: envoy.access_loggers.stdout
      typed_config:
        "@type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog

访问示例:

$ curl -vvv 'http://192.168.0.2:80'
$ curl -vvv 'http://192.168.0.2:80'
$ curl -vvv 'http://192.168.0.2:80'
$ telnet 192.168.0.2 80

输出示例:

[2024-02-01T08:59:07.049Z] "- - HTTP/1.1" 0 - 74 201 32 - "-" "-" "-" "-" "-"
[2024-02-01T08:59:08.175Z] "- - HTTP/1.1" 0 - 74 200 3 - "-" "-" "-" "-" "-"
[2024-02-01T08:59:08.868Z] "- - HTTP/1.1" 0 - 74 201 15 - "-" "-" "-" "-" "-"
[2024-02-01T08:59:22.948Z] "- - -" 0 DPE 7 156 3131 - "-" "-" "-" "-" "-"

下游连接访问日志可以通过启用监听器访问日志来实现。

监听器访问日志是HTTP请求访问日志的补充,可以独立于过滤器访问日志单独启用。这提供了更灵活的配置选项,使得可以对下游连接的访问情况进行记录,从而更好地监测和分析网络流量。

在 UDP 代理中使用

extensions.filters.udp.udp_proxy.v3.UdpProxyConfig 数据结构。

{
  ......
  "access_log": [],
  "proxy_access_log": [],  
  "access_log_options": {...}
  ......
}

TODO;

在 TCP 代理中使用

extensions.filters.network.tcp_proxy.v3.TcpProxy 数据结构。

{
  ......
  "access_log": [],   
  "access_log_flush_interval": {...},
  "flush_access_log_on_connected": ...,
  "access_log_options": {...}
  ......
}

TODO;

在 HTTP 管理中使用

extensions.filters.network.http_connection_manager.v3.HttpConnectionManager 数据结构中以下几个参数:

{
  ......
  "access_log": [],
  "access_log_flush_interval": {...},
  "flush_access_log_on_new_request": ...,
  "access_log_options": {...},
  ......
}

配置示例:

static_resources:
  listeners:
  - name: listener_0
    ......
    filter_chains:
    - filters:
      - name: envoy.filters.network.http_connection_manager
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager

          access_log:
          - name: envoy.access_loggers.stdout
            typed_config:
              "@type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog

访问示例:

$ curl -vvv 'http://192.168.0.2:80'
$ telnet 192.168.0.2 80

日志记录:

[2024-02-01T09:38:40.387Z] "GET / HTTP/1.1" 200 - 0 5 14 12 "-" "curl/8.1.2" "e84f1a02-bbec-4c64-b908-aaf9f2b025cd" "192.168.0.2" "192.168.0.1:8080"
[2024-02-01T09:39:17.379Z] "- - HTTP/1.1" 400 DPE 0 11 0 - "-" "-" "-" "-" "-"

在 HTTP 路由中使用

extensions.filters.http.router.v3.Router 数据结构。

配置示例:

http_filters:
- name: envoy.filters.http.router
  typed_config:
	"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router

	upstream_log:
	- name: envoy.access_loggers.stdout
	  typed_config:
		"@type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog
	upstream_log_options:
	  # 是否记录请求前日志
	  flush_upstream_log_on_upstream_stream: false
	  upstream_log_flush_interval: 1s

访问示例:

$ curl -vvv 'http://192.168.0.2:80'
$ telnet 192.168.0.2 80

日志示例:

[2024-02-01T09:28:24.230Z] "GET / HTTP/1.1" 200 - 5 0 13 - "-" "curl/8.1.2" "f43c6cae-a2c3-4722-991e-f8bab54bd0d1" "192.168.0.2" "192.168.0.1:8000"

在上面的 “telnet” 是不会在该阶段产生日志,所以仅存在一条。

访问日志格式

支持的变量

字段 HTTP TCP UDP THRIFT
%START_TIME% 支持 支持 支持 支持
%EMIT_TIME% 支持 支持 支持 支持
%REQUEST_HEADERS_BYTES% 支持 - - -
%BYTES_RECEIVED% 支持 支持 - -
%BYTES_RETRANSMITTED% HTTP3 - - -
%PACKETS_RETRANSMITTED% HTTP3 - - -
%PROTOCOL% 支持 - - -
%UPSTREAM_PROTOCOL% 支持 - - -
%RESPONSE_CODE% 支持 - - -
%RESPONSE_CODE_DETAILS% 支持 - - -
%CONNECTION_TERMINATION_DETAILS% 支持 支持 - -
%RESPONSE_HEADERS_BYTES% 支持 - - -
%RESPONSE_TRAILERS_BYTES% 支持 - - -
%BYTES_SENT% 支持 支持 - 支持
%UPSTREAM_REQUEST_ATTEMPT_COUNT% 支持 支持 - -
%UPSTREAM_WIRE_BYTES_SENT% 支持 支持 - -
%UPSTREAM_WIRE_BYTES_RECEIVED% 支持 支持 - -
%UPSTREAM_HEADER_BYTES_SENT% 支持 - - -
%UPSTREAM_HEADER_BYTES_RECEIVED% 支持 - - -
%DOWNSTREAM_WIRE_BYTES_SENT% 支持 支持 - -
%DOWNSTREAM_WIRE_BYTES_RECEIVED% 支持 支持 - -
%DOWNSTREAM_HEADER_BYTES_SENT% 支持 - - -
%DOWNSTREAM_HEADER_BYTES_RECEIVED% 支持 - - -
%DURATION% 支持 支持 - 支持
%REQUEST_DURATION% 支持 - - -
%REQUEST_TX_DURATION% 支持 - - -
%RESPONSE_DURATION% 支持 - - -
%ROUNDTRIP_DURATION% HTTP3 - - -
%RESPONSE_TX_DURATION% 支持 - - -
%DOWNSTREAM_HANDSHAKE_DURATION% - 支持 - -
%UPSTREAM_CONNECTION_POOL_READY_DURATION% 支持 支持 - -
%RESPONSE_FLAGS% 支持 支持 - -
%RESPONSE_FLAGS_LONG% 支持 支持 - -
%ROUTE_NAME% 支持 支持 - -
%VIRTUAL_CLUSTER_NAME% gRPC - - -
%UPSTREAM_HOST% 支持 支持 支持 支持

这里仅列出部分,更多参考官方 Command Operators

默认格式与自定义

默认日志格式为:

[%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%"
%RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION%
%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%"
"%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"\n

在 yaml 中编写时,注意 ‘"’ 引号转译,如:

access_log:
- name: envoy.access_loggers.stdout
  typed_config:
    "@type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog
    log_format:
      text_format: "[%START_TIME%] \"%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%\" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% \"%REQ(X-FORWARDED-FOR)%\" \"%REQ(USER-AGENT)%\" \"%REQ(X-REQUEST-ID)%\" \"%REQ(:AUTHORITY)%\" \"%UPSTREAM_HOST%\"\n"

与 nginx 格式对比

nginx 日志格式:

log_format main '$msec "$remote_addr" $request_length "$request_method" "$host" "$request_uri"'
                ' "$server_name" "$server_addr" $server_port "$uri" "$args" "$server_protocol"'
                ' $bytes_sent $body_bytes_sent $status $request_time "$http_referer" "$http_user_agent"'
                ' "$http_x_tr_user_id" "$http_x_tr_pv_id" "$http_x_tr_request_id" "$http_x_tr_rpc_id"'
                ' "$upstream_addr" "$http_x_forwarded_for" [$time_local] ';

TODO;

性能数据配置

开启 prometheus 端点

admin:
  address:
    socket_address:
      address: 127.0.0.1
      port_value: 9902

访问 http://127.0.0.1:9902/stats/prometheus

链路跟踪配置

初始化服务

通过 extensions.filters.network.http_connection_manager.v3.HttpConnectionManager 配置以下内容:

{
  ......
  "tracing": {
    "client_sampling": {...},
    "random_sampling": {...},
    "overall_sampling": {...},
    "verbose": ...,
    "max_path_tag_length": {...},
    "custom_tags": [],
    "provider": {...},
    "spawn_upstream_span": {...}
  },
  ......
}

必须添加 “provider” 开启外部的链路跟踪服务提供方配置,支持以下几个:

envoy.tracers.datadog
envoy.tracers.dynamic_ot
envoy.tracers.opencensus
envoy.tracers.opentelemetry
envoy.tracers.skywalking
envoy.tracers.xray
envoy.tracers.zipkin

这里以 “envoy.tracers.opentelemetry” 为示例:

filter_chains:
- filters:
  - name: envoy.filters.network.http_connection_manager
    typed_config:
      "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
      tracing:
        provider:
          name: envoy.tracers.opentelemetry
          typed_config:
            "@type": type.googleapis.com/envoy.config.trace.v3.OpenTelemetryConfig
            # 上报到 otel 的服务名,默认为:unknown_service:envoy
            service_name: ingress-http:envoy
            http_service:
              http_uri:
                uri: "http://tracing-analysis-dc-hz.aliyuncs.com/adapt_******_******/api/otlp/traces"
                cluster: aliyun
                timeout: 3s



最后修改 2024.02.02: docs: update xx (34b4d3c)