随着微服务盛行,不少公司都把系统按照业务边界拆成了不少微服务,在排错查日志的时候。由于业务链路贯穿着不少微服务节点,致使定位某个请求的日志以及上下游业务的日志会变得有些困难。java
这时候不少童鞋会开始考虑上SkyWalking,Pinpoint等分布式追踪系统来解决,基于OpenTracing规范,并且一般都是无侵入性的,而且有相对友好的管理界面来进行链路Span的查询。git
可是搭建分布式追踪系统,熟悉以及推广到全公司的系统须要必定的时间周期,并且当中涉及到链路span节点的存储成本问题,全量采集仍是部分采集?若是全量采集,就以SkyWalking的存储来举例,ES集群搭建至少须要5个节点。这就须要增长服务器成本。何况若是微服务节点多的话,一天下来产生几十G上百G的数据其实很是正常。若是想保存时间长点的话,也须要增长服务器磁盘的成本。web
因此此次介绍的开源项目是TLog,它的产生背景源于想作一个轻量级的日志追踪解决方案,覆盖目前流行的日志框架和RPC框架,让用户以最少的成原本接入以解决微服务体系中日志跟踪的痛点。spring
固然分布式追踪系统是一个最终的解决方案,若是您的公司已经上了分布式追踪系统,那TLog并不适用。apache
TLog提供了一种最简单的方式来解决日志追踪问题,它不收集日志,也不须要另外的存储空间,它只是自动的对你的业务日志进行打标签,自动生成TraceId贯穿你微服务的一整条链路。而且提供上下游节点信息。适合中小型企业以及想快速解决日志追踪问题的公司项目使用。tomcat
为此我为了TLog适配了三大日志框架,支持自动检测适配。支持dubbo,dubbox,spring cloud三大RPC框架,更重要的是,你的项目接入TLog,可能连十分钟就不须要 :)springboot
项目地址:https://gitee.com/bryan31/TLog
TLog具备如下特性:服务器
TLog支持了springboot的自动装配,在springboot环境下,只须要如下两步就能够接入!app
依赖框架
<dependency> <groupId>com.yomahub</groupId> <artifactId>tlog-all-spring-boot-starter</artifactId> <version>1.0.0</version> </dependency>
目前jar包已上传中央仓库,能够直接依赖到
日志框架适配
只须要在你的启动类中加入一行代码,便可以自动进行探测你项目所使用的Log框架,并进行加强,目前支持log4j,log4j2,logback三大日志框架。
@SpringBootApplication public class Runner { static {AspectLogEnhance.enhance();}//进行日志加强,自动判断日志框架 public static void main(String[] args) { SpringApplication.run(Runner.class, args); } }
须要注意的是,由于这里是用javassit实现,须要在jvm加载对应日志框架的类以前,进行字节码加强。因此这里用static块。可是在如下2种状况下这种一行自动适配的可能不会生效:
1.Springboot/Spring的启动类加入log定义,这种状况不会生效,由于classload在加载static块以前已经把log日志框架加载了。
2.你是用tomcat/jboss/jetty等外置容器启动的(对于springboot内置容器无影响)
对于这2种状况,TLog也提供了3大日志框架的单独适配,只要替换日志配置文件中的相应layout类就能够了,下文也会介绍到
RPC框架的适配
在Springboot环境下,TLog会自动探测你用的RPC框架,自动进行适配。
作完以上2步,就ok了,最终效果以下(这里以dubbo+log4j为例):
Consumer端代码:
日志打印:
2020-09-16 18:12:56,748 [WARN] [TLOG]从新生成traceId[7161457983341056] >> com.yomahub.tlog.web.TLogWebInterceptor:39 2020-09-16 18:12:56,763 [INFO] <7161457983341056> logback-dubbox-consumer:invoke method sayHello,name=jack >> com.yomahub.tlog.example.dubbox.controller.DemoController:22 2020-09-16 18:12:56,763 [INFO] <7161457983341056> 测试日志aaaa >> com.yomahub.tlog.example.dubbox.controller.DemoController:23 2020-09-16 18:12:56,763 [INFO] <7161457983341056> 测试日志bbbb >> com.yomahub.tlog.example.dubbox.controller.DemoController:24
Provider代码:
日志打印:
2020-09-16 18:12:56,854 [INFO] <7161457983341056> logback-dubbox-provider:invoke method sayHello,name=jack >> com.yomahub.tlog.example.dubbo.service.impl.DemoServiceImpl:15 2020-09-16 18:12:56,854 [INFO] <7161457983341056> 测试日志cccc >> com.yomahub.tlog.example.dubbo.service.impl.DemoServiceImpl:16 2020-09-16 18:12:56,854 [INFO] <7161457983341056> 测试日志dddd >> com.yomahub.tlog.example.dubbo.service.impl.DemoServiceImpl:17
能够看到,通过简单接入后,各个微服务之间每一个请求有一个全局惟一的traceId贯穿其中,对全部的日志输出都能生效,这下定位某个请求的日志链就变得轻松了。
TLog容许用户自定义日志标签的格式,TLog默认只打出traceId,以<$traceId>这种模板打出,固然你能自定义其模板。还能加入其它的标签头
你只须要在springboot的application.properties里以下定义,改变标签的格式,就能按照你定义模板进行打印
tlog.pattern=[$preApp][$preIp][$traceId]
$preApp
:上游微服务节点名称
$preIp
:上游微服务的IP地址
$traceId
:全局惟一跟踪ID
若是你的自动化日志探测失效或者你用的是外置容器,你须要针对你项目中的日志框架配置进行修改,修改方法也很简单。
Log4j配置文件加强
只须要把layout
的实现类换掉就能够了
每一个公司的Log4J的模板大同小异,这里只给出xml的例子
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <log4j:configuration> <appender name="stdout" class="org.apache.log4j.ConsoleAppender"> <!--替换成AspectLog4jPatternLayout--> <layout class="com.yomahub.tlog.core.enhance.log4j.AspectLog4jPatternLayout"> <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss,SSS} [%p] %m >> %c:%L%n"/> </layout> </appender> <appender name="fileout" class="org.apache.log4j.DailyRollingFileAppender"> <param name="File" value="./logs/test.log"/> <!--替换成AspectLog4jPatternLayout--> <layout class="com.yomahub.tlog.core.enhance.log4j.AspectLog4jPatternLayout"> <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss,SSS} [%p] %m >> %c:%L%n"/> </layout> </appender> <root> <priority value="info" /> <appender-ref ref="stdout"/> <appender-ref ref="fileout"/> </root> </log4j:configuration>
Logback的配置文件加强
换掉encoder
的实现类或者换掉layout
的实现类就能够了
如下给出xml示例:
<?xml version="1.0" encoding="UTF-8"?> <configuration debug="false"> <property name="APP_NAME" value="logtest"/> <property name="LOG_HOME" value="./logs" /> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <!--替换成AspectLogbackEncoder--> <encoder class="com.yomahub.tlog.core.enhance.logback.AspectLogbackEncoder"> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> </encoder> </appender> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <File>${LOG_HOME}/${APP_NAME}.log</File> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <FileNamePattern>${LOG_HOME}/${APP_NAME}.log.%d{yyyy-MM-dd}.%i.log</FileNamePattern> <MaxHistory>30</MaxHistory> <maxFileSize>1000MB</maxFileSize> </rollingPolicy> <!--替换成AspectLogbackEncoder--> <encoder class="com.yomahub.tlog.core.enhance.logback.AspectLogbackEncoder"> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> </encoder> </appender> <!-- 日志输出级别 --> <root level="INFO"> <appender-ref ref="STDOUT" /> <appender-ref ref="FILE" /> </root> </configuration>
Log4j2的配置文件加强
log4J2因为是经过插件形式实现的,log4J2有自动扫描插件的功能。因此无需对配置文件作任何更改就能生效。
TLog本质上是一个日志框架,只不过具备了支持RPC框架的日志追踪功能。写框架大概肝了我一周的时间,力求作到一个最轻量级的日志追踪解决方案,让使用者能以最少的成本接入。TLog不光支持springboot,对非springboot项目也进行了支持,具体配置方法请到项目主页查看文档。
我还为TLog写了详细的示例项目,涵盖了所涉及几乎全部场景,具体示例项目地址也在项目主页。
若是你在项目中也碰到日志追踪困难的场景,不妨来试试TLog吧,但愿这款开源框架能帮助到你,开源不易,如你喜欢,请帮忙star,你的支持是我前进的最大动力。如你碰到任何疑问,也欢迎联系我。
「元人部落」是一个坚持作原创的技术科技分享号,但愿你能关注我,我每周会出一篇实用的原创技术文章,陪着你一块儿走,陪你一块儿成长。关注公众号回复tlog
能加入群聊,我会耐心回答你的每个使用中的问题,也会长期对这个项目进行长期维护和迭代。