前言
最近一个朋友老是和我抱怨:公司系统日志打的实在是太烂了,有用的信息很少,没用的一大堆。就连那有用的信息,在那么多节点日志之间进行追查,也是痛苦的一笔。
我问他,公司没有日志收集吗,日志收集起来看总好过一个节点一个节点日志查看。他表示,公司有接入一个收费第三方的日志产品,做了收集。但是仅仅是方便了统一化查看搜索,但是系统本身的日志缺少一些关键性的要素。比较乱,在很多微服务之间查看调用日志时定位很难。
归纳下来问题有以下几点:
- 并非所有的日志有关键性信息,比如订单号和SKU信息,有些日志有,有些日志没有,导致有些日志虽然打出了处理步骤日志,但是并不知道是处理哪一个对象。
- 日志没有统一规范,导致看起来非常杂乱无章
- 微服务之间同一个请求的调用链追查更加痛苦,往往只能根据时间戳去搜索,并发小的时候,通过时间戳还能查到,并发一大,查问题的成本太大了。
我给他推荐了一些分布式追踪框架,skywalking,pinpoint。他看过之后表示,很完善,但是搭建和推行成本有点大。还涉及到存储成本 ,公司已经购买了第三方的日志服务。对接起来还是有点麻烦的。恐怕上面不同意这么折腾。
近段时间,在开源社区看到这么一款开源框架,号称是轻量级的日志追踪神器,10分钟接入,于是我推荐了给了朋友。过了几日,他和我表示这个东西非常贴切他现在的痛点,现在已经上生产,初步效果来看,还是非常满意的。能给他们的日志定位减少时间成本。
项目特性
受邀请,所以我打算来分析下这款框架。给大家一个直观的理解。
这个框架叫TLog,项目托管在Gitee上
https://gitee.com/dromara/TLog
主页长这样,浓浓的一股暗黑系。。。
我使用下来,直白点的说,就是TLog为每一行日志自动打了前缀,也就是所谓的标签
。标签分为系统级标签和业务型标签,其中业务型标签开发者可以自定义。画了张图便于理解:
TLog最终呈现的每行日志,就如同上图所示。其中系统日志,能够展现的信息目前有5个,上游信息能够让你知道是谁调用了你的系统,链路TraceId则是跨微服务的全局链路唯一ID,搜索一个Id,就能得到所有系统中同一请求的日志。这个还是很香的!
关于SpanId,官网的解释是,这是一个代表本次调用在整个调用链路树中的位置,具体演示借用下官网的图,解释的还算清晰:
个人对SpanId的理解是,这个东西可以让你知道系统在某一个调用链中的层级,如果加以收集,可以通过spanId生成一棵调用链路树。其实很希望TLog能实现这个树的展示,可惜现在还不支持。
这是官网的赘述,事实上我在测试的时候,TLog所提供的日志就是日志本身,在多节点微服务当中,日志还是分散的。只是在逻辑上给日志进行一定程度的串联。但是同时,TLog文档也建议说,利用其它的方案去做日志收集。比如ELK,阿里云日志,其它收费的日志产品等等。TLog只是修改日志,并不生成新的日志。所以对接其它日志收集方案,也是完全没有任何问题的,对于已经对接日志收集方案的公司来说,也完全不需要修改什么。
支持的日志框架
每个公司所用的日志框架形形色色。TLog宣称支持了主流的三大日志框架:log4j,log4j2,logback
实际测试中,在这3个框架中,TLog也都能够正常打印出标签。只是在接入过程中,官方给出的接入方式有3种
测试下来,javaagent的方式对于有些项目的确不太稳定,有些复杂的项目会出现无效的情况。对于宣称最稳定的日志适配方式,测试了一下公司的项目,的确能顺利接入。
接入方式,按照文档一步步来就可以了。
支持的RPC框架
既然是跨微服务进行日志追踪,在实现方面也要对常用的RPC进行支持。TLog支持了Dubbo,SpringCloud,Dubbox三种常用的RPC,这点还是不错的。
实际测试中,在Spring cloud这块,TLog还支持了SpringCloud的Gateway。
在接入过程中,无论是哪种RPC框架,在springboot环境下TLog也能自动适配,引入一个就能自动装配。无需额外的配置。这点很方便。
但是在原生spring环境下(非springboot),还是需要xml的额外配置的,但是也相对简单,文档也有专门的说明。
业务标签
除了系统给予的标签外,我发现TLog另一大特点就是允许开发者自定义标签。接入也很简单,举个例子:
@TLogAspect({"str","user.name","user.userDetail.company","user.dddd"})
public void test(String str, User user){
log.info("这是自定义表达标签");
log.info("这是业务日志1");
log.info("这是业务日志2");
log.info("这是业务日志3");
log.info("这是业务日志4");
log.info("这是业务日志5");
}
只要在方法上加一个标签,那么这个方法下面所有的日志,包括之后的N个层级,都会自动加上你定义的标签
这个功能在对日志的排版和查找上,又能增加很多个标记。这个很赞!
甚至于自定义标签还支持对信息的逻辑处理,可以自定义类去处理这些信息
@TLogAspect(convert = CustomAspectLogConvert.class)
public void demo(Person person){
log.info("自定义Convert示例");
}
这个具体效果,大家可以去试试。总之一个标签搞定所有的自定义标签。
其他场景的支持
参数&耗时打印支持:
引入了TLog之后,发现TLog还附带了无论在哪种框架之下每个方法的参数打印和耗时,默认为关闭,需要的只需要配置下就可以了:
tlog.enableInvokeTimePrint=true
出来的效果如下:
异步线程&线程池的支持
如果你的项目有异步线程,对于标签传递的连贯性,也是自动支持的,没有任何问题。
但是对于线程池场景,TLog并没有原生支持。但是提供了一个辅助类,需要少量的侵入代码。这点还有待改善。
MQ支持
同样的,TLog也考虑到了MQ场景标签的传递。这个也需要少量的侵入代码。如果你什么都不改,则在MQ场景下无法支持。
性能
对于性能,我对TLog进行了简单的测试,只在log4j2的环境下进行了测试,测试条件是同步打印出几w条日志,在原生环境下的耗时和加入TLog框架之后的耗时对比,每组分别测10次,取平均值
测试代码非常简单:
StopWatch stopWatch = new StopWatch();
stopWatch.start();
for (int i = 0; i < 100; i++) {
log.info("test log {}", i+1);
}
stopWatch.stop();
log.info("耗时:{}",stopWatch.getTotalTimeSeconds());
不加TLog
第1次 | 6.496249974 | 15.595447718 |
第2次 | 6.185712521 | 14.295489162 |
第3次 | 6.116123718 | 13.559289437 |
第4次 | 6.205771261 | 12.782565374 |
第5次 | 6.727208117 | 12.884360048 |
第6次 | 5.908489157 | 14.604699842 |
第7次 | 6.153151066 | 13.700609245 |
第8次 | 6.603960836 | 13.048889457 |
第9次 | 6.139718196 | 12.584335736 |
第10次 | 6.365920588 | 12.85222910 |
平均 | 6.29 | 13.60 |
加入TLog
第1次 | 5.997981416 | 12.878389572 |
第2次 | 6.154590093 | 14.268328625 |
第3次 | 6.228010581 | 12.385200456 |
第4次 | 6.452949788 | 15.542794904 |
第5次 | 6.156225995 | 12.350440713 |
第6次 | 6.121611887 | 12.543883453 |
第7次 | 6.18131273 | 12.192140225 |
第8次 | 6.238254682 | 12.159684042 |
第9次 | 6.403632588 | 12.308115127 |
第10次 | 5.954781153 | 12.321667925 |
平均 | 6.19 | 12.89 |
测试结果有点出乎意料,加了TLog后10次平均下来反而比不加要快第一点。但是我推测应该是测试环境和样本数量太少的问题,并不是说加反而比不加要快。只能说,如果进行100次,1000次测试。2者应该是差不多的。
从这个性能测试也侧面反映了,TLog不会给系统带来额外的开销。这点也赞一下。
总结
这次评测这款开源框架TLog总体上还算是个日志框架,但是集成了分布式追踪,日志标签和其他一些小功能还算是一个蛮有特色的Java开源项目,从结构上来说,它非常小巧,而且性能也非常优越。从实用性上来说,它解决了在中小公司快速定位日志的痛点。缺点是不收集日志,无法做更有效的日志挖掘,但是这也是TLog号称10分钟接入的原因。从客观上来分析,这有利也有弊。希望TLog在之后能够完善这一部分的功能。
关于我
我是一个开源作者,也是一名内容创作者。「元人部落」是一个坚持做原创的技术科技分享号,会一直分享原创的技术文章,陪你一起成长。