El recorrido hacia la configuración declarativa: por qué tomó 5 años ignorar los endpoints de health check en las trazas

Una de las solicitudes de funcionalidades más persistentes y populares para OpenTelemetry Java durante los últimos años ha sido la posibilidad de descartar spans para los endpoints de health check, o de cualquier otro endpoint de bajo valor que incremente costos. Este issue se planteó por primera vez en agosto de 2020, pero una solución integral tardó sorprendentemente mucho tiempo en llegar. ¿Por qué nos tomó cinco años abordar un problema aparentemente sencillo? La respuesta está en los principios fundamentales del sistema de configuración de OpenTelemetry y en el recorrido hacia un enfoque más robusto y flexible: la configuración declarativa.

Desde el inicio, OpenTelemetry se basó en variables de entorno para la configuración, una elección impulsada por su disponibilidad universal entre lenguajes y su facilidad de análisis. Sin embargo, a medida que crecían los casos de uso con configuraciones más complejas, las limitaciones de las variables de entorno basadas en texto se volvieron cada vez más evidentes, haciendo que las configuraciones avanzadas fueran complicadas y difíciles de mantener.

Aquí entra la configuración declarativa, una poderosa evolución que utiliza archivos YAML para definir los ajustes de OpenTelemetry. Este cambio permite leer datos desde cualquier fuente estructurada en forma de árbol, transformando fundamentalmente la manera en que abordamos configuraciones complejas. A lo largo de este artículo, exploraremos cómo la configuración declarativa ofrece una solución elegante a los desafíos del pasado y cómo tiene un impacto inmediato con casos prácticos como la exclusión de health checks en Java.

Primeros pasos

El archivo de configuración es independiente del lenguaje, por lo que una vez creado, puedes usarlo con todos tus SDKs. Las únicas excepciones son los parámetros con el nombre del lenguaje, que solo son relevantes para ese lenguaje (por ejemplo, el parámetro instrumentation/development.java.spring_batch). Ten en cuenta que la configuración declarativa es experimental, por lo que aún puede haber cambios.

El siguiente ejemplo muestra un archivo de configuración básico para comenzar:

file_format: '1.0-rc.1'

resource:
  attributes_list: ${OTEL_RESOURCE_ATTRIBUTES}
  detection/development:
    detectors:
      - service: # agregará "service.instance.id" y "service.name" desde OTEL_SERVICE_NAME

tracer_provider:
  processors:
    - batch:
        exporter:
          otlp_http:
            endpoint: ${OTEL_EXPORTER_OTLP_TRACES_ENDPOINT:-http://localhost:4318/v1/traces}

meter_provider:
  readers:
    - periodic:
        exporter:
          otlp_http:
            endpoint: ${OTEL_EXPORTER_OTLP_METRICS_ENDPOINT:-http://localhost:4318/v1/metrics}

logger_provider:
  processors:
    - batch:
        exporter:
          otlp_http:
            endpoint: ${OTEL_EXPORTER_OTLP_LOGS_ENDPOINT:-http://localhost:4318/v1/logs}

Todo lo que necesitas es pasar OTEL_EXPERIMENTAL_CONFIG_FILE=/path/to/otel-config.yaml a la aplicación para activar la opción experimental de configuración declarativa. Esta variable solo funciona en el agente de Java y en JavaScript al momento de escribir este texto.

Configuración declarativa en Java

Veamos ahora la implementación más amplia de la configuración declarativa dentro del ecosistema Java. Como lenguaje pionero en esta área, el agente de Java en la versión 2.21+ ya admite completamente la configuración declarativa, con la mayoría de las instrumentaciones y funcionalidades operativas. Estamos trabajando para incorporar las funcionalidades restantes durante 2026, y puedes seguir el progreso en el panel del proyecto y ver la lista de funcionalidades aún no soportadas.

Dependiendo de si comienzas desde cero o migras desde variables de entorno, puedes aprovechar varios recursos:

  • El archivo básico (independiente del lenguaje) del ejemplo anterior es la forma más rápida de empezar si no necesitas personalizaciones adicionales.
  • El archivo de migración mapea las variables de entorno antiguas al esquema YAML, permitiendo una sustitución directa para usuarios con cargas configuradas mediante variables de entorno.
  • El archivo completo (“cocina completa”) muestra todo el esquema, con documentación como comentarios. Es útil para quienes desean ver todas las opciones disponibles y sus valores predeterminados.

Todos los archivos anteriores funcionan para cualquier lenguaje que admita configuración declarativa.

Además, existen ajustes específicos del agente Java que deben incluirse en la sección instrumentation del archivo de configuración. Por ejemplo, si tienes la propiedad del sistema otel.instrumentation.spring-batch.experimental.chunk.new-trace en tu aplicación, puedes crear la configuración declarativa eliminando el prefijo otel.instrumentation, dividiendo por puntos y reemplazando - por _.

file_format: '1.0-rc.1'

# ...

instrumentation/development:
  java:
    spring_batch:
      experimental:
        chunk:
          new_trace: true

Con esta configuración, los desarrolladores pueden continuar usando la instrumentación de Java como siempre, enviando datos de telemetría a su backend de observabilidad preferido. Además, el archivo de configuración declarativa ofrece flexibilidad para ampliar y agregar más parámetros según sea necesario, permitiendo un control altamente personalizado y detallado sobre la configuración de observabilidad.

Exclusión de health checks

Como se mencionó en la introducción, una de las solicitudes más comunes en la comunidad de Java fue poder excluir los health checks (u otros recursos poco relevantes o ruidosos) de la generación de trazas.

Para lograrlo, debes agregar un bloque sampler dentro de tu configuración de tracer_provider, como se muestra a continuación:

file_format: '1.0-rc.1'

# ... el resto de la configuración ...

tracer_provider:
  # Configura el muestreo para excluir endpoints de health check.
  sampler:
    rule_based_routing:
      fallback_sampler:
        always_on:
      span_kind: SERVER
      rules:
        # Acción a tomar cuando la regla coincide. Debe ser DROP o RECORD_AND_SAMPLE.
        - action: DROP
          # El atributo del span con el que se comparará.
          attribute: url.path
          # El patrón a comparar con el atributo del span.
          pattern: /actuator.*
# ... el resto de la configuración de tracer_provider ...

Consulta la documentación del sampler de Java para más detalles sobre las opciones disponibles.

Pruébalo tú mismo:

  1. Guarda la configuración completa
  2. Ejecuta el agente de Java con -Dotel.experimental.config.file=/path/to/otel-config.yaml

Disponibilidad

Luego de leer sobre la configuración declarativa, quizás te preguntes dónde está disponible y cómo puedes empezar a usarla. Puedes encontrar orientación y los lenguajes soportados en la documentación. Al momento de esta publicación, Java es totalmente compatible, mientras que PHP, JavaScript y Go tienen compatibilidad parcial. Para ver el estado más reciente, consulta la matriz de compatibilidad o el issue de seguimiento de implementaciones por lenguaje.

Java

Como se describió antes, la configuración declarativa en Java es experimental, pero lista para usarse. Usa el ejemplo mencionado para configurar tu entorno. Si tienes preguntas o comentarios, comunícate en #otel-java en Slack de la CNCF.

Nota para mantenedores de otros lenguajes: Es útil crear un módulo puente que adapte los ajustes de configuración declarativa y las variables de entorno a una interfaz común. En Java, este módulo es el Declarative Config Bridge.

JavaScript

La implementación en el SDK de JavaScript está actualmente en desarrollo. Se ha creado un nuevo paquete llamado opentelemetry-configuration, que maneja tanto variables de entorno como configuración declarativa. Con este enfoque, el usuario no necesita modificar su instrumentación al cambiar entre variables de entorno y archivo de configuración, ya que el nuevo paquete maneja ambos y devuelve el mismo modelo de configuración. Actualmente, este paquete se está integrando en otros paquetes de instrumentación para aprovechar la configuración declarativa. Si tienes dudas, únete a #otel-js en Slack de la CNCF.

PHP

La implementación de PHP es parcialmente compatible, y puedes empezar a usarla inicializando desde tu archivo de configuración. Para soporte o comentarios, comunícate en #otel-php.

Go

Go tiene una implementación parcial de la configuración declarativa. Cada versión del esquema soportada tiene su propio directorio de paquete. Por ejemplo, al importar go.opentelemetry.io/contrib/otelconf/v0.3.0 obtienes el código compatible con la versión 0.3.0 del esquema. Puedes encontrar todas las versiones disponibles en el índice de paquetes. Si tienes dudas sobre cómo usarlo, únete a #otel-go.

El recorrido

Entonces, ¿por qué nos tomó realmente cinco años ignorar los endpoints de health check en las trazas?

El recorrido hacia la configuración declarativa —y en consecuencia, hacia la solución de exclusión de health checks— refleja un principio central de OpenTelemetry: construir soluciones sostenibles a través de especificaciones rigurosas.

Desde el inicio, la dependencia de OpenTelemetry en las variables de entorno, aunque universal, se volvió cada vez más compleja para configuraciones avanzadas. Finalmente, se prohibió la creación de nuevas variables de entorno, dejando un vacío que debía llenarse con una solución más robusta.

La sustitución, como presentamos en este artículo, es la configuración declarativa. Definir y acordar la sintaxis y semántica precisas fue un proceso largo y, a veces, agotador. Por ejemplo, se debatieron varias propuestas sobre cómo incrustar variables de entorno hasta llegar a la solución actual de usar ${OTEL_EXPORTER_OTLP_ENDPOINT:-http://localhost:4318}.

Este proceso sirve como un poderoso caso de estudio sobre cómo opera la comunidad de OpenTelemetry: es un testimonio del consenso, la colaboración y el esfuerzo colectivo necesarios para introducir nuevas funcionalidades y llevarlas a cabo a través de diversos proyectos.

¿Qué sigue para la configuración declarativa?

El recorrido de la configuración declarativa está lejos de terminar. Nuestro enfoque actual implica un gran esfuerzo para ampliar el soporte entre lenguajes, lo cual es crucial para garantizar que los desarrolladores, sin importar sus herramientas preferidas, puedan aprovechar los beneficios del enfoque declarativo.

Nos interesa profundamente los comentarios de los usuarios a medida que seguimos desarrollando y mejorando estas funcionalidades. Te invitamos a experimentar con las implementaciones actuales y comunicar activamente cualquier funcionalidad que falte, los puntos problemáticos o las áreas de mejora. Este enfoque colaborativo nos ayudará a priorizar esfuerzos y a garantizar que las soluciones que construimos realmente respondan a las necesidades de la comunidad. Puedes compartir tus comentarios o preguntas en el canal #otel-config-file de Slack de la CNCF.

Además de brindar comentarios, hay otras maneras de participar y contribuir al crecimiento de la configuración declarativa. Cada SDK de OpenTelemetry tiene Grupos de Interés Especial (SIGs) dedicados a su implementación. Unirte a estos SIGs ofrece una vía directa para entender el estado actual, participar en discusiones e identificar oportunidades de colaboración. Ya sea a través de contribuciones de código, mejoras en la documentación o simplemente compartiendo tu experiencia, cada aporte ayuda a fortalecer el ecosistema de configuración declarativa. Tu participación activa es clave para fomentar un conjunto sólido y versátil de herramientas para el desarrollo de aplicaciones modernas.

¡Esperamos escucharte pronto!

Recursos adicionales

Para conocer más sobre el trabajo que se está realizando en torno a la configuración declarativa, consulta los siguientes recursos: