这篇文章简单描述一下我这一两天关于trace日志收集的一些思考
trace日志收集的特点
- trace日志分散 trace相关的日志收集和平时的日志收集还是有一些区别的,主要区别在于trace的日志是分散在各个系统的各个机器上,而不是集中在某个或者多个文件中的。这就要求trace的日志收集需要对所有的机器都开启,这样收集到的日志才全。
- trace日志的顺序问题 因为
trace的日志分散
的缘故,以及日志agent
在不同机器上的收集速度问题,可能导致在trace链路中靠后的日志反而先收集上来,而我们展示的时候,一般都是需要按照trace链路的时间顺序来展示的。 - trace日志的查询特点 一般trace的日志,我们查询的时候都会基于
TraceId
来查询,这也就导致trace相关的日志存储的时候,和kafka的文件存储还是有一些区别的。 - 相比写请求来说读请求极少
上面4个点,是我觉的trace日志收集的一些比较特殊的情况。
日志收集疑难点:
- 日志一般存在轮转的情况,比如每小时轮转
- 一般情况下,公司的服务器上都会配置定时压缩脚本,可能存在日志压缩的问题
这2个问题是我接下来准备研究的,所以这篇文章先不说这个。
初步简要设计想法
核心流程
- 各个机器上的原始日志通过
日志收集agent
收集上来以后写入kafka
中,这些原始数据中需要携带文件路径,文件名,机器host,收集的时间戳等信息- 可以基于这个原始的topic做日志的静态存储,写入hdfs中
- 基于的kafka的原始数据,消费这些kafka数据,然后写入kafka的另外一个
topic
中,做日志分类。- 此处需要自定义kafka的分区分配策略,策略核心内容是基于日志中的traceid做分配。将相同的traceId的日志分配给同样的consumer节点,这样当使用traceId做日志查询的时候,就可以使用相同的策略去目标机器上找日志。
- 备注:如果这一步要做数据高可用,那么可以给这个kafka topic增加consumer group来弄,也可以只有一个consumer group,但是写的时候写多个nfs。
- 然后在消费第二步分类以后的kafka数据,这样按照下面说的存储方式存储
机器上的trace日志组织:
- 按天 20190125
- 按小时 20
- 按照分钟级别划分 没10分钟/前后30分钟,最多1分钟一个目录
- 按照appName分 比如
- 如果这样单个目录下的文件数还是太多的话,在按照host来划分
- 按照traceId分 每个traceId一个文件,文本文件,顺序写入,但是注意,这样写入的日志文件直接展示的时候顺序是有问题的,可能存在乱序的问题。
先按照时间是便于定期按照时间删除文件。之所以分这么多目录,主要是考虑到linux文件系统的限制。不要超过ulimit -n
的限制。
单个trace日志文化的日志乱序问题
在上一个小节说的日志存储在单个trace日志文件中是可能乱序的,但是存储的时候没有去排序,只要是考虑到trace系统的特点,写非常多,读相比写来说非常少。而且大多数
时候单个trace链路并不会太长,所以可以考虑查询整个trace日志的时候在排序。
当然也不排序某些循环trace链路的问题,比如A发延迟消息给B,B收到以后在发延迟消息给A,这种就恶心,不过解决99.9%的问题就很不错了已经。
定时任务进行过期和压缩
- 进行文件压缩,我打算选gzip,当然也可以选其他压缩算法,主要是平衡cpu和空间,定时任务压缩前1小时的文件夹下面的所有的trace日志文件
- 文件过期删除
先写这么多