欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

關(guān)于Java應(yīng)用日志與Jaeger的trace關(guān)聯(lián)的問題

 更新時間:2022年01月18日 10:08:04   作者:itips  
這篇文章主要介紹了Java應(yīng)用日志如何與Jaeger的trace關(guān)聯(lián),通過jaeger發(fā)現(xiàn)這十次請求中有一次耗時特別長,想定位一下具體原因,感興趣的朋友跟隨小編一起看看吧

歡迎訪問我的GitHub

https://github.com/zq2599/blog_demos

內(nèi)容:所有原創(chuàng)文章分類匯總及配套源碼,涉及Java、Docker、Kubernetes、DevOPS等;

本篇概覽

  • 經(jīng)過[《Jaeger開發(fā)入門(java版)》]的實戰(zhàn),相信您已經(jīng)能將自己的應(yīng)用接入Jaeger,并用來跟蹤定位問題了,本文將介紹Jaeger一個小巧而強大的輔助功能,用少量改動大幅度提升定位問題的便利性:將業(yè)務(wù)日志與Jaeger的trace關(guān)聯(lián)
  • 在正式開始前,咱們先來看一個具體的問題:

一次web請求可能有多條業(yè)務(wù)日志(log4j或者logback配置的那種),這和您寫代碼執(zhí)行l(wèi)og.info的次數(shù)有關(guān),假設(shè)有10條,那么十次請求就有一百條業(yè)務(wù)日志;

通過jaeger發(fā)現(xiàn)這十次請求中有一次耗時特別長,想定位一下具體原因,現(xiàn)在問題來了:一共有100條業(yè)務(wù)日志,到底哪些是和Jaeger中耗時長的那一次請求有關(guān)?

  • 您可能會說:有些業(yè)務(wù)特征如user-id,咱們可以寫入span的tag或者log中,這樣通過span查到user-id,再去日志中查找含有此user-id的日志即可,這樣確實可以,但未必每條日志都有user-id,所以并非最佳方式
  • 好在Jaeger官方給出了一種簡單有效的方案:基于MDC,Jaeger的SDK在日志中注入trace相關(guān)的變量

關(guān)于MDC

  • 關(guān)于sl4j的MDC不是本篇的重點,因此只把本篇用到的特性簡單說說即可,經(jīng)驗豐富的您如果對MDC已經(jīng)了解,請?zhí)^此節(jié)
  • 在sl4j的配置文件中可以配置日志的格式,例如logback的配置文件如下,可見模板中新增了一段內(nèi)容[user-id=%X{user-id}]:
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>INFO</level>
        </filter>
        <encoder>
            <!--%logger{10}表示類名過長時會自動縮寫-->
            <pattern>%d{HH:mm:ss} [%thread] %-5level %logger{10} [user-id=%X{user-id}] %msg%n</pattern>
            <charset>utf-8</charset>
        </encoder>
    </appender>

再來看一段日志的代碼,先調(diào)用MDC.put方法將一個鍵值對寫入當前線程的診斷上下文map(diagnostic context map),鍵名和上面的模板中配置的%X{user-id}一模一樣:

@GetMapping("/test")
    public void test() {
        MDC.put("user-id", "user-" + System.currentTimeMillis());
        log.info("this is test request");
    }

現(xiàn)在把代碼運行起來,打印日志看看,如下所示,之前模板中配置的%X{user-id}已被替換成了user-1632122267618,就是代碼中MDC.put設(shè)置的值:

15:17:47 [http-nio-18081-exec-6] INFO  c.b.j.c.c.HelloConsumerController [user-id=user-1632122267618] this is test request

以上就是MDC的基本功能:對日志模板中的變量進行填充,填充的內(nèi)容可以用MDC.put方法隨意設(shè)置;

此刻聰明的您應(yīng)該能猜到j(luò)aeger官方的方案是如何實現(xiàn)的了,沒錯,就是借助MDC將trace信息填充到日志模板中,這樣每行日志都有了trace信息,咱們在jaeger web頁面中感興趣的任何一次trace,都能找到對應(yīng)的日志了

關(guān)于Jaeger的官方方案

Jaeger的官方方案如下圖所示,SDK已經(jīng)把traceId、spanId、sampled寫入當前線程的診斷上下文map(diagnostic context map),只要日志模板中配置上述三個變量,就會在所有業(yè)務(wù)日志中輸出它們具體的值:

看起來似乎非常簡單,那就動手編碼試試吧

編碼實戰(zhàn)

  • jaeger與MDC的關(guān)聯(lián)只是個小功能,沒必要大張旗鼓的新建項目,基于[《Jaeger開發(fā)入門(java版)》]的代碼繼續(xù)開發(fā)即可,也就是說修改兩個子工程jaeger-service-consumer和jaeger-service-provider的源碼,讓它們的業(yè)務(wù)日志打印出Jaeger的trace信息
  • 首先從jaeger-service-provider工程開始,增加一個標準的logback日志配置文件logback.xml,如下所示,日志模板中已添加了traceId、spanId、sampled變量:
<?xml version="1.0" encoding="UTF-8"?>

<configuration scan="true" scanPeriod="60 seconds" debug="false">

    <contextName>logback</contextName>

    <!--輸出到控制臺-->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>INFO</level>
        </filter>
        <encoder>
            <!--%logger{10}表示類名過長時會自動縮寫-->
            <pattern>%d{HH:mm:ss} [%thread] %-5level %logger{10} [traceId=%X{traceId} spanId=%X{spanId} sampled=%X{sampled}] %msg%n</pattern>
            <charset>utf-8</charset>
        </encoder>
    </appender>

    <root level="info">
        <appender-ref ref="console" />
    </root>
</configuration>

再去檢查配置類,確認JaegerTracer實例化時用了MDCScopeManager參數(shù),如下所示,咱們在上一章已經(jīng)這么做了,可以維持不變:

package com.bolingcavalry.jaeger.provider.config;

import io.jaegertracing.internal.MDCScopeManager;
import io.opentracing.contrib.java.spring.jaeger.starter.TracerBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class JaegerConfig {
    @Bean
    public TracerBuilderCustomizer mdcBuilderCustomizer() {
        // 1.8新特性,函數(shù)式接口
        return builder -> builder.withScopeManager(new MDCScopeManager.Builder().build());
    }
}

接下來是在業(yè)務(wù)代碼中隨意加幾行打印日志的代碼,如下圖紅框所示:

接下來繼續(xù)修改jaeger-service-consumer子工程,具體步驟與剛才改造jaeger-service-provider時一模一樣,就不多占用篇幅贅述了,記得在業(yè)務(wù)代碼中隨意加幾行日志,如下圖紅框:

開發(fā)完成,開始驗證吧

驗證

  • 像[《Jaeger開發(fā)入門(java版)》]那樣操作,將jaeger-service-consumer和jaeger-service-provider編譯構(gòu)建制作成docker鏡像
  • 用docker-compose將所有服務(wù)啟動,然后通過瀏覽器訪問jaeger-service-consumer的服務(wù),多訪問幾次
  • 打開jaeger的web頁面,可以看到多次請求的trace,咱們隨機選擇一個,鼠標點擊下圖紅框中的圓點:

此時會跳轉(zhuǎn)到該trace的詳情頁,注意頁面的url,如下圖紅框,里面的2037fe105d73f4a5就是traceid:

用2037fe105d73f4a5搜索jaeger-service-provider的日志,由于應(yīng)用部署在docker中,咱們要用docker log和grep命令組合來過濾,如下所示,咱們代碼寫的日志都打印出來了,并且紅框中就是traceid等關(guān)鍵信息

再去查看jaeger-service-consumer的日志,如下圖紅框,本次請求相關(guān)的日志也可以通過traceid搜索到:

至此,本篇實戰(zhàn)就完成了,Jaeger的web頁面上的任何一個trace,現(xiàn)在都能輕易找到與之對應(yīng)的所有業(yè)務(wù)日志,這在定位問題時簡直是如虎添翼的效果,如果您的系統(tǒng)用了ELK或者EFK來匯總所有分布式服務(wù)的日志,那就更高效了

到此這篇關(guān)于Java應(yīng)用日志如何與Jaeger的trace關(guān)聯(lián)的文章就介紹到這了,更多相關(guān)Java應(yīng)用日志與Jaeger的trace關(guān)聯(lián)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot多級緩存實現(xiàn)方案總結(jié)

    SpringBoot多級緩存實現(xiàn)方案總結(jié)

    所謂多級緩存,是指在整個系統(tǒng)架構(gòu)的不同系統(tǒng)層面進行數(shù)據(jù)緩存,以提升訪問速度,多級緩存就是為了解決項目服務(wù)中單一緩存使用不足的缺點,本文我們將給大家總結(jié)了SpringBoot多級緩存實現(xiàn)方案,需要的朋友可以參考下
    2023-08-08
  • 淺談java中異步多線程超時導(dǎo)致的服務(wù)異常

    淺談java中異步多線程超時導(dǎo)致的服務(wù)異常

    下面小編就為大家?guī)硪黄獪\談java中異步多線程超時導(dǎo)致的服務(wù)異常。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-06-06
  • Spring Boot Admin Server管理客戶端過程詳解

    Spring Boot Admin Server管理客戶端過程詳解

    這篇文章主要介紹了Spring Boot Admin Server管理客戶端過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-03-03
  • Java 面試題和答案 - (下)

    Java 面試題和答案 - (下)

    本文主要介紹Java 面試題,這里整理了Java面試題關(guān)于JDBC,線程異常處理,Servlet,JSP的知識的整理,幫助大家理解知識點,便于面試,有興趣的小伙伴可以參考下
    2016-09-09
  • Java數(shù)據(jù)結(jié)構(gòu)和算法之鏈表詳解

    Java數(shù)據(jù)結(jié)構(gòu)和算法之鏈表詳解

    鏈表是一種物理存儲單元上非連續(xù)、非順序的存儲結(jié)構(gòu),java代碼實現(xiàn)單鏈表,插入,刪除和遍歷等功能,這篇文章主要給大家介紹了關(guān)于Java數(shù)據(jù)結(jié)構(gòu)和算法之鏈表的相關(guān)資料,需要的朋友可以參考下
    2024-01-01
  • Java Web學習之Cookie和Session的深入理解

    Java Web學習之Cookie和Session的深入理解

    這篇文章主要給大家介紹了關(guān)于Java Web學習之Cookie和Session的相關(guān)資料,需要的朋友可以參考下
    2018-04-04
  • 分享Java8中通過Stream對列表進行去重的實現(xiàn)

    分享Java8中通過Stream對列表進行去重的實現(xiàn)

    本文主要介紹了分享Java8中通過Stream對列表進行去重的實現(xiàn),包括兩種方法,具有一定的參考價值,感興趣的可以了解一下
    2023-11-11
  • Java中MapStruct使用方法解析

    Java中MapStruct使用方法解析

    這篇文章主要介紹了Java中MapStruct使用方法解析,接受請求參數(shù)都會使用一個vo類,這個vo類里封裝了所有需要接受的參數(shù),然后對參數(shù)進行業(yè)務(wù)邏輯處理,處理完后會持久化處理,?使用MapStruct可以快速幫你解決轉(zhuǎn)換工作,需要的朋友可以參考下
    2023-10-10
  • Spring中RedisTemplate的基本使用淺析

    Spring中RedisTemplate的基本使用淺析

    Spring Boot Data(數(shù)據(jù)) Redis中提供了RedisTemplate和StringRedisTemplate,其中StringRedisTemplate是RedisTemplate的子類,兩個方法基本一致。本文介紹了Spring操作Redis的方法,需要的可以參考一下
    2023-02-02
  • spring batch 讀取多個文件數(shù)據(jù)導(dǎo)入數(shù)據(jù)庫示例

    spring batch 讀取多個文件數(shù)據(jù)導(dǎo)入數(shù)據(jù)庫示例

    本篇文章主要介紹了spring batch 讀取多個文件數(shù)據(jù)導(dǎo)入數(shù)據(jù)庫示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-03-03

最新評論