SpringBoot?2.5.5整合輕量級的分布式日志標(biāo)記追蹤神器TLog的詳細(xì)過程
隨著微服務(wù)盛行,很多公司都把系統(tǒng)按照業(yè)務(wù)邊界拆成了很多微服務(wù),在排錯查日志的時候。因?yàn)闃I(yè)務(wù)鏈路貫穿著很多微服務(wù)節(jié)點(diǎn),導(dǎo)致定位某個請求的日志以及上下游業(yè)務(wù)的日志會變得有些困難。
這時候很多童鞋會開始考慮上SkyWalking,Pinpoint等分布式追蹤系統(tǒng)來解決,基于OpenTracing規(guī)范,而且通常都是無侵入性的,并且有相對友好的管理界面來進(jìn)行鏈路Span的查詢。
但是搭建分布式追蹤系統(tǒng),熟悉以及推廣到全公司的系統(tǒng)需要一定的時間周期,而且當(dāng)中涉及到鏈路span節(jié)點(diǎn)的存儲成本問題,全量采集還是部分采集?如果全量采集,就以SkyWalking的存儲來舉例,ES集群搭建至少需要5個節(jié)點(diǎn)。這就需要增加服務(wù)器成本。況且如果微服務(wù)節(jié)點(diǎn)多的話,一天下來產(chǎn)生幾十G上百G的數(shù)據(jù)其實(shí)非常正常。如果想保存時間長點(diǎn)的話,也需要增加服務(wù)器磁盤的成本。
當(dāng)然分布式追蹤系統(tǒng)是一個最終的解決方案,如果您的公司已經(jīng)上了分布式追蹤系統(tǒng),那TLog并不適用。
項目整合
項目結(jié)構(gòu)
添加依賴
<!-- 引入全量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,如果設(shè)置為WARN,則低于WARN的信息都不會輸出 --> <!-- scan:當(dāng)此屬性設(shè)置為true時,配置文件如果發(fā)生改變,將會被重新加載,默認(rèn)值為true --> <!-- scanPeriod:設(shè)置監(jiān)測配置文件是否有修改的時間間隔,如果沒有給出時間單位,默認(rèn)單位是毫秒。當(dāng)scan為true時,此屬性生效。默認(rèn)的時間間隔為1分鐘。 --> <!-- debug:當(dāng)此屬性設(shè)置為true時,將打印出logback內(nèi)部日志信息,實(shí)時查看logback運(yùn)行狀態(tài)。默認(rèn)值為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是為開發(fā)使用,只配置最底級別,控制臺輸出的日志級別是大于或等于此級別的日志信息--> <!-- <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> <!-- 設(shè)置字符集 --> <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> <!--日志文件保留天數(shù)--> <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> <!-- 此處設(shè)置字符集 --> </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> <!--日志文件保留天數(shù)--> <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("這是第一條日志----->多個數(shù)值"); log.info("這是第二條日志----->多個數(shù)值"); log.info("這是第三條日志----->多個數(shù)值"); new Thread(() -> log.info("這是異步日志----->多個數(shù)值")).start(); } @TLogAspect(value = {"id", "name"}, pattern = "<-{}->", joint = "_") @GetMapping("demo3") public void demo3(String id, String name) { log.info("多個數(shù)值-------->加了patter和joint的示例"); } @TLogAspect(str = "陳彥斌博客地址:https://www.cnblogs.com/chenyanbin/") @GetMapping("demo4") public void demo4(String name){ log.info("這是第一條日志----->常量字符串標(biāo)簽"); log.info("這是第二條日志----->常量字符串標(biāo)簽"); log.info("這是第三條日志----->常量字符串標(biāo)簽"); new Thread(() -> log.info("這是異步日志----->常量字符串標(biāo)簽")).start(); } @TLogAspect({"request.id","request.age"}) @GetMapping("demo5") public void demo4(PersonRequest request){ log.info("多參數(shù)加多層級示例"); } }
SpanId的生成規(guī)則
TLog業(yè)務(wù)標(biāo)簽
很多公司的系統(tǒng)在打日志的時候,每打一個日志里都會帶入一些業(yè)務(wù)信息,比如記錄ID,會員CODE,方便業(yè)務(wù)日志的定位?,F(xiàn)在有了TLog,不僅能做分布式鏈路標(biāo)簽追加,還能自動幫你做業(yè)務(wù)標(biāo)簽的添加。這樣在定位日志的時候可以更加方便的搜索。
Tlog支持方法級別的自定義業(yè)務(wù)標(biāo)簽。你可以在方法上定義簡單的標(biāo)注,來實(shí)現(xiàn)在某一個方法的日志里,統(tǒng)一加入業(yè)務(wù)的指標(biāo)標(biāo)簽,用于更加細(xì)致的定位。
演示
示例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("這是第一條日志----->多個數(shù)值"); log.info("這是第二條日志----->多個數(shù)值"); log.info("這是第三條日志----->多個數(shù)值"); new Thread(() -> log.info("這是異步日志----->多個數(shù)值")).start(); }
2022-10-18 23:22:33.941 INFO 88321 --- [nio-8080-exec-8] com.ybchen.controller.DemoController : <0><11477355982223040> [id:"10085",name:"alex"] 這是第一條日志----->多個數(shù)值 2022-10-18 23:22:33.946 INFO 88321 --- [nio-8080-exec-8] com.ybchen.controller.DemoController : <0><11477355982223040> [id:"10085",name:"alex"] 這是第二條日志----->多個數(shù)值 2022-10-18 23:22:33.947 INFO 88321 --- [nio-8080-exec-8] com.ybchen.controller.DemoController : <0><11477355982223040> [id:"10085",name:"alex"] 這是第三條日志----->多個數(shù)值 2022-10-18 23:22:33.950 INFO 88321 --- [ Thread-15] com.ybchen.controller.DemoController : <0><11477355982223040> [id:"10085",name:"alex"] 這是異步日志----->多個數(shù)值 2022-10-18 23:22:37.744 INFO 88321 --- [nio-8080-exec-9] com.ybchen.controller.DemoController : <0><11477356232308416> [id:"10086",name:"alex"] 這是第一條日志----->多個數(shù)值 2022-10-18 23:22:37.744 INFO 88321 --- [nio-8080-exec-9] com.ybchen.controller.DemoController : <0><11477356232308416> [id:"10086",name:"alex"] 這是第二條日志----->多個數(shù)值 2022-10-18 23:22:37.744 INFO 88321 --- [nio-8080-exec-9] com.ybchen.controller.DemoController : <0><11477356232308416> [id:"10086",name:"alex"] 這是第三條日志----->多個數(shù)值 2022-10-18 23:22:37.745 INFO 88321 --- [ Thread-16] com.ybchen.controller.DemoController : <0><11477356232308416> [id:"10086",name:"alex"] 這是異步日志----->多個數(shù)值
示例三
@TLogAspect(value = {"id", "name"}, pattern = "<-{}->", joint = "_") @GetMapping("demo3") public void demo3(String id, String name) { log.info("多個數(shù)值-------->加了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"-> 多個數(shù)值-------->加了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"-> 多個數(shù)值-------->加了patter和joint的示例
示例四
@TLogAspect(str = "陳彥斌博客地址:https://www.cnblogs.com/chenyanbin/") @GetMapping("demo4") public void demo4(String name){ log.info("這是第一條日志----->常量字符串標(biāo)簽"); log.info("這是第二條日志----->常量字符串標(biāo)簽"); log.info("這是第三條日志----->常量字符串標(biāo)簽"); new Thread(() -> log.info("這是異步日志----->常量字符串標(biāo)簽")).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/] 這是第一條日志----->常量字符串標(biāo)簽 2022-10-18 23:29:25.802 INFO 10245 --- [nio-8080-exec-4] com.ybchen.controller.DemoController : <0><11477382974797504> [陳彥斌博客地址:https://www.cnblogs.com/chenyanbin/] 這是第二條日志----->常量字符串標(biāo)簽 2022-10-18 23:29:25.802 INFO 10245 --- [nio-8080-exec-4] com.ybchen.controller.DemoController : <0><11477382974797504> [陳彥斌博客地址:https://www.cnblogs.com/chenyanbin/] 這是第三條日志----->常量字符串標(biāo)簽 2022-10-18 23:29:25.803 INFO 10245 --- [ Thread-8] com.ybchen.controller.DemoController : <0><11477382974797504> [陳彥斌博客地址:https://www.cnblogs.com/chenyanbin/] 這是異步日志----->常量字符串標(biāo)簽 2022-10-18 23:29:30.216 INFO 10245 --- [nio-8080-exec-5] com.ybchen.controller.DemoController : <0><11477383264138944> [陳彥斌博客地址:https://www.cnblogs.com/chenyanbin/] 這是第一條日志----->常量字符串標(biāo)簽 2022-10-18 23:29:30.217 INFO 10245 --- [nio-8080-exec-5] com.ybchen.controller.DemoController : <0><11477383264138944> [陳彥斌博客地址:https://www.cnblogs.com/chenyanbin/] 這是第二條日志----->常量字符串標(biāo)簽 2022-10-18 23:29:30.217 INFO 10245 --- [nio-8080-exec-5] com.ybchen.controller.DemoController : <0><11477383264138944> [陳彥斌博客地址:https://www.cnblogs.com/chenyanbin/] 這是第三條日志----->常量字符串標(biāo)簽 2022-10-18 23:29:30.218 INFO 10245 --- [ Thread-9] com.ybchen.controller.DemoController : <0><11477383264138944> [陳彥斌博客地址:https://www.cnblogs.com/chenyanbin/] 這是異步日志----->常量字符串標(biāo)簽
示例五
@TLogAspect
支持點(diǎn)操作符,適用于對象的取值,支持類型:
- Bean對象
- Map對象
- Json格式的字符串
- Fastjson的JSONObject對象
@TLogAspect({"request.id","request.age"}) @GetMapping("demo5") public void demo4(PersonRequest request){ log.info("多參數(shù)加多層級示例"); } ================ @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] 多參數(shù)加多層級示例 2022-10-18 23:33:03.289 INFO 14747 --- [nio-8080-exec-3] com.ybchen.controller.DemoController : <0><11477
到此這篇關(guān)于SpringBoot 2.5.5整合輕量級的分布式日志標(biāo)記追蹤神器TLog的文章就介紹到這了,更多相關(guān)SpringBoot 2.5.5整合輕量級內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot中dubbo+zookeeper實(shí)現(xiàn)分布式開發(fā)的應(yīng)用詳解
- 2020最新IDEA SpringBoot整合Dubbo的實(shí)現(xiàn)(zookeeper版)
- SpringBoot系列教程之dubbo和Zookeeper集成方法
- 淺談Java(SpringBoot)基于zookeeper的分布式鎖實(shí)現(xiàn)
- SpringBoot整合XxlJob分布式任務(wù)調(diào)度平臺
- springboot如何使用redis的incr創(chuàng)建分布式自增id
- SpringBoot集成redis與session實(shí)現(xiàn)分布式單點(diǎn)登錄
- springboot 使用zookeeper實(shí)現(xiàn)分布式隊列的基本步驟
相關(guān)文章
Java使用modbus4j實(shí)現(xiàn)modbus?tcp通訊
Modbus是由Modicon(現(xiàn)為施耐德電氣公司的一個品牌)在1979年發(fā)明的,是全球第一個真正用于工業(yè)現(xiàn)場的總線協(xié)議,本文主要介紹了java如何使用modbus4j實(shí)現(xiàn)modbus?tcp通訊,感興趣的可以了解下2023-12-12SSH框架網(wǎng)上商城項目第2戰(zhàn)之基本增刪查改、Service和Action的抽取
SSH框架網(wǎng)上商城項目第2戰(zhàn)之基本增刪查改、Service和Action的抽取,感興趣的小伙伴們可以參考一下2016-05-05Java?如何接收kernel傳過來的數(shù)組(推薦)
這篇文章主要介紹了Java?如何接收kernel傳過來的數(shù)組,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧2024-08-08Java項目導(dǎo)出數(shù)據(jù)為 PDF 文件的操作代碼
一個小需求,需要將頁面上的數(shù)據(jù)導(dǎo)出為PDF,正常情況下這個需求需要讓前端來做,但是現(xiàn)在上面讓咱們后端來做,也沒問題,這篇文章主要介紹了Java項目導(dǎo)出數(shù)據(jù)為 PDF 文件的操作代碼,需要的朋友可以參考下2022-12-12基于Java8 Stream API實(shí)現(xiàn)數(shù)據(jù)抽取收集
這篇文章主要介紹了基于Java8 Stream API實(shí)現(xiàn)數(shù)據(jù)抽取收集,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-03-03Elasticsearch查詢之Term?Query示例解析
這篇文章主要為大家介紹了Elasticsearch查詢之Term?Query示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04IDEA對使用了第三方依賴jar包的非Maven項目打jar包的問題(圖文詳解)
這篇文章主要介紹了IDEA對使用了第三方依賴jar包的非Maven項目打jar包的問題,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-07-07