5

SpringBoot 2.5.5整合轻量级的分布式日志标记追踪神器TLog - 陈彦斌

 1 year ago
source link: https://www.cnblogs.com/chenyanbin/p/16804650.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

TLog能解决什么痛点#

  随着微服务盛行,很多公司都把系统按照业务边界拆成了很多微服务,在排错查日志的时候。因为业务链路贯穿着很多微服务节点,导致定位某个请求的日志以及上下游业务的日志会变得有些困难。

  这时候很多童鞋会开始考虑上SkyWalking,Pinpoint等分布式追踪系统来解决,基于OpenTracing规范,而且通常都是无侵入性的,并且有相对友好的管理界面来进行链路Span的查询。

但是搭建分布式追踪系统,熟悉以及推广到全公司的系统需要一定的时间周期,而且当中涉及到链路span节点的存储成本问题,全量采集还是部分采集?如果全量采集,就以SkyWalking的存储来举例,ES集群搭建至少需要5个节点。这就需要增加服务器成本。况且如果微服务节点多的话,一天下来产生几十G上百G的数据其实非常正常。如果想保存时间长点的话,也需要增加服务器磁盘的成本。

当然分布式追踪系统是一个最终的解决方案,如果您的公司已经上了分布式追踪系统,那TLog并不适用。

项目整合#

项目结构#

1504448-20221018230838317-55155903.png

添加依赖#

        <!-- 引入全量tlog依赖 -->
        <dependency>
            <groupId>com.yomahub</groupId>
            <artifactId>tlog-all-spring-boot-starter</artifactId>
            <version>1.5.0</version>
        </dependency>

logback-spring.xml#

<?xml version="1.0" encoding="UTF-8"?>
<!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 -->
<!-- scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true -->
<!-- scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 -->
<!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->
<configuration  scan="true" scanPeriod="10 seconds">

    <contextName>logback</contextName>
    <!-- name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。 -->
    <property name="log.path" value="applog/" />
    <property name="log.name" value="springboot-tlog"/>
    <property name="CONSOLE_LOG_PATTERN_FILE" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %C:%M:%L [%thread] %-5level %msg%n"/>

    <!-- 彩色日志 -->
    <!-- 彩色日志依赖的渲染类 -->
    <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
    <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
    <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
    <!-- 彩色日志格式 -->
    <property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>

    <!--输出到控制台-->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息-->
<!--        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">-->
<!--            <level>info</level>-->
<!--        </filter>-->
        <encoder class="com.yomahub.tlog.core.enhance.logback.AspectLogbackEncoder">
            <Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
            <!-- 设置字符集 -->
            <charset>UTF-8</charset>
        </encoder>
    </appender>


    <!--输出到文件-->
    <!-- 时间滚动输出 level为 INFO 日志 -->
    <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在记录的日志文件的路径及文件名 -->
        <file>${log.path}/${log.name}/${log.name}_info.log</file>
        <!--日志文件输出格式-->
        <encoder class="com.yomahub.tlog.core.enhance.logback.AspectLogbackEncoder">
            <pattern>${CONSOLE_LOG_PATTERN_FILE}</pattern>
            <charset>UTF-8</charset>
        </encoder>
        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 每天日志归档路径以及格式 -->
            <fileNamePattern>${log.path}/${log.name}/info/${log.name}-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文件保留天数-->
            <maxHistory>180</maxHistory>
        </rollingPolicy>
        <!-- 此日志文件只记录info级别的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>info</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!-- 时间滚动输出 level为 ERROR 日志 -->
    <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在记录的日志文件的路径及文件名 -->
        <file>${log.path}/${log.name}/${log.name}_error.log</file>
        <!--日志文件输出格式-->
        <encoder class="com.yomahub.tlog.core.enhance.logback.AspectLogbackEncoder">
            <pattern>${CONSOLE_LOG_PATTERN_FILE}</pattern>
            <charset>UTF-8</charset> <!-- 此处设置字符集 -->
        </encoder>
        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.path}/${log.name}/error/${log.name}-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文件保留天数-->
            <maxHistory>180</maxHistory>
        </rollingPolicy>
        <!-- 此日志文件只记录ERROR级别的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <root level="info">
        <appender-ref ref="CONSOLE" />
        <appender-ref ref="INFO_FILE" />
        <appender-ref ref="ERROR_FILE" />
    </root>

    <!-- sql打印 -->
<!--    <logger name="com.ybchen.mapper" level="DEBUG"/>-->
</configuration>

请求类#

package com.ybchen.request;

import lombok.Data;

/**
 * @author: chenyanbin 2022-10-18 23:03
 */
@Data
public class PersonRequest {
    private Long id;
    private Long age;
    private String name;
}

Controller#

package com.ybchen.controller;

import com.ybchen.request.PersonRequest;
import com.yomahub.tlog.core.annotation.TLogAspect;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author: chenyanbin 2022-10-18 22:56
 */
@RestController
@Slf4j
public class DemoController {
    @TLogAspect({"id"})
    @GetMapping("demo1")
    public void demo1(String id, String name) {
        log.info("这是第一条日志---->简单例子");
        log.info("这是第二条日志---->简单例子");
        log.info("这是第三条日志---->简单例子");
        new Thread(() -> log.info("这是异步日志---->简单例子")).start();
    }

    @TLogAspect({"id", "name"})
    @GetMapping("demo2")
    public void demo2(String id, String name) {
        log.info("这是第一条日志----->多个数值");
        log.info("这是第二条日志----->多个数值");
        log.info("这是第三条日志----->多个数值");
        new Thread(() -> log.info("这是异步日志----->多个数值")).start();
    }

    @TLogAspect(value = {"id", "name"}, pattern = "<-{}->", joint = "_")
    @GetMapping("demo3")
    public void demo3(String id, String name) {
        log.info("多个数值-------->加了patter和joint的示例");
    }

    @TLogAspect(str = "陈彦斌博客地址:https://www.cnblogs.com/chenyanbin/")
    @GetMapping("demo4")
    public void demo4(String name){
        log.info("这是第一条日志----->常量字符串标签");
        log.info("这是第二条日志----->常量字符串标签");
        log.info("这是第三条日志----->常量字符串标签");
        new Thread(() -> log.info("这是异步日志----->常量字符串标签")).start();
    }

    @TLogAspect({"request.id","request.age"})
    @GetMapping("demo5")
    public void demo4(PersonRequest request){
        log.info("多参数加多层级示例");
    }
}

SpanId的生成规则#

1504448-20221018231948774-811685899.png

 TLog业务标签#

  很多公司的系统在打日志的时候,每打一个日志里都会带入一些业务信息,比如记录ID,会员CODE,方便业务日志的定位。现在有了TLog,不仅能做分布式链路标签追加,还能自动帮你做业务标签的添加。这样在定位日志的时候可以更加方便的搜索。

  Tlog支持方法级别的自定义业务标签。你可以在方法上定义简单的标注,来实现在某一个方法的日志里,统一加入业务的指标标签,用于更加细致的定位。

演示#

示例1#

1504448-20221018231506706-1189767823.gif

1504448-20221018231704218-1167901197.png
    @TLogAspect({"id"})
    @GetMapping("demo1")
    public void demo1(String id, String name) {
        log.info("这是第一条日志---->简单例子");
        log.info("这是第二条日志---->简单例子");
        log.info("这是第三条日志---->简单例子");
        new Thread(() -> log.info("这是异步日志---->简单例子")).start();
    }
2022-10-18 23:14:37.450  INFO 88321 --- [nio-8080-exec-4] com.ybchen.controller.DemoController     : <0><11477324755760832> [id:"10086"] 这是第一条日志---->简单例子
2022-10-18 23:14:37.451  INFO 88321 --- [nio-8080-exec-4] com.ybchen.controller.DemoController     : <0><11477324755760832> [id:"10086"] 这是第二条日志---->简单例子
2022-10-18 23:14:37.451  INFO 88321 --- [nio-8080-exec-4] com.ybchen.controller.DemoController     : <0><11477324755760832> [id:"10086"] 这是第三条日志---->简单例子
2022-10-18 23:14:37.452  INFO 88321 --- [      Thread-12] com.ybchen.controller.DemoController     : <0><11477324755760832> [id:"10086"] 这是异步日志---->简单例子
2022-10-18 23:14:41.160  INFO 88321 --- [nio-8080-exec-5] com.ybchen.controller.DemoController     : <0><11477324998899392> [id:"10087"] 这是第一条日志---->简单例子
2022-10-18 23:14:41.160  INFO 88321 --- [nio-8080-exec-5] com.ybchen.controller.DemoController     : <0><11477324998899392> [id:"10087"] 这是第二条日志---->简单例子
2022-10-18 23:14:41.160  INFO 88321 --- [nio-8080-exec-5] com.ybchen.controller.DemoController     : <0><11477324998899392> [id:"10087"] 这是第三条日志---->简单例子
2022-10-18 23:14:41.161  INFO 88321 --- [      Thread-13] com.ybchen.controller.DemoController     : <0><11477324998899392> [id:"10087"] 这是异步日志---->简单例子
2022-10-18 23:14:43.938  INFO 88321 --- [nio-8080-exec-6] com.ybchen.controller.DemoController     : <0><11477325181023936> [id:"10085"] 这是第一条日志---->简单例子
2022-10-18 23:14:43.939  INFO 88321 --- [nio-8080-exec-6] com.ybchen.controller.DemoController     : <0><11477325181023936> [id:"10085"] 这是第二条日志---->简单例子
2022-10-18 23:14:43.939  INFO 88321 --- [nio-8080-exec-6] com.ybchen.controller.DemoController     : <0><11477325181023936> [id:"10085"] 这是第三条日志---->简单例子
2022-10-18 23:14:43.940  INFO 88321 --- [      Thread-14] com.ybchen.controller.DemoController     : <0><11477325181023936> [id:"10085"] 这是异步日志---->简单例子

示例二#

1504448-20221018232258564-1644988224.gif
    @TLogAspect({"id", "name"})
    @GetMapping("demo2")
    public void demo2(String id, String name) {
        log.info("这是第一条日志----->多个数值");
        log.info("这是第二条日志----->多个数值");
        log.info("这是第三条日志----->多个数值");
        new Thread(() -> log.info("这是异步日志----->多个数值")).start();
    }
2022-10-18 23:22:33.941  INFO 88321 --- [nio-8080-exec-8] com.ybchen.controller.DemoController     : <0><11477355982223040> [id:"10085",name:"alex"] 这是第一条日志----->多个数值
2022-10-18 23:22:33.946  INFO 88321 --- [nio-8080-exec-8] com.ybchen.controller.DemoController     : <0><11477355982223040> [id:"10085",name:"alex"] 这是第二条日志----->多个数值
2022-10-18 23:22:33.947  INFO 88321 --- [nio-8080-exec-8] com.ybchen.controller.DemoController     : <0><11477355982223040> [id:"10085",name:"alex"] 这是第三条日志----->多个数值
2022-10-18 23:22:33.950  INFO 88321 --- [      Thread-15] com.ybchen.controller.DemoController     : <0><11477355982223040> [id:"10085",name:"alex"] 这是异步日志----->多个数值
2022-10-18 23:22:37.744  INFO 88321 --- [nio-8080-exec-9] com.ybchen.controller.DemoController     : <0><11477356232308416> [id:"10086",name:"alex"] 这是第一条日志----->多个数值
2022-10-18 23:22:37.744  INFO 88321 --- [nio-8080-exec-9] com.ybchen.controller.DemoController     : <0><11477356232308416> [id:"10086",name:"alex"] 这是第二条日志----->多个数值
2022-10-18 23:22:37.744  INFO 88321 --- [nio-8080-exec-9] com.ybchen.controller.DemoController     : <0><11477356232308416> [id:"10086",name:"alex"] 这是第三条日志----->多个数值
2022-10-18 23:22:37.745  INFO 88321 --- [      Thread-16] com.ybchen.controller.DemoController     : <0><11477356232308416> [id:"10086",name:"alex"] 这是异步日志----->多个数值

示例三#

1504448-20221018232519546-910002436.gif
    @TLogAspect(value = {"id", "name"}, pattern = "<-{}->", joint = "_")
    @GetMapping("demo3")
    public void demo3(String id, String name) {
        log.info("多个数值-------->加了patter和joint的示例");
    }
2022-10-18 23:24:52.137  INFO 88321 --- [nio-8080-exec-1] com.ybchen.controller.DemoController     : <0><11477365039888064> <-id:"10086"_name:"alex"-> 多个数值-------->加了patter和joint的示例
2022-10-18 23:24:56.329  INFO 88321 --- [nio-8080-exec-2] com.ybchen.controller.DemoController     : <0><11477365314614976> <-id:"10089"_name:"alex"-> 多个数值-------->加了patter和joint的示例

示例四#

1504448-20221018232946415-554830546.gif
    @TLogAspect(str = "陈彦斌博客地址:https://www.cnblogs.com/chenyanbin/")
    @GetMapping("demo4")
    public void demo4(String name){
        log.info("这是第一条日志----->常量字符串标签");
        log.info("这是第二条日志----->常量字符串标签");
        log.info("这是第三条日志----->常量字符串标签");
        new Thread(() -> log.info("这是异步日志----->常量字符串标签")).start();
    }
2022-10-18 23:29:25.801  INFO 10245 --- [nio-8080-exec-4] com.ybchen.controller.DemoController     : <0><11477382974797504> [陈彦斌博客地址:https://www.cnblogs.com/chenyanbin/] 这是第一条日志----->常量字符串标签
2022-10-18 23:29:25.802  INFO 10245 --- [nio-8080-exec-4] com.ybchen.controller.DemoController     : <0><11477382974797504> [陈彦斌博客地址:https://www.cnblogs.com/chenyanbin/] 这是第二条日志----->常量字符串标签
2022-10-18 23:29:25.802  INFO 10245 --- [nio-8080-exec-4] com.ybchen.controller.DemoController     : <0><11477382974797504> [陈彦斌博客地址:https://www.cnblogs.com/chenyanbin/] 这是第三条日志----->常量字符串标签
2022-10-18 23:29:25.803  INFO 10245 --- [       Thread-8] com.ybchen.controller.DemoController     : <0><11477382974797504> [陈彦斌博客地址:https://www.cnblogs.com/chenyanbin/] 这是异步日志----->常量字符串标签
2022-10-18 23:29:30.216  INFO 10245 --- [nio-8080-exec-5] com.ybchen.controller.DemoController     : <0><11477383264138944> [陈彦斌博客地址:https://www.cnblogs.com/chenyanbin/] 这是第一条日志----->常量字符串标签
2022-10-18 23:29:30.217  INFO 10245 --- [nio-8080-exec-5] com.ybchen.controller.DemoController     : <0><11477383264138944> [陈彦斌博客地址:https://www.cnblogs.com/chenyanbin/] 这是第二条日志----->常量字符串标签
2022-10-18 23:29:30.217  INFO 10245 --- [nio-8080-exec-5] com.ybchen.controller.DemoController     : <0><11477383264138944> [陈彦斌博客地址:https://www.cnblogs.com/chenyanbin/] 这是第三条日志----->常量字符串标签
2022-10-18 23:29:30.218  INFO 10245 --- [       Thread-9] com.ybchen.controller.DemoController     : <0><11477383264138944> [陈彦斌博客地址:https://www.cnblogs.com/chenyanbin/] 这是异步日志----->常量字符串标签

示例五#

@TLogAspect支持点操作符,适用于对象的取值,支持类型:

  • Bean对象
  • Map对象
  • Json格式的字符串
  • Fastjson的JSONObject对象

1504448-20221018233327524-1904739833.gif
    @TLogAspect({"request.id","request.age"})
    @GetMapping("demo5")
    public void demo4(PersonRequest request){

        log.info("多参数加多层级示例");
    }



================



@Data
public class PersonRequest {
    private Long id;
    private Long age;
    private String name;
}
2022-10-18 23:32:58.761  INFO 14747 --- [nio-8080-exec-2] com.ybchen.controller.DemoController     : <0><11477396931212992> [request.id:10089,request.age:27] 多参数加多层级示例
2022-10-18 23:33:03.289  INFO 14747 --- [nio-8080-exec-3] com.ybchen.controller.DemoController     : <0><11477397228025536> [request.id:10099,request.age:27] 多参数加多层级示例

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK