对乱糟糟的日志说再见

1,090 阅读8分钟

前言

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

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

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

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

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

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

1

项目特性

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

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

gitee.com/dromara/TLo…

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

2

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

3

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

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

4

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

“TLog的定位是提供了一种最简单的方式来解决日志追踪问题,它不收集日志,也不需要另外的存储空间,它只是自动的对你的业务日志进行打标签,自动生成TraceId贯穿你微服务的一整条链路。并且提供上下游节点信息。适合中小型企业以及想快速解决日志追踪问题的公司项目使用。“

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

支持的日志框架

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

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

5

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

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

7

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

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

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

其他场景的支持

参数&耗时打印支持:

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

tlog.enableInvokeTimePrint=true

出来的效果如下:

6

异步线程&线程池的支持

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

但是对于线程池场景,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

打印5w条日志(秒)打印10w条日志(秒)
第1次6.49624997415.595447718
第2次6.18571252114.295489162
第3次6.11612371813.559289437
第4次6.20577126112.782565374
第5次6.72720811712.884360048
第6次5.90848915714.604699842
第7次6.15315106613.700609245
第8次6.60396083613.048889457
第9次6.13971819612.584335736
第10次6.36592058812.85222910
平均6.2913.60

加入TLog

打印5w条日志(秒)打印10w条日志(秒)
第1次5.99798141612.878389572
第2次6.15459009314.268328625
第3次6.22801058112.385200456
第4次6.45294978815.542794904
第5次6.15622599512.350440713
第6次6.12161188712.543883453
第7次6.1813127312.192140225
第8次6.23825468212.159684042
第9次6.40363258812.308115127
第10次5.95478115312.321667925
平均6.1912.89

测试结果有点出乎意料,加了TLog后10次平均下来反而比不加要快第一点。但是我推测应该是测试环境和样本数量太少的问题,并不是说加反而比不加要快。只能说,如果进行100次,1000次测试。2者应该是差不多的。

从这个性能测试也侧面反映了,TLog不会给系统带来额外的开销。这点也赞一下。

总结

这次评测这款开源框架TLog总体上还算是个日志框架,但是集成了分布式追踪,日志标签和其他一些小功能还算是一个蛮有特色的Java开源项目,从结构上来说,它非常小巧,而且性能也非常优越。从实用性上来说,它解决了在中小公司快速定位日志的痛点。缺点是不收集日志,无法做更有效的日志挖掘,但是这也是TLog号称10分钟接入的原因。从客观上来分析,这有利也有弊。希望TLog在之后能够完善这一部分的功能。