【日志服务CLS】应用工作流ASW接入CLS实践分享

2021-05-31 15:47:13 浏览数 (1)

本文介绍了通过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接入最佳实践

本次业务场景的接入需要完成如下事情:

  1. CAM换票,得到SecretId、SecretKey
  2. CLS签名构造
  3. 调用CLS API:创建日志集、创建日志主题、创建索引、写入日志
  4. 获取结果

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

0 人点赞