Cómo utilizar Spring Boot 3.4 para propagar seguimientos desde encabezados personalizados

Temp mail SuperHeros
Cómo utilizar Spring Boot 3.4 para propagar seguimientos desde encabezados personalizados
Cómo utilizar Spring Boot 3.4 para propagar seguimientos desde encabezados personalizados

Manejo de seguimientos de encabezados personalizados en Spring Boot 3.4

Imagine que tiene un servicio web Spring Boot 3.4 que funciona perfectamente con dos clientes. El primer cliente utiliza Spring Boot 3+, lo que facilita la propagación del seguimiento. Sin ningún esfuerzo adicional, obtendrá una hermosa continuidad de seguimiento de extremo a extremo 🪄. Los registros aparecen limpios y conectados, como por arte de magia.

Sin embargo, las cosas cambian cuando entra en juego el cliente dos. En lugar de encabezados de seguimiento estándar, envían encabezados personalizados como "ot-custom-traceid" y "ot-custom-spanid". Si bien estos encabezados personalizados contienen información de seguimiento válida, Spring Boot no puede propagar estos seguimientos. ¿El resultado? Pierde la capacidad de conectar seguimientos de clientes con registros del lado del servidor.

Esto crea una brecha de observabilidad. Para el cliente uno, verá la ruta completa de una solicitud entre servicios. Para el cliente dos, solo ve los registros del lado del servidor, falta el seguimiento crítico del cliente. Es como ver medio rompecabezas: sabes que falta algo pero no puedes unir las piezas. 😓

En este artículo, exploraremos cómo resolver este problema sin depender de Spring Cloud Sleuth, manteniéndonos fieles al ecosistema Spring Boot 3.4. Al final, sabrá cómo propagar y continuar los seguimientos desde encabezados personalizados, lo que garantizará una observabilidad perfecta en todo su sistema.

Dominio Ejemplo de uso
MDC.put Este comando agrega pares clave-valor al Contexto de diagnóstico asignado (MDC), lo que permite incluir ID de seguimiento personalizados en los registros. Por ejemplo, MDC.put("traceId", "12345").
MDC.clear Borra todas las entradas del MDC después de procesar una solicitud para evitar la contaminación de rastros entre solicitudes. Por ejemplo, MDC.clear().
OncePerRequestFilter Un filtro Spring Boot que garantiza que la lógica del filtro se ejecute solo una vez por solicitud HTTP, ideal para rastrear encabezados. Ejemplo: la clase pública CustomTraceFilter extiende OncePerRequestFilter.
filterChain.doFilter Continúa con el siguiente filtro de la cadena, asegurando que la solicitud continúe a través de otros filtros. Por ejemplo, filterChain.doFilter (solicitud, respuesta).
RestTemplate.getInterceptors() Recupera la lista de interceptores para una instancia de RestTemplate, lo que permite agregar interceptores personalizados. Ejemplo: restTemplate.getInterceptors().add(nuevo CustomInterceptor()).
ClientHttpRequestInterceptor Una interfaz para interceptar solicitudes HTTP salientes y agregar encabezados personalizados. Por ejemplo, implementar ClientHttpRequestInterceptor para insertar ID de seguimiento.
HttpServletRequest.getHeader Extrae el valor de un encabezado HTTP específico de la solicitud entrante. Ejemplo: request.getHeader("ot-custom-traceid").
FilterRegistrationBean Registra filtros personalizados en la aplicación Spring Boot. Por ejemplo: registroBean.setFilter (nuevo CustomTraceFilter()).
MockMvc.perform Simula solicitudes HTTP en pruebas unitarias para aplicaciones Spring Boot. Ejemplo: mockMvc.perform(get("/test-endpoint").header("ot-custom-traceid", "12345")).
ClientHttpRequestExecution.execute Ejecuta la solicitud HTTP interceptada con el cuerpo y los encabezados de la solicitud proporcionados. Ejemplo: ejecución.execute (solicitud, cuerpo).

Propagación de seguimiento de encabezado personalizado en Spring Boot

Uno de los componentes clave para resolver este problema es CustomTraceFilter. Este filtro amplía la Una vez por filtro de solicitud clase, asegurando que la lógica del encabezado de seguimiento se ejecute solo una vez para cada solicitud HTTP. Los filtros en Spring Boot son increíblemente útiles al modificar solicitudes o respuestas globalmente. Por ejemplo, si el cliente envía información de seguimiento como ot-traceid personalizado o ot-personalizado-español en encabezados personalizados, este filtro intercepta la solicitud, extrae estos encabezados y los propaga al Contexto de diagnóstico asignado (MDC). Al agregar los ID de seguimiento al MDC, nos aseguramos de que estos identificadores sean visibles en los registros generados durante el procesamiento de la solicitud.

El MDC es una parte fundamental de los marcos de registro como SLF4J y Logback. Nos permite almacenar información contextual para el hilo actual, como ID de seguimiento personalizados. Usando comandos como MDC.poner y MDC.claro, nos aseguramos de que el sistema de registro incluya los detalles del seguimiento y evite la contaminación entre solicitudes simultáneas. Por ejemplo, si el Cliente Dos envía "ot-custom-traceid" como "8f7ebd8a73f9a8f50e6a00a87a20952a", este ID se almacena en MDC y se incluye en todos los registros posteriores, creando una ruta de seguimiento coherente.

Por otro lado, para las solicitudes HTTP salientes, el interceptor RestTemplate juega un papel esencial. Al implementar ClienteHttpRequestInterceptor, podemos adjuntar los mismos encabezados de seguimiento (`ot-custom-traceid` y `ot-custom-spanid`) a las solicitudes salientes. Esto garantiza que se mantenga la continuidad del seguimiento cuando la aplicación llama a otros microservicios. Por ejemplo, cuando el servidor procesa una solicitud con el ID de seguimiento `8f7ebd8a73f9a8f50e6a00a87a20952a`, adjunta este ID a los encabezados salientes, de modo que los servicios posteriores puedan reconocer y propagar el seguimiento sin problemas.

Finalmente, las pruebas unitarias escritas con MockMvc validan toda la configuración simulando solicitudes HTTP y verificando la propagación del encabezado. En aplicaciones del mundo real, las pruebas son cruciales para garantizar que los encabezados de seguimiento se manejen correctamente. Por ejemplo, al enviar una solicitud GET con encabezados personalizados e inspeccionar la respuesta o los registros, podemos confirmar que el filtro y el interceptor funcionan como se esperaba. Este enfoque integral resuelve el desafío sin depender de dependencias heredadas como Spring Cloud Sleuth. En última instancia, la combinación de filtros, interceptores y MDC garantiza la continuidad del rastreo incluso cuando los clientes utilizan encabezados personalizados, lo que hace que el sistema sea robusto y totalmente observable. 🌟

Propagación de encabezados de seguimiento personalizados en Spring Boot 3.4

Uso de Java con Spring Boot 3.4 y Micrometer para procesamiento backend

// 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;
    }
}

Prueba unitaria para propagación de encabezados de seguimiento personalizados

Pruebas con JUnit y MockMvc para validar la propagación del encabezado de seguimiento

// 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());
    }
}

Propagar encabezados personalizados en solicitudes HTTP usando RestTemplate

Uso de interceptores RestTemplate para agregar encabezados personalizados en solicitudes salientes

// 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;
    }
}

Manejo de seguimientos de encabezados personalizados con OpenTelemetry en Spring Boot 3.4

Cuando se trabaja con Spring Boot 3.4, otro enfoque poderoso para propagar rastros desde encabezados personalizados es integrar OpenTelemetría. OpenTelemetry, un marco de observabilidad de código abierto, ayuda a instrumentar, recopilar y exportar seguimientos sin problemas. Proporciona mecanismos para extraer e inyectar contexto de seguimiento, incluidos encabezados personalizados como ot-traceid personalizado y ot-personalizado-español, en su aplicación. Al aprovechar TextMapPropagator de OpenTelemetry, puede cerrar la brecha entre los clientes no estándar y su sistema de observabilidad.

Para usar OpenTelemetry en Spring Boot 3.4, se puede implementar un propagador personalizado para extraer información de seguimiento de los encabezados personalizados y adjuntarla al contexto de seguimiento actual. Por ejemplo, cuando su servidor recibe una solicitud entrante del Cliente Dos, OpenTelemetry puede analizar encabezados personalizados y reconstruir el contexto de seguimiento original. Esto garantiza que los servicios posteriores vean los mismos ID de seguimiento, lo que permite una visibilidad de un extremo a otro. A diferencia de soluciones más antiguas como Spring Cloud Sleuth, OpenTelemetry es liviano y se alinea con los estándares de observabilidad modernos.

Al combinar el propagador de OpenTelemetry con Micrometer, puede enriquecer sus métricas y registros con información de seguimiento. Imagine ver seguimientos de solicitudes provenientes tanto del Cliente Uno como del Cliente Dos sin problemas en su herramienta de observabilidad. OpenTelemetry admite automáticamente integraciones con Prometheus, Zipkin o Jaeger, lo que le permite centralizar la visualización de seguimiento. Este enfoque garantiza que, incluso cuando se trata de encabezados personalizados, no se pierdan datos de seguimiento y la depuración sea mucho más sencilla. 🚀

Preguntas frecuentes sobre la propagación de seguimientos personalizados en Spring Boot

  1. ¿Cómo extraigo manualmente encabezados de seguimiento personalizados en Spring Boot?
  2. Puede usar request.getHeader("custom-header") para recuperar manualmente un encabezado específico y agregarlo al MDC usando MDC.put("traceId", value).
  3. ¿Cuál es el beneficio de utilizar OpenTelemetry para la propagación de seguimiento personalizado?
  4. OpenTelemetry proporciona un enfoque moderno y neutral para los proveedores para propagar seguimientos, incluidos encabezados personalizados, entre microservicios.
  5. ¿Puedo propagar encabezados personalizados con RestTemplate en Spring Boot?
  6. Sí, al implementar un ClientHttpRequestInterceptor, puedes adjuntar encabezados personalizados como traceid y spanid a las solicitudes salientes.
  7. ¿Cómo registro un filtro para capturar encabezados a nivel global?
  8. Puede crear un filtro que extienda OncePerRequestFilter y registrarlo usando FilterRegistrationBean para capturar encabezados para todos los puntos finales.
  9. ¿Qué herramientas puedo utilizar para visualizar rastros de Spring Boot?
  10. Herramientas como Zipkin, Jaeger y Prometheus se pueden integrar con Spring Boot y OpenTelemetry para visualizar seguimientos de un extremo a otro.

Garantizar la continuidad del seguimiento sin interrupciones

En los sistemas modernos, el manejo de encabezados de seguimiento personalizados es fundamental para una observabilidad confiable. Al utilizar filtros e interceptores, puede capturar información de seguimiento proporcionada por el cliente y propagarla correctamente en sus servicios. Esto evita registros fragmentados y rastros faltantes. 🔍

Spring Boot 3.4, combinado con Micrometer u OpenTelemetry, permite soluciones sólidas sin depender de herramientas más antiguas como Spring Cloud Sleuth. Ya sea que esté tratando con encabezados estándar del Cliente Uno o encabezados personalizados del Cliente Dos, la implementación de estas técnicas cierra las brechas de seguimiento de manera eficiente. 🚀

Fuentes y referencias
  1. Documentación oficial de Spring Boot: propagación de contextos de seguimiento. Documentación de arranque de primavera
  2. OpenTelemetry para desarrolladores de Java: guía para la propagación de seguimiento. OpenTelemetría Java
  3. Documentación de observabilidad micrométrica: integración de encabezados de seguimiento personalizados. Observabilidad micrométrica
  4. API de registro SLF4J: casos de uso de contexto de diagnóstico asignado (MDC). Manual SLF4J