通过定时SQL提取阿里云API网关访问日志指标

中州
  • 收获赞:25
  • 擅长领域:这个同学很专业,但是有点神秘哟~

背景

阿里云API网关服务提供API托管服务,提供了强大的适配和集成能力,可以将各种不同的业务系统API实现统一管理。API网关同时支持将API访问日志一键存储到日志服务,通过日志服务强大的查询分析能力,用户可以针对访问日志自定义计算多种指标,监测服务运行情况。继而通过定时SQL将结果指标直接存储到时序库,直接查询API网关指标,而且可以通过较低成本长期存储指标数据。 下面我们一步步从头开始,学习如何利用日志服务监测API网关及其代理的服务。

数据采集

数据采集一直是让开发运维比较头疼的事情,要学习各种不同的采集工具,适配形形色色的环境,解析各式各样的数据格式,在不断试错的情况下,才能够完成第一次的数据采集。而在此之后,还需要不断地完善优化,耗费大量的经历。下面简单介绍下数据采集以及采集到的日志格式,详情可以参考官方文档

一键采集

阿里云API网关已经很好的集成了日志服务,用户只需要在API网关的日志管理界面关联日志服务,即可完成API访问日志的一键采集,极其方便。

  1. 在API网关的日志管理界面点击创建日志配置;

  2. 在弹出窗中选择日志服务的Project/Logstore;

  3. 点击确认,完成数据采集;

image.png

日志格式

下面是采集到的API访问日志示例,

{
    "exception": " ",
    "apiName": "getbill",
    "apiStageName": "stage3",
    "__tag__:__receive_time__": "1667222540",
    "httpMethod": "POST",
    "path": "/request/path-1/file-6",
    "__pack_meta__": "1|MTY2NzIwNzcxMTIyMzU0Mzc1Ng==|1094|1093",
    "requestHandleTime": "31/Oct/2022:13:02:49",
    "requestId": "d6b86756-83c2-e5a8-63f6-da39045f6595",
    "appId": "9fb195bd-3d39-be83-ca8c-44a6e85262eb",
    "__time__": 1667221369,
    "__topic__": "apigateway_log",
    "apiStageUid": "e5c13606-f96e-5653-26b1-750d766dd3ae",
    "appName": "app3",
    "__source__": "127.0.0.1",
    "apiGroupUid": "3a51584d-20de-2da1-3095-7f82aa7022dc",
    "errorMessage": " ",
    "responseSize": "472",
    "serviceLatency": "967",
    "providerAliUid": "9e21f8dc-54bd-7ad0-5fb4-a898614bc41c",
    "apiGroupName": "group4",
    "apiUid": "316af01f-8f8f-e2f9-17d7-ac0ea3b28518",
    "domain": "www.qt.mock.com",
    "clientIp": "127.0.0.1",
    "__tag__:__receive_time___0": "1667222540",
    "region": "cn-chengdu",
    "requestSize": "945",
    "statusCode": "200"
}

关于各字段的含义,可以查看下表,也可以参考官方文档。访问日志的字段也会随着API网关能力的增强进行补充,不需要用户手动增删,极大的减轻了维护负担。

日志项

描述

apiGroupUid

API的分组ID

apiGroupName

API分组名称

apiUid

API的ID

apiName

API名称

apiStageUid

API环境ID

apiStageName

API环境名称

httpMethod

调用的HTTP方法

path

请求的PATH

domain

调用的域名

statusCode

HttpStatusCode

errorMessage

错误信息

appId

调用者应用ID

appName

调用者应用名称

clientIp

调用者客户端IP

exception

后端返回的具体错信息

providerAliUid

API提供者账户ID

region

区域,如:cn-hangzhou

requestHandleTime

请求时间,UTC

requestId

请求ID,全局唯一

requestSize

请求大小,单位:字节

responseSize

返回数据大小,单位:字节

serviceLatency

访问后端资源耗时总和,包括申请连接资源耗时,建立连接耗时,调用后端服务耗时,单位:毫秒

errorCode

错误码code,如:X500ER

requestProtocol

客户端请求协议:HTTP/HTTPS/WS

instanceId

API服务所在的网关实例ID

initialRequestId

API网关自调用时,例如API-1调用API-2 ,那么API-2的日志中会用initialRequestId来记录API-1的requestid。

clientNonce

客户端X-Ca-Nonce头

requestQueryString

客户端请求的queryString

requestHeaders

客户端请求的header内容

requestBody

客户端请求的body内容,最多1024个字节

responseHeaders

API响应的header内容

responseBody

API响应的response内容,最多1024个

consumerAppKey

API请求的appKey

totalLatency

API请求的总延迟,单位毫秒

customTraceId

全链路日志的traceId

jwtClaims

从JWT中解析出来的Claim,可以在分组上配置

plugin

API请求命中的插件列表及相关上下文

查询分析

有了日志,就可以针对访问日志进行简单的查询分析,查看自己感兴趣的指标。日志服务即支持简单的查询,也支持复杂的聚合分析,下面进行简单的介绍。

简单过滤

最常见的情况是查看错误请求,可以通过查询语句:* not statusCode: 200来查看所有的异常请求。

image.png

当然还可以通过更多的字段进行过滤,详情可以参考官方文档

聚合分析

对于更复杂的分析,例如不同错误码的请求数量,不同API的平均响应时间,就需要用到聚合分析。下面以平均响应时间为例,介绍下如何使用聚合分析。

在查询框中输入过滤以及分析语句

* and statusCode: 200 | select avg(serviceLatency) as rt, (__time__ - __time__ % 300) as ts from log group by ts order by ts limit 10000

其中* and statusCode: 200 用来过滤出正常请求,其余的sql语句则用来计算过滤后的数据,并通过图表展示出来,如下图所示。可以清楚地看到平均请求延迟的变化曲线。

image.png

确认指标

了解了如何进行基本的查询分析,我们能做的事情就非常多了。可以根据自己的需求以及业务场景,自定义多种不同的业务指标,满足自己的日常运维、监测需求。下面列出一些常用的指标,以及对应指标的查询分析语句。

请求延迟

在查询分析中,本文已经介绍过简单的平均延迟计算方法,下面介绍下更完整的请求延迟指标:平均延迟、P99延迟、P95延迟、P90延迟、P50延迟、最大延迟以及最小延迟。

*| select approx_percentile(serviceLatency, 0.99) as p99_latency, approx_percentile(serviceLatency, 0.95) as p95_latency, approx_percentile(serviceLatency, 0.90) as p90_latency, approx_percentile(serviceLatency, 0.50) as p50_latency, min(serviceLatency) as min_latency, min(serviceLatency) as max_latency, avg(serviceLatency) as avg_latency, (__time__ - __time__ % 60) as ts from log group by ts order by ts limit 1000000
image.png

错误码分布

*| select count(1) as cnt, statusCode, (__time__ - __time__ % 60) as ts from log group by statusCode, ts order by ts limit 1000000
image.png

请求/响应大小

*| select approx_percentile(requestSize, 0.99) as p99_req_size, approx_percentile(requestSize, 0.95) as p95_req_size, approx_percentile(requestSize, 0.90) as p90_req_size, approx_percentile(requestSize, 0.50) as p50_req_size, min(requestSize) as min_req_size, min(requestSize) as max_req_size, avg(requestSize) as avg_req_size, approx_percentile(responseSize, 0.99) as p99_resp_size, approx_percentile(responseSize, 0.95) as p95_resp_size, approx_percentile(responseSize, 0.90) as p90_resp_size, approx_percentile(responseSize, 0.50) as p50_resp_size, min(responseSize) as min_resp_size, min(responseSize) as max_resp_size, avg(responseSize) as avg_resp_size, (__time__ - __time__ % 60) as ts from log group by ts order by ts limit 1000000
image.png

地域分布

* | select region, count(1) as cnt , (__time__ - __time__ % 60) as ts from log group by region, ts order by ts 
image.png

定时任务

可以看到,日志服务强大的查询分析能力允许用户多网关日志进行多种查询分析,得到期望的结果。如果需要把上一小节计算的定时保存下来,就要用到定时任务。下面介绍如何将上一小节中计算的请求/响应大小指标,定时保存到时序库中,从而可以快速获取指标。

创建时序库

点击左侧边栏的时序存储按钮,在时序库管理界面点击+号,填入名称即可创建一个时序库,用来存储希望保存的时序指标。

image.png

保存定时任务

创建好时序库,就可以创建任务定时保存分析结果,以供实时查看。下面简单介绍下定时任务配置步骤,详情可以参考官方文档

点击创建任务

在查询分析界面点击定时保存分析结果,即可弹出任务创建窗口。

image.png

选择存储格式

在弹出窗口中选择日志库导入时序库,确定数据存储格式。

image.png

确定存储指标

在sql配置中选择期望保存的指标列,以及指标对应的时间列,即完成了指标配置。

image.png

配置任务调度

点击下一步,调度间隔选择15分钟,开始时间选择当前时间, SQL时间窗口同样选择15分钟即完成了调度配置。当然,用户也可以根据自己的场景自行选择。最后点击确认完成任务配置。

image.png

查看结果指标

点击刚刚创建的时序存储,在Metrics一行点击刷新,即可查看该时序存储包含的所有指标。选择max_resp_size,点击预览,即可查看该指标,无需编写查询分析语句。

image.png

添加报表

有了指标,就可以使用这些指标构建监控大盘,查看整体指标,构建自己的专属监控大盘。在指标查询界面点击添加到仪表盘,在弹出窗中选择新建仪表盘,填入名称点击确认,即完成了仪表盘的创建。

image.png

点开仪表盘,即可看到刚刚创建的图标。

image.png

结语

API网关是服务的入口,通过网关日志可以计算出丰富的服务监控指标。本文以部分常用指标为例,介绍了从数据接入到定时任务创建的整个流程,供用户参考。可以看出,日志服务提供了及其简便的日志采集入口,丰富的查询分析功能,简便的定时任务,帮助用户简单快速的建立起一个完整的日志采集、指标分析、大盘查看系统,减轻了运维负担。