Kaip naudoti „Spring Boot 3.4“ pėdsakams iš tinkintų antraščių skleisti

Tracing

Pasirinktinių antraštės pėdsakų tvarkymas naudojant Spring Boot 3.4

Įsivaizduokite, kad turite „Spring Boot 3.4“ žiniatinklio paslaugą, kuri sklandžiai veikia su dviem klientais. Pirmasis klientas naudoja Spring Boot 3+, todėl pėdsakų sklidimas yra greitas. Be jokių papildomų pastangų gausite nuostabų nuo galo iki galo pėdsakų tęstinumą 🪄. Rąstai atrodo švarūs ir sujungti, tarsi burtų keliu.

Tačiau viskas pasisuka, kai pradeda veikti klientas du. Vietoj standartinių sekimo antraščių jie siunčia pasirinktines antraštes, pvz., „ot-custom-traceid“ ir „ot-custom-spanid“. Nors šiose tinkintose antraštėse yra tinkama sekimo informacija, „Spring Boot“ nepavyksta perduoti šių pėdsakų. Rezultatas? Prarasite galimybę sujungti kliento pėdsakus su serverio žurnalais.

Tai sukuria stebėjimo spragą. Pirmojo kliento atveju matote visą užklausos kelią įvairiose paslaugose. Antrojo kliento atveju matote tik serverio žurnalus, trūksta kritinio kliento pėdsakų. Tarsi pamatytum pusę galvosūkio – žinai, kad kažko trūksta, bet negali sudėlioti dalių. 😓

Šiame straipsnyje mes išnagrinėsime, kaip išspręsti šią problemą nepasitikėdami Spring Cloud Sleuth, išlikdami ištikimi Spring Boot 3.4 ekosistemai. Pabaigoje žinosite, kaip platinti ir tęsti pėdsakus iš tinkintų antraščių, užtikrinant sklandų stebėjimą visoje sistemoje.

komandą Naudojimo pavyzdys
MDC.put Ši komanda prideda raktų ir reikšmių poras į susietėjusį diagnostikos kontekstą (MDC), leidžiantį į žurnalus įtraukti pasirinktinius sekimo ID. Pavyzdžiui, MDC.put("traceId", "12345").
MDC.clear Apdorojus užklausą, išvalomi visi įrašai iš MDC, kad būtų išvengta pėdsakų užteršimo tarp užklausų. Pavyzdžiui, MDC.clear().
OncePerRequestFilter „Spring Boot“ filtras, užtikrinantis, kad filtro logika būtų vykdoma tik vieną kartą per HTTP užklausą, idealiai tinka antraštėms sekti. Pavyzdys: viešoji klasė CustomTraceFilter išplečia OncePerRequestFilter.
filterChain.doFilter Pereinama prie kito filtro grandinėje, užtikrinant, kad užklausa būtų tęsiama naudojant kitus filtrus. Pavyzdžiui, filtrasChain.doFilter(užklausa, atsakymas).
RestTemplate.getInterceptors() Nuskaito „RestTemplate“ egzemplioriaus perėmėjų sąrašą, leidžiantį pridėti pasirinktinius gaudytuvus. Pavyzdys: restTemplate.getInterceptors().add(new CustomInterceptor()).
ClientHttpRequestInterceptor Sąsaja, skirta perimti siunčiamas HTTP užklausas ir pridėti pasirinktines antraštes. Pavyzdžiui, ClientHttpRequestInterceptor įdiegimas sekimo ID įterpimui.
HttpServletRequest.getHeader Iš gaunamos užklausos ištraukia konkrečios HTTP antraštės reikšmę. Pavyzdys: request.getHeader("ot-custom-traceid").
FilterRegistrationBean Registruoja pasirinktinius filtrus „Spring Boot“ programoje. Pavyzdžiui: registracijaBean.setFilter(new CustomTraceFilter()).
MockMvc.perform Imituoja HTTP užklausas atliekant „Spring Boot“ programų vienetų testus. Pavyzdys: mockMvc.perform(get("/test-endpoint").header("ot-custom-traceid", "12345")).
ClientHttpRequestExecution.execute Vykdo perimtą HTTP užklausą su pateiktu užklausos turiniu ir antraštėmis. Pavyzdys: execution.execute(request, body).

Pasirinktinis antraštės pėdsakų platinimas „Spring Boot“.

Vienas iš pagrindinių komponentų sprendžiant šią problemą yra CustomTraceFilter. Šis filtras prailgina klasė, užtikrinant, kad sekimo antraštės logika būtų vykdoma tik vieną kartą kiekvienai HTTP užklausai. „Spring Boot“ filtrai yra nepaprastai naudingi keičiant užklausas ar atsakymus visame pasaulyje. Pavyzdžiui, jei klientas siunčia sekimo informaciją, pvz arba tinkintose antraštėse šis filtras sulaiko užklausą, ištraukia šias antraštes ir perkelia jas į Suplanuotą diagnostikos kontekstą (MDC). Pridėję sekimo ID prie MDC užtikriname, kad šie identifikatoriai būtų matomi žurnaluose, sugeneruotuose apdorojant užklausą.

MDC yra svarbi registravimo sistemų, tokių kaip SLF4J ir Logback, dalis. Tai leidžia mums saugoti esamos gijos kontekstinę informaciją, pvz., pasirinktinius sekimo ID. Naudojant tokias komandas kaip ir , užtikriname, kad registravimo sistema apimtų sekimo duomenis ir išvengtų užteršimo tarp vienalaikių užklausų. Pavyzdžiui, jei „Client Two“ siunčia „ot-custom-traceid“ kaip „8f7ebd8a73f9a8f50e6a00a87a20952a“, šis ID saugomas MDC ir įtraukiamas į visus tolesnius žurnalus, sukuriant nuoseklų sekimo kelią.

Kita vertus, siunčiamoms HTTP užklausoms RestTemplate perėmėjas atlieka esminį vaidmenį. Įgyvendinant , galime pridėti tas pačias sekimo antraštes („ot-custom-traceid“ ir „ot-custom-spanid“) prie siunčiamų užklausų. Taip užtikrinamas sekimo tęstinumas, kai programa iškviečia kitas mikro tarnybas. Pavyzdžiui, kai serveris apdoroja užklausą su sekimo ID „8f7ebd8a73f9a8f50e6a00a87a20952a“, jis prideda šį ID prie siunčiamų antraštių, kad paskesnės paslaugos galėtų sklandžiai atpažinti ir skleisti pėdsaką.

Galiausiai, vienetų testai, parašyti naudojant MockMvc, patvirtina visą sąranką imituodami HTTP užklausas ir tikrindami antraštės sklidimą. Realiose programose testavimas yra labai svarbus siekiant užtikrinti, kad sekimo antraštės būtų tinkamai tvarkomos. Pavyzdžiui, išsiųsdami GET užklausą su pasirinktinėmis antraštėmis ir patikrinę atsakymą ar žurnalus, galime patvirtinti, kad filtras ir perėmėjas veikia taip, kaip tikėtasi. Šis visapusiškas metodas išsprendžia iššūkį nepasikliaujant senomis priklausomybėmis, tokiomis kaip Spring Cloud Sleuth. Galiausiai filtrų, gaudyklių ir MDC derinys užtikrina sekimo tęstinumą, net kai klientai naudoja pasirinktines antraštes, todėl sistema yra tvirta ir visiškai stebima. 🌟

Pasirinktinių sekimo antraščių platinimas naudojant Spring Boot 3.4

„Java“ naudojimas su „Spring Boot 3.4“ ir „Mikrometru“ foniniam apdorojimui

// Solution 1: Extract and Propagate Custom Trace Headers Manually
// Import necessary Spring Boot and Micrometer libraries
import org.slf4j.MDC;
import org.springframework.http.HttpHeaders;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class CustomTraceFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws IOException {
        String traceId = request.getHeader("ot-custom-traceid");
        String spanId = request.getHeader("ot-custom-spanid");
        try {
            if (traceId != null) {
                MDC.put("traceId", traceId); // Add traceId to Mapped Diagnostic Context
            }
            if (spanId != null) {
                MDC.put("spanId", spanId);
            }
            filterChain.doFilter(request, response); // Continue request processing
        } finally {
            MDC.clear(); // Ensure MDC is cleared after processing
        }
    }
}

// Register the filter in your configuration class
@Configuration
public class FilterConfig {
    @Bean
    public FilterRegistrationBean<CustomTraceFilter> traceFilter() {
        FilterRegistrationBean<CustomTraceFilter> registrationBean = new FilterRegistrationBean<>();
        registrationBean.setFilter(new CustomTraceFilter());
        registrationBean.addUrlPatterns("/*");
        return registrationBean;
    }
}

Individualizuotos pėdsakų antraštės skleidimo vieneto testas

Bandymai su JUnit ir MockMvc, kad patvirtintumėte pėdsakų antraštės sklaidą

// Import necessary libraries
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@WebMvcTest
public class CustomTraceFilterTest {
    @Autowired
    private MockMvc mockMvc;

    @Test
    public void testCustomTraceHeaders() throws Exception {
        mockMvc.perform(get("/test-endpoint")
                .header("ot-custom-traceid", "12345")
                .header("ot-custom-spanid", "67890"))
                .andExpect(status().isOk());
    }
}

Pasirinktinių antraščių platinimas HTTP užklausose naudojant RestTemplate

RestTemplate perėmėjų naudojimas norint pridėti pasirinktines antraštes į siunčiamas užklausas

// Import necessary libraries
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.web.client.RestTemplate;
import java.io.IOException;

public class CustomHeaderInterceptor implements ClientHttpRequestInterceptor {
    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
        HttpHeaders headers = request.getHeaders();
        headers.add("ot-custom-traceid", "12345");
        headers.add("ot-custom-spanid", "67890");
        return execution.execute(request, body);
    }
}

// Register the interceptor with RestTemplate
@Configuration
public class RestTemplateConfig {
    @Bean
    public RestTemplate restTemplate() {
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.getInterceptors().add(new CustomHeaderInterceptor());
        return restTemplate;
    }
}

Pasirinktinių antraštės pėdsakų tvarkymas naudojant „OpenTelemetry“ „Spring Boot 3.4“.

Dirbant su Spring Boot 3.4, dar vienas veiksmingas būdas skleisti pėdsakus iš tinkintų antraščių yra integravimas . „OpenTelemetry“, atvirojo kodo stebėjimo sistema, padeda sklandžiai valdyti, rinkti ir eksportuoti pėdsakus. Jame pateikiami mechanizmai, skirti sekimo kontekstui išgauti ir įterpti, įskaitant pasirinktines antraštes ir , į savo programą. Naudodami OpenTelemetry TextMapPropagator galite užpildyti atotrūkį tarp nestandartinių klientų ir savo stebėjimo sistemos.

Norint naudoti „OpenTelemetry“ „Spring Boot 3.4“, gali būti įdiegtas priskirtas skleidėjas, kuris ištraukia sekimo informaciją iš tinkintų antraščių ir pridedamas prie dabartinio sekimo konteksto. Pavyzdžiui, kai jūsų serveris gauna gaunamą užklausą iš antrojo kliento, „OpenTelemetry“ gali išanalizuoti pasirinktines antraštes ir atkurti pradinį sekimo kontekstą. Taip užtikrinama, kad paskesnės paslaugos matytų tuos pačius pėdsakų ID, o tai leidžia matyti visą. Skirtingai nuo senesnių sprendimų, pvz., Spring Cloud Sleuth, „OpenTelemetry“ yra lengvas ir atitinka šiuolaikinius stebėjimo standartus.

Sujungę „OpenTelemetry“ skleidiklį su mikrometru, galite praturtinti savo metriką ir registraciją sekimo informacija. Įsivaizduokite, kad stebėjimo įrankyje sklandžiai matote užklausų, gaunamų iš „Client One“ ir „Client Two“, pėdsakus. „OpenTelemetry“ automatiškai palaiko integraciją su „Prometheus“, „Zipkin“ arba „Jaeger“, todėl galite centralizuoti pėdsakų vizualizaciją. Šis metodas užtikrina, kad net naudojant pasirinktines antraštes, jokie sekimo duomenys neprarandami, o derinimas tampa daug lengvesnis. 🚀

  1. Kaip rankiniu būdu išgauti pasirinktines sekimo antraštes „Spring Boot“?
  2. Galite naudoti request.getHeader("custom-header"), norėdami rankiniu būdu gauti konkrečią antraštę ir pridėti ją prie MDC naudodami MDC.put("traceId", value).
  3. Kuo naudinga naudoti „OpenTelemetry“ tinkintam pėdsakų platinimui?
  4. OpenTelemetry suteikia šiuolaikišką, pardavėjų atžvilgiu neutralų metodą, kaip platinti pėdsakus, įskaitant pasirinktines antraštes, mikropaslaugose.
  5. Ar galiu platinti pasirinktines antraštes naudodamas „RestTemplate“ sistemoje „Spring Boot“?
  6. Taip, įdiegę ClientHttpRequestInterceptor, prie siunčiamų užklausų galite pridėti tinkintas antraštes, pvz., traceid ir spanid.
  7. Kaip užregistruoti filtrą, kad antraštės būtų užfiksuotos visame pasaulyje?
  8. Galite sukurti filtrą, praplečiantį OncePerRequestFilter, ir užregistruoti jį naudodami FilterRegistrationBean, kad užfiksuotumėte visų galinių taškų antraštes.
  9. Kokius įrankius galiu naudoti „Spring Boot“ pėdsakams vizualizuoti?
  10. Tokie įrankiai kaip Zipkin, Jaeger ir Prometheus gali būti integruoti su „Spring Boot“ ir „OpenTelemetry“, kad būtų galima vizualizuoti pėdsakus nuo galo iki galo.

Šiuolaikinėse sistemose tinkintų pėdsakų antraščių tvarkymas yra labai svarbus patikimam stebėjimui. Naudodami filtrus ir gaudykles galite užfiksuoti kliento pateiktą sekimo informaciją ir tinkamai ją skleisti savo paslaugose. Taip išvengiama suskaidytų rąstų ir trūkstamų pėdsakų. 🔍

„Spring Boot 3.4“ kartu su „Micrometer“ arba „OpenTelemetry“ leidžia priimti tvirtus sprendimus, nepasikliaujant senesniais įrankiais, pvz., „Spring Cloud Sleuth“. Nesvarbu, ar susiduriate su standartinėmis „Client One“ antraštėmis, ar „Client Two“ tinkintomis antraštėmis, šių metodų įdiegimas efektyviai pašalina pėdsakų spragas. 🚀

  1. „Spring Boot“ oficiali dokumentacija: sekimo kontekstų sklaida. Pavasario įkrovos dokumentacija
  2. „OpenTelemetry“, skirta „Java“ kūrėjams: sekimo platinimo vadovas. OpenTelemetry Java
  3. Mikrometro stebėjimo dokumentacija: tinkintų pėdsakų antraščių integravimas. Mikrometrinis stebėjimas
  4. SLF4J registravimo API: susietos diagnostikos konteksto (MDC) naudojimo atvejai. SLF4J vadovas