自定义数据面访问日志

部署在数据平面(即加入网格的Kubernetes集群)的Envoy Proxy可以输出所有访问日志。ASM支持自定义Envoy Proxy输出的访问日志内容。本文介绍如何自定义Envoy Proxy输出的访问日志内容。

前提条件

步骤一:启用访问日志

ASM实例版本为1.17.2.35以下

  1. 登录ASM控制台,在左侧导航栏,选择服务网格 > 网格管理

  2. 网格管理页面,单击目标实例名称,然后在左侧导航栏,选择网格实例 > 基本信息

  3. 基本信息页面右上角,单击功能设置

  4. 功能设置更新面板,选中开启访问日志并将其打印到容器标准输出,然后单击确定

    istio-proxy容器默认输出包含以下字段的日志。如果关闭访问日志,istio-proxy容器将不会产生JSON格式的访问日志。

    展开查看日志详情

    
        "authority_for":"%REQ(:AUTHORITY)%",
        "bytes_received":"%BYTES_RECEIVED%",
        "bytes_sent":"%BYTES_SENT%",
        "downstream_local_address":"%DOWNSTREAM_LOCAL_ADDRESS%",
        "downstream_remote_address":"%DOWNSTREAM_REMOTE_ADDRESS%",
        "duration":"%DURATION%",
        "istio_policy_status":"%DYNAMIC_METADATA(istio.mixer:status)%",
        "method":"%REQ(:METHOD)%",
        "path":"%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%",
        "protocol":"%PROTOCOL%",
        "request_id":"%REQ(X-REQUEST-ID)%",
        "requested_server_name":"%REQUESTED_SERVER_NAME%",
        "response_code":"%RESPONSE_CODE%",
        "response_flags":"%RESPONSE_FLAGS%",
        "route_name":"%ROUTE_NAME%",
        "start_time":"%START_TIME%",
        "trace_id":"%REQ(X-B3-TRACEID)%",
        "upstream_cluster":"%UPSTREAM_CLUSTER%",
        "upstream_host":"%UPSTREAM_HOST%",
        "upstream_local_address":"%UPSTREAM_LOCAL_ADDRESS%",
        "upstream_service_time":"%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%",
        "upstream_transport_failure_reason":"%UPSTREAM_TRANSPORT_FAILURE_REASON%",
        "user_agent":"%REQ(USER-AGENT)%",
        "x_forwarded_for":"%REQ(X-FORWARDED-FOR)%"

ASM实例版本为1.17.2.35及以上

  1. 登录ASM控制台,在左侧导航栏,选择服务网格 > 网格管理

  2. 网格管理页面,单击目标实例名称,然后在左侧导航栏,选择可观测管理中心 > 可观测配置

  3. 可观测配置页面,按需单击全局命名空间自定义页签。

    • 若您选择命名空间页签,请单击创建,按需选择命名空间

    • 若您选择自定义页签,请单击创建,按需选择命名空间,输入名称匹配标签

  4. 日志设置区域,打开启用日志输出开关,然后单击提交

    打开开关后,服务网格数据平面Sidecar或网关会将访问日志输出至容器标准输出。ASM还支持日志过滤功能,详情请参见日志过滤

  5. 在数据平面Sidecar容器的标准输出查看日志。

    下文以使用kubectl查看访问日志为例进行说明。

    1. 执行以下命令,查看Sidecar日志。

      kubectl logs httpbin-5c5944c58c-w**** -c istio-proxy --tail 1

      展开查看示例输出

      {
          "authority_for":"47.110.XX.XXX",
          "bytes_received":"0",
          "bytes_sent":"22382",
          "downstream_local_address":"192.168.0.29:80",
          "downstream_remote_address":"221.220.XXX.XXX:0",
          "duration":"80",
          "istio_policy_status":"-",
          "method":"GET",
          "path":"/static/favicon.ico",
          "protocol":"HTTP/1.1",
          "request_id":"0f2cf829-3da5-4810-a618-08d9745d****",
          "requested_server_name":"outbound_.8000_._.httpbin.default.svc.cluster.local",
          "response_code":"200",
          "response_flags":"-",
          "route_name":"default",
          "start_time":"2023-06-30T04:00:36.841Z",
          "trace_id":"-",
          "upstream_cluster":"inbound|80||",
          "upstream_host":"192.168.0.29:80",
          "upstream_local_address":"127.0.X.X:55879",
          "upstream_response_time":"79",
          "upstream_service_time":"79",
          "upstream_transport_failure_reason":"-",
          "user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.X.X Safari/537.36",
          "x_forwarded_for":"221.220.XXX.XXX"
      }
    2. 执行以下命令,查看入口网关日志。

      kubectl -n istio-system logs istio-ingressgateway-6cff9b6b58-r**** --tail 1

      展开查看示例输出

      {
          "authority_for":"47.110.XX.XXX",
          "bytes_received":"0",
          "bytes_sent":"22382",
          "downstream_local_address":"192.168.0.63:80",
          "downstream_remote_address":"221.220.XXX.XXX:64284",
          "duration":"81",
          "istio_policy_status":"-",
          "method":"GET",
          "path":"/static/favicon.ico",
          "protocol":"HTTP/1.1",
          "request_id":"0f2cf829-3da5-4810-a618-08d9745d****",
          "requested_server_name":"-",
          "response_code":"200",
          "response_flags":"-",
          "route_name":"httpbin",
          "start_time":"2023-06-30T04:00:36.841Z",
          "trace_id":"-",
          "upstream_cluster":"outbound|8000||httpbin.default.svc.cluster.local",
          "upstream_host":"192.168.0.29:80",
          "upstream_local_address":"192.168.0.63:36140",
          "upstream_response_time":"81",
          "upstream_service_time":"81",
          "upstream_transport_failure_reason":"-",
          "user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.X.X Safari/537.36",
          "x_forwarded_for":"221.220.XXX.XXX"
      }
  6. (可选)通过容器服务控制台查看访问日志。

    如果您使用阿里云容器服务集群,还可以通过容器服务控制台查看访问日志。

    1. 登录容器服务管理控制台,在左侧导航栏选择集群

    2. 集群列表页面,单击目标集群名称,然后在左侧导航栏,选择工作负载 > 容器组

    3. 容器组页面,单击目标Pod名称,然后在页面下方单击日志页签,查看访问日志。

关于日志的更多信息,请参见可观测配置启用控制平面日志采集和日志告警(新版)

步骤二:自定义数据面访问日志内容

ASM实例版本为1.17.2.35以下

  1. 登录ASM控制台,在左侧导航栏,选择服务网格 > 网格管理

  2. 网格管理页面,单击目标实例名称,然后在左侧导航栏,选择网格实例 > 基本信息

  3. 基本信息页面的配置信息区域,单击开启访问日志并将其打印到容器标准输出右侧的自定义访问日志格式

  4. 自定义访问日志格式对话框下方,新增自定义访问日志格式,设置变量名称my_custom_key变量值%REQ(end-user)%,然后单击确认

    本文以获取Bookinfo示例中HTTP请求的Header字段end-user为例。如下图所示,自定义访问日志格式时,您可以选择ASM提供的可选字段,也可以新增自定义字段。选中目标字段后,将按照自定义的访问日志格式输出访问日志。可选字段

ASM实例版本为1.17.2.35及以上

  1. 登录ASM控制台,在左侧导航栏,选择服务网格 > 网格管理

  2. 网格管理页面,单击目标实例名称,然后在左侧导航栏,选择可观测管理中心 > 可观测配置

  3. 可观测配置页面,按需单击全局命名空间自定义页签。

    • 若您选择命名空间页签,请单击创建,按需选择命名空间

    • 若您选择自定义页签,请单击创建,按需选择命名空间,输入名称匹配标签

  4. 日志设置区域,按需选中字段、修改目标字段信息或在最下方日志指标右侧单击增加.png图标,新增日志字段,然后单击提交

    只有打开启用日志输出开关,才能自定义日志格式。在日志格式区域,默认选中的日志字段为默认必选字段,不支持修改。日志字段支持从请求Header、响应Header、Envoy内置值中取值。

    下文以打印请求中的accept-encoding Header为例,配置变量名称accept-encoding类型请求属性变量值Accept-Encoding日志格式.png

  5. 执行以下命令,查看服务网格数据平面组件日志。

    kubectl logs httpbin-5c5944c58c-w**** -c istio-proxy --tail 1|grep accept-encoding --color=auto

    展开查看示例输出

    {
        "bytes_received":"0",
        "bytes_sent":"9593",
        "downstream_local_address":"192.168.0.29:80",
        "downstream_remote_address":"69.164.XXX.XX:0",
        "duration":"2",
        "istio_policy_status":"-",
        "method":"GET",
        "path":"/",
        "protocol":"HTTP/1.1",
        "request_id":"29939dc9-62be-4ddf-acf6-32cb098d****",
        "requested_server_name":"outbound_.8000_._.httpbin.default.svc.cluster.local",
        "response_code":"200",
        "response_flags":"-",
        "route_name":"default",
        "start_time":"2023-06-30T04:18:19.734Z",
        "trace_id":"-",
        "upstream_cluster":"inbound|80||",
        "upstream_host":"192.168.0.29:80",
        "upstream_local_address":"127.0.X.X:34723",
        "upstream_service_time":"2",
        "upstream_transport_failure_reason":"-",
        "user_agent":"Mozilla/5.0 zgrab/0.x",
        "x_forwarded_for":"69.164.XXX.XX",
        "authority_for":"47.110.XX.XXX",
        "upstream_response_time":"2",
        "accept-encoding":"gzip"
    }

    可以看到步骤4新增的Accept-Encoding Header的值,已被输出至访问日志。关于日志的更多信息,请参见可观测配置启用控制平面日志采集和日志告警(新版)

步骤三:查看访问日志

启用访问日志后,发起请求的Sidecar容器将按照自定义的访问日志格式输出访问日志。

  1. 在浏览器地址栏输入入口网关地址:productpage,访问Productpage应用。

  2. 登录容器服务管理控制台,在左侧导航栏选择集群

  3. 集群列表页面,单击目标集群名称,然后在左侧导航栏,选择工作负载 > 无状态

  4. 无状态页面顶部,设置命名空间default,然后在productpage-v1应用右侧,单击操作列下的详情

  5. 在应用详情页面,单击日志页签,设置Containeristio-proxy

    在日志输出框中可以看到如下日志。日志中包含名为jason的end-user,表明自定义日志内容成功。日志

请求耗时相关字段说明

服务网格ASM中,“上游(upstream)”表示调用链中请求的接收方,“下游(downstream)”表示请求的发起方。例如,服务A向服务B发起请求时,服务A为“下游(downstream)”,服务B为“上游(upstream)”。

变量名称

变量值

说明

duration

$DURATION%

  • 对于HTTP请求,该字段的值表示从该请求开始读取到返回给下游响应的最后一个字节被发送的时间,即Sidecar或网关处理一个请求所经过的完整时长。

  • 对于TCP请求,该字段表示下游连接的建立期间的总时长。

request_duration

%REQUEST_DURATION%

  • 对于HTTP请求,该字段的值表示从下游读取整个请求(Header + Body)所消耗的时间。如果这部分耗时较长,您可以按照以下方面进行排查:

    • 网络质量是否良好,带宽是否充足。

    • 上游或下游应用在同量级I/O下是否存在瓶颈。

  • 对于TCP请求,该字段未实现(在日志中显示为“-”)。

request_tx_duration

%REQUEST_TX_DURATION%

  • 对于HTTP请求,该字段表示从该请求发生开始,到其最后一个字节被发送至上游所经历的时间。如果这部分耗时较长,您可以按照以下方面进行排查:

    • 网络质量是否良好,带宽是否充足。

    • 上游或下游应用在同量级I/O下是否存在瓶颈。

  • 对于TCP请求,该字段未实现(在日志中显示为“-”)。

response_duration

%RESPONSE_DURATION%

  • 对于HTTP请求,该字段表示从该请求发生开始,到读取到上游返回的该请求Response的首个字节所经历的时间。如果这部分耗时较长,而request_tx_duration耗时较短,请检查上游应用是否存在性能瓶颈。

  • 对于TCP请求,该字段未实现(在日志中显示为“-”)。

response_tx_duration

%RESPONSE_TX_DURATION%

  • 对于HTTP请求,该字段表示从读取到上游Response的第一个字节开始,到最后一个字节被发送至下游所经历的时间。如果这部分耗时较长,您可以按照以下方面进行排查:

    • 网络质量是否良好,带宽是否充足。

    • 上游或下游应用在同量级I/O下是否存在瓶颈。

  • 对于TCP请求,该字段未实现(在日志中显示为“-”)。

upstream_service_time(sidecar)

%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%

在Sidecar访问日志或网关日志中,该字段表示上游的处理时间及与上游进行网络通信消耗的时间。若该时间较长,请检查:

  • 上游应用的处理性能是否符合预期。

  • 与上游通信的网络延迟、带宽是否符合预期。

upstream_response_time(gateway)

说明

对于带有Body(Content-Length > 0)的HTTP请求,Envoy是边接收边发给上游(而非全部接受后发送)。如果下游的读取速度缓慢,将会增加上游的读取时间,以及上游发送给它的上游的时间(上游为边读边发送的方式)。

相关操作

您还可以使用日志服务采集数据平面的AccessLog。具体操作,请参见生成和采集ASM网关访问日志