前言

日志服务(Cloud Log Service,CLS)是腾讯云提供的一站式日志服务平台,提供了从日志采集、日志存储到日志检索,图表分析、监控告警、日志投递等多项服务,协助用户通过日志来解决业务运维、服务监控、日志审计等场景问题。

简言之就是CLS提供了日志的云化存储,并提供了查询、分析、监控,告警等功能。所以今天就抱着好奇之心,来探索一下使用python如何将本机日志写入到CLS上。

环境配置

官方文档提供了详细的使用步骤使用步骤,文档链接如下:https://cloud.tencent.com/document/product/614/34340

1. 服务开通

点击https://cloud.tencent.com/product/cls进入页面,可以点击立即使用开通服务;



当然也可以点击活动公告来查看免费的使用额度:



可以看出,免费额度流量额度是5GB/日,活动截止于2021年底。

开通服务后,进入clk服务页面。可以看到,提供了多种日志的接入方案。

2. 创建日志集和日志主题

日志集(Logset)是日志服务的项目管理单元,用于区分不同项目的日志。日志主题(Topic)是日志服务的基本管理单元,用来存储日志文件。一个日志集可以包含多个日志主题。

点击https://console.cloud.tencent.com/cls/overviewCLS配置页面。

点击侧栏日志主题 ,点击创建日志主题



可能是文档过旧,官方文档写的是先要创建日志集,但是没找到这个按钮。其实在第一次创建时主题时输入一个日志集,就会自动创建。

创建好的日志主题如下,这里需要的是主题ID,以为写入时通过ID来将日志写到这个topic。

3. 创建机器组

CLS使用机器组来统一管理一组日志源机器。。同时我也理解成白名单,只有这些机器能访问CLS服务。

Python日志写入CLS

在刚开始CLS的概览页面,可以看到CLS提供了多种快速接入方案,很多需要安装Loglistener来采集日志,这里使用Python利用API写入接入方案来将日志写入,无需安装。

点击每种接入方案都会进入相应的开发文档,这里我点击API写入进入开发文档。

官方提供了API写入规范:

POST /structuredlog?topic_id=xxxxxxxx-xxxx-xxxx-xxxx HTTP/1.1
Host: <Region>.cls.tencentyun.com
Authorization: <AuthorizationString>
Content-Type: application/x-protobuf
x-cls-compress-type:lz4 <LogGroupList 的 PB 格式打包内容>

从上面可以看出有两个参数,一个是topic_id,即日志主题id;一个是LogGroupList,即日志传输协议内容。这里PB指的是使用protobuf进行序列化,所以必须先安装protobuf。

安装protobuf

protobuf是一种二进制的序列化格式,相对于json来说体积更小,传输更快。安装protobuf的目的主要用来将proto文件编译成python、c、Java可调用的接口。

# 如果gcc版本较低,需要升级gcc
wget https://main.qcloudimg.com/raw/d7810aaf8b3073fbbc9d4049c21532aa/protobuf-2.6.1.tar.gz
tar -zxvf protobuf-2.6.1.tar.gz -C /usr/local/ && cd /usr/local/protobuf-2.6.1
./configure
make && make install
# 可以在/etc/profile或者~/.bash_profile末尾设置永久有效
export PATH=$PATH:/usr/local/protobuf-2.6.1/bin

使用下面命令查看是否安装成功。

protoc --version

构建python可调用的PB

创建cls.proto文件,定义序列化结构:

package cls;

message Log
{
message Content
{
required string key = 1; // 每组字段的 key
required string value = 2; // 每组字段的 value
}
required int64 time = 1; // 时间戳,UNIX时间格式
repeated Content contents = 2; // 一条日志里的多个kv组合
} message LogTag
{
required string key = 1;
required string value = 2;
} message LogGroup
{
repeated Log logs = 1; // 多条日志合成的日志数组
optional string contextFlow = 2; // 目前暂无效用
optional string filename = 3; // 日志文件名
optional string source = 4; // 日志来源,一般使用机器IP
repeated LogTag logTags = 5;
} message LogGroupList
{
repeated LogGroup logGroupList = 1; // 日志组列表
}

只用下面命令将proto文件转换为python可调用的接口。

protoc cls.proto --python_out=./

执行完后,在此目录下生成cls_pb2.py

python代码开发

代码的开发主要分为三个部分:Protobuf结构构造、Authorization加密构造和请求上传日志。前两个部分细节太多,尤其是Authorization构造涉及sha1加密、hmac-sha1签名以及四个加密参数的构造。:

1. Protobuf结构构造

import cls_pb2 as cls
import time
import requests
from hashlib import sha1
import hmac # 构建protoBuf日志内容
LogLogGroupList = cls.LogGroupList() LogGroup = LogLogGroupList.logGroupList.add()
LogGroup.contextFlow = "1"
LogGroup.filename = "python.log"
LogGroup.source = "localhost" LogTag = LogGroup.logTags.add()
LogTag.key = "key"
LogTag.value = "value" Log = LogGroup.logs.add()
Log.time = int(round(time.time() * 1000000)) Content = Log.contents.add()
Content.key = "Hello"
Content.value = "World"
print(LogLogGroupList)
# 序列化
LogLogGroupList = LogLogGroupList.SerializeToString()

2. Authorization加密构造

查看文档:https://cloud.tencent.com/document/product/614/12445,里面有详细的参数生成步骤和样例。

这部分的代码开发绝对考验个人的耐心和细心,适合在夜深人静自己搞。

# 公共参数部分
secretId = '替换成你的secretId'
secretKey = '替换成你的secretKey'
region = 'ap-nanjing'
host = f'{region}.cls.tencentyun.com'
start = int(time.time())
end = start + 1000
uri = 'structuredlog'
method = 'post'
params = 'topic' # 构建HttpRequestInfo
HttpRequestInfo = f'{method}\n' + f'/{uri}\n' + '\n\n'
sha1_info = sha1()
sha1_info.update(HttpRequestInfo.encode('utf-8'))
print(sha1_info.hexdigest()) # 根据HttpRequestInfo构建StringToSign
StringToSign = 'sha1\n' + f'{start};{end}\n' + sha1_info.hexdigest() + '\n'
key = secretKey.encode('utf-8')
value = f'{start};{end}'.encode('utf-8')
SignKey = hmac.new(key, value, 'sha1')
print(SignKey.hexdigest()) # 根据StringToSign构建Signature
key = SignKey.hexdigest().encode('utf-8')
value = StringToSign.encode('utf-8')
Signature = hmac.new(key, value, 'sha1').hexdigest()
print(Signature) # 构建Authorization
Authorization = f'q-sign-algorithm=sha1&q-ak={secretId}&q-sign-time={start};{end}&q-key-time={start};{end}&q-header-list=&q-url-param-list=&q-signature={Signature}'

这一块是让我感觉最难的,里面的坑太多,一个参数套一个参数,容易让人云里雾里,所以大部分时间都花在了测试参数生成这部分。



如图,一直提示我签名计算错误,原因总结如下:1.参数拼接不对;2.hmac的kv弄反。

本来我也在请求头里添加了lz4压缩格式,但是运行发现代码中未实现lz4的压缩,所以报了以下错误。



最后舍弃了lz4请求头,压缩功能也没有实现。有兴趣的可以搞一下。

3. 上传日志

其实就是构造一个post请求,将日志序列化成protobuf格式上传到服务器。

# 发起请求
url = f'https://{host}/{uri}?topic_id=717eba7d-85bb-4cd5-9c68-dfaa9f672bc6'
headers = {'Authorization': Authorization, 'Host': host, 'Content-Type': 'application/x-protobuf'}
response = requests.post(url, headers=headers, data=LogLogGroupList)
print(response.status_code, response.text)
print(LogLogGroupList)

运行测试

python3运行程序:

打印了日志的protobuf结构信息、二进制数据,以及加密参数和请求状态码。



接着进入CLS页面查看,日志已经写入。

结语

跟着文档从学习CLS、python开发到收集素材、整理成文章差不多用了五、六个小时,下班就在搞,写到这的时候已经凌晨一点了,本来还想用Java写一版,但是实在是肝不动了。

希望这篇文章能够帮助你了解CLS,期待下一次相遇。


95后小程序员,写的都是日常工作中的亲身实践,置身于初学者的角度从0写到1,详细且认真。文章会在公众号 [入门到放弃之路] 首发,期待你的关注。



CLS的探索:Python如何让日志免费云化的更多相关文章

  1. 探索 Python 学习

    Python 是一种敏捷的.动态类型化的.极富表现力的开源编程语言,可以被自由地安装到多种平台上(参阅 参考资料).Python 代码是被解释的.如果您对编辑.构建和执行循环较为熟悉,则 Python ...

  2. 转:python教程专题资源免费下载整理合集收藏

    python教程专题资源免费下载整理合集收藏 < Python学习手册(第4版)>(Learning Python, 4th Edition)[PDF] 94MB 简体中文 <Pyt ...

  3. python高效解析日志入库

    python脚本解析日志文件入库一般有三个重要的步骤:读文件.解析文件.入库.在这三个方面下功夫,可确保我们获得最优的性能(这里不讨论并发) 1 读文件:一次读一行,磁盘IO太多,效率低下:一次性读如 ...

  4. Python切割nginx日志_小组_ThinkSAAS

    Python切割nginx日志_小组_ThinkSAAS Python切割nginx日志

  5. 用anaconda的pip安装第三方python包的日志

    用anaconda的pip安装第三方python包的日志 启动anaconda命令窗口: 开始> 所有程序> anaconda> anaconda prompt 会得到两行提示: D ...

  6. python之配置日志的三种方式

    以下3种方式来配置logging: 1)使用Python代码显式的创建loggers, handlers和formatters并分别调用它们的配置函数: 2)创建一个日志配置文件,然后使用fileCo ...

  7. Python之配置日志的几种方式(logging模块)

    原文:https://blog.csdn.net/WZ18810463869/article/details/81147167 作为开发者,我们可以通过以下3种方式来配置logging: 1)使用Py ...

  8. python中的日志操作和发送邮件

    1.python中的日志操作 安装log模块:pip install nnlog 参数:my_log = nnlog.Logger('server_log.log',level='debug',bac ...

  9. 【转】Python之向日志输出中添加上下文信息

    [转]Python之向日志输出中添加上下文信息 除了传递给日志记录函数的参数(如msg)外,有时候我们还想在日志输出中包含一些额外的上下文信息.比如,在一个网络应用中,可能希望在日志中记录客户端的特定 ...

随机推荐

  1. 2.pandas常用读取

    一.文本读写 名称 接收 代表(含义) 默认 filepath string 文件路径 无 sep string 分割符 ',' header Int/sequence 某行做列名 infer自动寻找 ...

  2. ARFoundation - 实现物体旋转, 平移,缩放

    ARFoundation - 实现物体旋转, 平移,缩放 本文目的是为了确定在移动端怎样通过单指滑动实现物体的旋转,双指实现平移和缩放. 前提知识: ARFoundation - touch poin ...

  3. 使用C# (.NET Core) 实现模板方法模式 (Template Method Pattern)

    本文的概念内容来自深入浅出设计模式一书. 项目需求 有一家咖啡店, 供应咖啡和茶, 它们的工序如下: 咖啡: 茶: 可以看到咖啡和茶的制作工序是差不多的, 都是有4步, 其中有两步它们两个是一样的, ...

  4. python登陆界面尝试

    示例1: """ 编写一个程序 用户可以输入用户名和密码 用户有三次机会 登录成功可以进行相应的操作 输入Q退出系统 """ name_li ...

  5. 面试高频题:说一说对Spring和SpringMvc父子容器的理解?

    引言 以前写了几篇关于SpringBoot的文章<面试高频题:springBoot自动装配的原理你能说出来吗>.<保姆级教程,手把手教你实现一个SpringBoot的starter& ...

  6. (二)基于商品属性的相似商品推荐算法——Flink SQL实时计算实现商品的隐式评分

    系列随笔: (总览)基于商品属性的相似商品推荐算法 (一)基于商品属性的相似商品推荐算法--整体框架及处理流程 (二)基于商品属性的相似商品推荐算法--Flink SQL实时计算实现商品的隐式评分 ( ...

  7. Go-23-接口

    接口定义 type 接口名 interface{ 方法1(参数列表) [返回值] 方法2(参数列表)[返回值] } 接口实现 func (变量 结构体类型)方法1 ([参数列表])(返回值){ } f ...

  8. Python容器相关操作

    (集合与字典除外)的容器相关操作 (1)容器的拼接 >>> 'abc' + 'def' 'abcdef' (2)容器的重复 >>> (1, 2) * 3 (1, 2 ...

  9. springboot的logback的配置文件

    之前敲出来一个 logback 的配置文件,防止以后找起来麻烦在这里存个档 修改了日志输出的内容 设置默认级别为 INFO 正常日志 ( TRACE 到 WARN ) 输出到单独的文件夹 异常日志 ( ...

  10. PAT归纳总结——关于C++输入输出格式问题的一些总结

    自从使用了C++就不再想使用C语言来刷题了,C++便捷的输入输出方式,以及一些STL库函数的使用都要比使用C语言方便的多.但是使用的时候还有一些需要注意的地方,在这篇博客中写一下.(更好的教程可以参看 ...