前言

最近一个朋友老是和我抱怨:公司系统日志打的实在是太烂了,有用的信息很少,没用的一大堆。就连那有用的信息,在那么多节点日志之间进行追查,也是痛苦的一笔。

我问他,公司没有日志收集吗,日志收集起来看总好过一个节点一个节点日志查看。他表示,公司有接入一个收费第三方的日志产品,做了收集。但是仅仅是方便了统一化查看搜索,但是系统本身的日志缺少一些关键性的要素。比较乱,在很多微服务之间查看调用日志时定位很难。

归纳下来问题有以下几点:

  • 并非所有的日志有关键性信息,比如订单号和SKU信息,有些日志有,有些日志没有,导致有些日志虽然打出了处理步骤日志,但是并不知道是处理哪一个对象。
  • 日志没有统一规范,导致看起来非常杂乱无章
  • 微服务之间同一个请求的调用链追查更加痛苦,往往只能根据时间戳去搜索,并发小的时候,通过时间戳还能查到,并发一大,查问题的成本太大了。

我给他推荐了一些分布式追踪框架,skywalking,pinpoint。他看过之后表示,很完善,但是搭建和推行成本有点大。还涉及到存储成本 ,公司已经购买了第三方的日志服务。对接起来还是有点麻烦的。恐怕上面不同意这么折腾。

近段时间,在开源社区看到这么一款开源框架,号称是轻量级的日志追踪神器,10分钟接入,于是我推荐了给了朋友。过了几日,他和我表示这个东西非常贴切他现在的痛点,现在已经上生产,初步效果来看,还是非常满意的。能给他们的日志定位减少时间成本。

项目特性

受邀请,所以我打算来分析下这款框架。给大家一个直观的理解。

这个框架叫TLog,项目托管在Gitee上

https://gitee.com/dromara/TLog

主页长这样,浓浓的一股暗黑系。。。

对乱糟糟的日志说再见-LMLPHP

我使用下来,直白点的说,就是TLog为每一行日志自动打了前缀,也就是所谓的标签。标签分为系统级标签和业务型标签,其中业务型标签开发者可以自定义。画了张图便于理解:

对乱糟糟的日志说再见-LMLPHP

TLog最终呈现的每行日志,就如同上图所示。其中系统日志,能够展现的信息目前有5个,上游信息能够让你知道是谁调用了你的系统,链路TraceId则是跨微服务的全局链路唯一ID,搜索一个Id,就能得到所有系统中同一请求的日志。这个还是很香的!

关于SpanId,官网的解释是,这是一个代表本次调用在整个调用链路树中的位置,具体演示借用下官网的图,解释的还算清晰:

个人对SpanId的理解是,这个东西可以让你知道系统在某一个调用链中的层级,如果加以收集,可以通过spanId生成一棵调用链路树。其实很希望TLog能实现这个树的展示,可惜现在还不支持。

这是官网的赘述,事实上我在测试的时候,TLog所提供的日志就是日志本身,在多节点微服务当中,日志还是分散的。只是在逻辑上给日志进行一定程度的串联。但是同时,TLog文档也建议说,利用其它的方案去做日志收集。比如ELK,阿里云日志,其它收费的日志产品等等。TLog只是修改日志,并不生成新的日志。所以对接其它日志收集方案,也是完全没有任何问题的,对于已经对接日志收集方案的公司来说,也完全不需要修改什么。

支持的日志框架

每个公司所用的日志框架形形色色。TLog宣称支持了主流的三大日志框架:log4j,log4j2,logback

实际测试中,在这3个框架中,TLog也都能够正常打印出标签。只是在接入过程中,官方给出的接入方式有3种

对乱糟糟的日志说再见-LMLPHP

测试下来,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个层级,都会自动加上你定义的标签

这个功能在对日志的排版和查找上,又能增加很多个标记。这个很赞!

对乱糟糟的日志说再见-LMLPHP

甚至于自定义标签还支持对信息的逻辑处理,可以自定义类去处理这些信息

@TLogAspect(convert = CustomAspectLogConvert.class)
public void demo(Person person){
  log.info("自定义Convert示例");
}

这个具体效果,大家可以去试试。总之一个标签搞定所有的自定义标签。

其他场景的支持

参数&耗时打印支持:

引入了TLog之后,发现TLog还附带了无论在哪种框架之下每个方法的参数打印和耗时,默认为关闭,需要的只需要配置下就可以了:

tlog.enableInvokeTimePrint=true

出来的效果如下:

对乱糟糟的日志说再见-LMLPHP

异步线程&线程池的支持

如果你的项目有异步线程,对于标签传递的连贯性,也是自动支持的,没有任何问题。

但是对于线程池场景,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在之后能够完善这一部分的功能。

关于我

我是一个开源作者,也是一名内容创作者。「元人部落」是一个坚持做原创的技术科技分享号,会一直分享原创的技术文章,陪你一起成长。

对乱糟糟的日志说再见-LMLPHP

05-18 07:32