TLog能解决什么痛点

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

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

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

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

项目整合

项目结构

添加依赖

        <!-- 引入全量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的生成规则

TLog业务标签

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

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

演示

示例1

    @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"] 这是异步日志---->简单例子

示例二

    @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"] 这是异步日志----->多个数值

示例三

    @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的示例

示例四

    @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({"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] 多参数加多层级示例

SpringBoot 2.5.5整合轻量级的分布式日志标记追踪神器TLog的更多相关文章

  1. SpringBoot 整合 Elastic Stack 最新版本(7.14.1)分布式日志解决方案,开源微服务全栈项目【有来商城】的日志落地实践

    一. 前言 日志对于一个程序的重要程度不用过多的言语修饰,本篇将以实战的方式讲述开源微服务全栈项目 有来商城 是如何整合当下主流日志解决方案 ELK +Filebeat . 话不多说,先看实现的效果图 ...

  2. SpringBoot进阶教程(二十七)整合Redis之分布式锁

    在之前的一篇文章(<Java分布式锁,搞懂分布式锁实现看这篇文章就对了>),已经介绍过几种java分布式锁,今天来个Redis分布式锁的demo.redis 现在已经成为系统缓存的必备组件 ...

  3. 【Spring Cloud & Alibaba全栈开源项目实战】:SpringBoot整合ELK实现分布式登录日志收集和统计

    一. 前言 其实早前就想计划出这篇文章,但是最近主要精力在完善微服务.系统权限设计.微信小程序和管理前端的功能,不过好在有群里小伙伴的一起帮忙反馈问题,基础版的功能已经差不多,也在此谢过,希望今后大家 ...

  4. SpringBoot接入轻量级分布式日志框架(GrayLog)

    我是3y,一年CRUD经验用十年的markdown程序员‍常年被誉为优质八股文选手 前两天我不是发了一篇数据链路追踪的文章嘛,在末尾也遗留了TODO:运行应用的服务器一般是集群,日志数据会记录到不同的 ...

  5. SpringBoot学习- 4、整合JWT

    SpringBoot学习足迹 1.Json web token(JWT)是为了网络应用环境间传递声明而执行的一种基于JSON的开发标准(RFC 7519),该token被设计为紧凑且安全的,特别适用于 ...

  6. seata整合nacos完成分布式的部署

    seata整合nacos完成分布式的部署 一.背景 二.部署机器 三.部署步骤 1.在seata上创建命名空间 2.下载对应版本的seata 3.单机启动 1.修改seata配置文件 1.修改注册中心 ...

  7. springboot+jpa+mysql+swagger整合

    Springboot+jpa+MySQL+swagger整合 创建一个springboot web项目 <dependencies> <dependency>      < ...

  8. Springboot 2.0.4 整合Mybatis出现异常Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required

    在使用Springboot 2.0.4 整合Mybatis的时候出现异常Property 'sqlSessionFactory' or 'sqlSessionTemplate' are require ...

  9. SpringBoot+SpringMVC+MyBatis快速整合搭建

    作为开发人员,大家都知道,SpringBoot是基于Spring4.0设计的,不仅继承了Spring框架原有的优秀特性,而且还通过简化配置来进一步简化了Spring应用的整个搭建和开发过程.另外Spr ...

随机推荐

  1. 四位一体水溶交融,Docker一拖三Tornado6.2 + Nginx + Supervisord非阻塞负载均衡容器式部署实践

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_203 容器,又见容器.Docker容器的最主要优点就在于它们是可移植的.一套服务,其所有的依赖关系可以捆绑到一个独立于Linux内 ...

  2. 主流前沿的开源监控和报警系统Prometheus+Grafana入门之旅

    Prometheus概述 定义 Prometheus 官网地址 https://prometheus.io/ Prometheus 官网文档地址 https://prometheus.io/docs/ ...

  3. Windows 电脑杀毒简单有效的方式

    Windows 电脑杀毒通常会选择杀毒软件,这样太笨重,且容易占内存和存在流氓软件侵入. 推荐使用 Windows 自带的恶意软件删除工具 按住 Win + R 键,弹出运行窗口,输入 mrt. 系统 ...

  4. Excel 统计函数(五):MINIFS 和 MAXIFS

    MINIFS [语法]MINIFS(min_range, criteria_range1, criteria1, [criteria_range2, criteria2], ...) [参数] min ...

  5. 乘风破浪,遇见最佳跨平台跨终端框架.Net Core/.Net生态 - 官方扩展集锦(Microsoft.Extensions on Nuget)

    什么是Microsoft.Extensions .NET Platform Extensions是一套.Net官方的API集合,提供了一些常用的编程模式和实用工具,例如依赖项注入.日志记录.缓存.Ho ...

  6. z—libirary最新地址获取,zlibirary地址获取方式,zliabary最新地址,zliabary官网登录方式,zliabary最新登陆

    Z-Library(缩写为z-lib,以前称为BookFinder)是Library Genesis的镜像,一个影子图书馆项目,用于对学术期刊文章.学术文本和大众感兴趣的书籍(其中一些是盗版的)进行文 ...

  7. Html飞机大战(八):子弹的移动和管理

    好家伙,这应该是这个小游戏最难的几个点之一了 现在我们要做出子弹射击的效果我们应该如何处理? 1.首先我们要确定几个变量和方法的关系 变量: 子弹  bullet  弹夹(用来装子弹的东西)bulle ...

  8. Linux软件包常见的几种下载、安装方法

    在线源下载和安装 如果服务器是处于在线状态,在使用默认下载源是外国的情况下,安装更新软件包往往会比较痛苦的存在,下载了许久来一个超时就gg了.国内有许多镜像源,完美的解决了这个问题. 对于rpm系列的 ...

  9. 流媒体协议扫盲(rtp/rtcp/rtsp/rtmp/mms/hls)

    RTP           参考文档 RFC3550/RFC3551 Real-time Transport Protocol)是用于Internet上针对多媒体数据流的一种传输层协议.RTP协议详细 ...

  10. KingbaseES R6 集群物理copy方式手工添加新备库节点

    案例说明: 对于主库数据量比较大的环境,在添加新节点是可以采用在线clone方式创建新的备库节点,也可以在离线的状态下,直接拷贝其中一个备库的所有集群相关目录来创建新的备库节点.本案例介绍了通过离线物 ...