1. 背景
阿里云API网关服务提供API托管服务,提供了强大的适配和集成能力,可以将各种不同的业务系统API实现统一管理。API网关同时支持将API访问日志一键存储到日志服务,通过日志服务强大的查询分析能力,用户可以针对访问日志自定义计算多种指标,监测服务运行情况。继而通过定时SQL将结果指标直接存储到时序库,直接查询API网关指标,而且可以通过较低成本长期存储指标数据。 下面我们一步步从头开始,学习如何利用日志服务监测API网关及其代理的服务。
2. 数据采集
数据采集一直是让开发运维比较头疼的事情,要学习各种不同的采集工具,适配形形色色的环境,解析各式各样的数据格式,在不断试错的情况下,才能够完成第一次的数据采集。而在此之后,还需要不断地完善优化,耗费大量的经历。下面简单介绍下数据采集以及采集到的日志格式,详情可以参考官方文档。
一键采集
阿里云API网关已经很好的集成了日志服务,用户只需要在API网关的日志管理界面关联日志服务,即可完成API访问日志的一键采集,极其方便。
在API网关的日志管理界面点击创建日志配置;
在弹出窗中选择日志服务的Project/Logstore;
点击确认,完成数据采集;
日志格式
下面是采集到的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请求命中的插件列表及相关上下文 |
3. 查询分析
有了日志,就可以针对访问日志进行简单的查询分析,查看自己感兴趣的指标。日志服务即支持简单的查询,也支持复杂的聚合分析,下面进行简单的介绍。
简单过滤
最常见的情况是查看错误请求,可以通过查询语句:* not statusCode: 200
来查看所有的异常请求。
当然还可以通过更多的字段进行过滤,详情可以参考官方文档。
聚合分析
对于更复杂的分析,例如不同错误码的请求数量,不同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语句则用来计算过滤后的数据,并通过图表展示出来,如下图所示。可以清楚地看到平均请求延迟的变化曲线。
4. 确认指标
了解了如何进行基本的查询分析,我们能做的事情就非常多了。可以根据自己的需求以及业务场景,自定义多种不同的业务指标,满足自己的日常运维、监测需求。下面列出一些常用的指标,以及对应指标的查询分析语句。
请求延迟
在查询分析中,本文已经介绍过简单的平均延迟计算方法,下面介绍下更完整的请求延迟指标:平均延迟、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
错误码分布
*| select count(1) as cnt, statusCode, (__time__ - __time__ % 60) as ts from log group by statusCode, ts order by ts limit 1000000
请求/响应大小
*| 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
地域分布
* | select region, count(1) as cnt , (__time__ - __time__ % 60) as ts from log group by region, ts order by ts
5. 定时任务
可以看到,日志服务强大的查询分析能力允许用户多网关日志进行多种查询分析,得到期望的结果。如果需要把上一小节计算的定时保存下来,就要用到定时任务。下面介绍如何将上一小节中计算的请求/响应大小指标,定时保存到时序库中,从而可以快速获取指标。
创建时序库
点击左侧边栏的时序存储按钮,在时序库管理界面点击+号,填入名称即可创建一个时序库,用来存储希望保存的时序指标。
保存定时任务
创建好时序库,就可以创建任务定时保存分析结果,以供实时查看。下面简单介绍下定时任务配置步骤,详情可以参考官方文档。
点击创建任务
在查询分析界面点击定时保存分析结果,即可弹出任务创建窗口。
选择存储格式
在弹出窗口中选择日志库导入时序库,确定数据存储格式。
确定存储指标
在sql配置中选择期望保存的指标列,以及指标对应的时间列,即完成了指标配置。
配置任务调度
点击下一步,调度间隔选择15分钟,开始时间选择当前时间, SQL时间窗口同样选择15分钟即完成了调度配置。当然,用户也可以根据自己的场景自行选择。最后点击确认完成任务配置。
查看结果指标
点击刚刚创建的时序存储,在Metrics一行点击刷新,即可查看该时序存储包含的所有指标。选择max_resp_size,点击预览,即可查看该指标,无需编写查询分析语句。
6. 添加报表
有了指标,就可以使用这些指标构建监控大盘,查看整体指标,构建自己的专属监控大盘。在指标查询界面点击添加到仪表盘,在弹出窗中选择新建仪表盘,填入名称点击确认,即完成了仪表盘的创建。
点开仪表盘,即可看到刚刚创建的图标。
7. 结语
API网关是服务的入口,通过网关日志可以计算出丰富的服务监控指标。本文以部分常用指标为例,介绍了从数据接入到定时任务创建的整个流程,供用户参考。可以看出,日志服务提供了及其简便的日志采集入口,丰富的查询分析功能,简便的定时任务,帮助用户简单快速的建立起一个完整的日志采集、指标分析、大盘查看系统,减轻了运维负担。