本文介绍了通过HTTP请求CLS API的一个具体业务场景的接入实践,由于CLS体量过大,无法接入腾讯云SDK,也在接入过程中遇到了一些问题,特此将流程总结分享,以免重蹈覆辙~
涉及的代码示例为Go语言。
业务场景
附业务场景需求分析WIKI:https://iwiki.woa.com/pages/viewpage.action?pageId=572745651
ASW执行编排好的工作流时,需要逐个任务节点执行,过程将产生大量日志,不宜自设数据库来存,需要借助专门存储日志的系统,也就是本次文章所介绍使用的CLS了。
日志服务(Cloud Log Service)提供一站式的日志数据解决方案。您无需关注扩缩容等资源问题,五分钟快速便捷接入,即可享受从日志采集、日志存储到日志内容搜索、统计分析等全方位稳定可靠的日志服务。帮助您轻松解决业务问题定位,指标监控、安全审计等日志问题。大大降低日志运维门槛。
日志服务主要提供以下功能:
- 日志采集:通过 LogListener、API 等方式从不同日志采集端采集日志至日志服务。
- 日志存储:使用日志服务存储日志数据。
- 日志索引:开启日志索引对日志进行查询,可帮助用户快速定位日志问题。
- 日志投递:用户可以将指定日志投递至其他云产品中,满足存储或其他计算需求。如指定的 COS 存储桶中,对日志进行生命周期管理等,满足日志审计需求。
根据官网介绍,CLS很好地切合了需求。API采集、无感知扩缩容、稳定可靠、索引搜索等即是ASW目前所极需的,因此决定接入CLS
Go API接入最佳实践
本次业务场景的接入需要完成如下事情:
- CAM换票,得到SecretId、SecretKey
- CLS签名构造
- 调用CLS API:创建日志集、创建日志主题、创建索引、写入日志
- 获取结果
CAM换票,得到SecretId、SecretKey
通过RoleQRN,调用Cam服务的DescribeToken接口校验并换取有权限操作CLS日志服务的SID、SKey,这里通过预设服务相关角色来帮助用户跳转到Cam一键开通,确保用户具有操作权限。
具体来说,在野鹤平台创建一个服务相关角色ASW_QCSLinkedRoleInAswLog
用户授权链接就是形如
https://console.cloud.tencent.com/cam/role/grant?roleName=ASW_QCSLinkedRoleInAswLog&serviceLinkedRole=1&s_url={call_back_url}
这样的跳转链接,在授权后,就可以根据这个相关角色的QRN来换票得到SID、SKey了,此步骤完成。
CLS签名构造
可以从https://cloud.tencent.com/document/product/614/12445获取签名计算方法demo。
拿来就能直接用了,请求所有API都需要加入这个签名头部,因此也可以根据实际业务需要,加一层封装。
签名封装
代码语言:javascript复制//获取cls要求的签名
func Authorization(credential *sdkCommon.Credential, headers url.Values, params url.Values, interfaceName, method string) string {
return signature(credential.SecretId, credential.SecretKey, method, interfaceName, params, headers, 300)
}
获取签名
代码语言:javascript复制// 构建请求
request, err := http.NewRequest("GET", fmt.Sprintf(aswCommon.Conf.Cls.Url, region), nil)
if err != nil {
return false, err
}
//获取cls需要的签名
headers := url.Values {
"Content-Type": {"application/json"},
"x-cls-token": {credential.Token},
}
params := url.Values{}
// 调用封装后的签名函数
authorization := clsutils.Authorization(credential, headers, params, "/logsets", "GET")
// 添加签名字段Header
request.Header.Add("Content-Type", "application/json")
request.Header.Add("x-cls-token", credential.Token)
request.Header.Add("Authorization", authorization)
// 发起请求
response, err := client.Do(request)
if err != nil {
return false, err
}
调用CLS API:创建日志集、创建日志主题、创建索引、写入日志
复用前面介绍的方式,一个一个接口调就好了~
其中,创建索引、构造日志两步需要创建比较复杂的数据结构,这部分可以参考文档完成,
建议将创建索引作为必选步骤,防止检索不到日志的情况出现。
创建索引 官方参考文档:https://cloud.tencent.com/document/product/614/16905
构造日志pb结构、写入日志 官方参考文档:https://cloud.tencent.com/document/product/614/16873
获取结果
以上步骤,前两步会返回创建成功的logset id 和topic id。
而后两步索引创建、写入日志返回200即代表成功,可以利用这一点,判断cls服务是否开通,可以调用cls的logsets接口(获取日志集列表),无需传入参数,返回200代表查询成功,即服务已开通,返回403等状态码则代表服务未开通。
遇到的问题总结
1. 使用签名函数时需注意,一些接口需要通过body传递参数,而签名仅需要计算header和query,不需要传入body。
示例:
代码语言:javascript复制// body参数构造
reqJson := "{"logset_name": "" tomlconfig.Conf.ClsClient.ClsLogSetName "","period": "
strconv.Itoa(tomlconfig.Conf.ClsClient.ClsLogSetPeriod) "}"
// 构建请求
request, err := http.NewRequest("POST", tomlconfig.Conf.ClsClient.ClsLogSetUrl, strings.NewReader(reqJson))
// 无需传入reqJson
authorization := Authorization(credential, headers, params, "/logsets", "GET")
2. 创建完日志集和日志主题后,一定确保创建索引成功后再写入日志,否则之前写入的日志无法检索到
3. 要获取本次调用的RequestId,根据CLS文档可从响应头部获取,这里文档给出的名称实际调用时获取不到,实际返回字段为x-Cls-Requestid
4. 构造日志时,用proto pb3语法定义日志结构,调用接口报400 bad request
改用pb2即可,经查证是CLS还未支持pb3
5. 测试环境问题
业务涉及sts服务换票、cls签名校验等环节,因此在测试过程中,若使用测试环境,需要配置如下host才能正常访问到测试环境上,而且需要注意的是,cls的测试环境URL是现网的ap-guangzhou