Este tutorial te guiará a través de los pasos para habilitar el rastreo en una aplicación de ejemplo Java instalada en un clúster en AWS Elastic Kubernetes Service (EKS). En este caso, el Datadog Agent también está instalado en el clúster.
Para otros casos, incluyendo el de un host, un contenedor, otra infraestructura en la nube y aplicaciones escritas en otros lenguajes, consulta Tutoriales: Habilitación del rastreo.
Para obtener documentación general sobre la configuración del rastreo en Java, consulta Rastreo de aplicaciones Java.
El repositorio contiene una aplicación Java preconfigurada de servicio múltiple para ejecutarse dentro de un clúster Kubernetes. La del ejemplo es una aplicación básica de notas con una API REST para añadir y modificar datos. Los archivos docker-compose YAML para la creación de contenedores para pods Kubernetes se encuentran en el directorio docker. Este tutorial utiliza el archivo service-docker-compose-k8s.yaml, que crea contenedores para la aplicación.
En cada uno de los directorios notes y calendar, hay dos conjuntos de archivos Docker para crear aplicaciones, ya sea con Maven o con Gradle. Este tutorial utiliza la creación con Maven, pero si Gradle te resulta más familiar, puedes utilizarlo en su lugar con los cambios correspondientes en los comandos de creación.
Los archivos de configuración Kubernetes para las aplicaciones notes, calendar y el Datadog Agent se encuentran en el directorio kubernetes.
El proceso para obtener la aplicación de ejemplo implica crear las imágenes desde la carpeta docker, cargarlas en un registro y crear recursos Kubernetes desde la carpeta kubernetes.
Para iniciar el clúster
Si aún no dispones de un clúster EKS que quieras reutilizar, crea uno ejecutando el siguiente comando y sustituyendo <CLUSTER_NAME> por el nombre que quieres utilizar:
eksctl create cluster --name <CLUSTER_NAME>
Esta acción crea un clúster EKS con un grupo de nodos gestionado, donde puedes desplegar pods. Para obtener más información sobre la resolución de problemas y la configuración, consulta la documentación de eksctl para la creación de clústeres. Si estás utilizando un clúster creado de otra forma (por ejemplo, utilizando la consola web AWS), asegúrate de que el clúster está conectado a tu archivo local kubeconfig, tal y como se describe en la documentación de eksctl.
La creación de un clúster puede tardar entre 15 y 20 minutos. Mientras esperas a que el clúster termine de crearse, continúa con otros pasos.
Creación y carga de la imagen de la aplicación
Si no te resulta familiar Amazon ECR, que es un registro para imágenes EKS, podría serte útil consultar el uso de Amazon ECR con la AWS CLI.
En el directorio /docker del proyecto de ejemplo, ejecuta los siguientes comandos:
Autentícate con el ECR, introduciendo tu nombre de usuario y contraseña en este comando:
docker tag docker-notes:latest <ECR_REGISTRY_URL>:notes
Carga el contenedor en el registro ECR:
docker push <ECR_REGISTRY_URL>:notes
Tu aplicación está contenedorizada y se encuentra disponible para la extracción para clústeres EKS.
Actualización de las políticas de seguridad de entrada del clúster AWS
Para comunicarte con las aplicaciones de ejemplo, asegúrate de que las reglas de seguridad del clúster están configuradas con los puertos 30080 y 30090 abiertos.
Abre la consola AWS y ve hasta tu clúster desplegado dentro del servicio EKS.
En la consola del clúster, selecciona la pestaña de redes y haz clic en el grupo de seguridad de tu clúster.
En la configuración de tu grupo de seguridad, edita las reglas de entrada. Añade una regla que permita el tráfico TCP personalizado, un intervalo de puertos de 30060 a 30100 y el origen de 0.0.0.0/0.
Guarda la regla.
Configuración local y despliegue de la aplicación
Abre kubernetes/notes-app.yaml y actualiza la entrada image con la URL de la imagen ECR, donde introdujiste el contenedor anterior:
Desde el directorio /kubernetes, ejecuta el siguiente comando para desplegar la aplicación notes:
kubectl create -f notes-app.yaml
Para ejercitar la aplicación, es necesario encontrar su dirección IP externa para llamar a su API REST. En primer lugar, busca el pod notes-app-deploy en el resultado de la lista con el siguiente comando y anota su nodo:
kubectl get pods -o wide
A continuación, busca el nombre del nodo en el resultado del siguiente comando y anota el valor de la IP externa:
kubectl get nodes -o wide
En los ejemplos mostrados, notes-app se ejecuta en el nodo ip-192-189-63-129.ec2.internal, cuya IP externa es 34.230.7.210.
Abre otro terminal y envía solicitudes API para ejercitar la aplicación. La aplicación de notas es una API REST que almacena datos en una base de datos H2 en memoria que se ejecuta en el mismo contenedor. Envíale algunos comandos:
curl '<EXTERNAL_IP>:30080/notes'
[]
curl -X POST '<EXTERNAL_IP>:30080/notes?desc=hello'
{"id":1,"description":"hello"}
curl '<EXTERNAL_IP>:30080/notes?id=1'
{"id":1,"description":"hello"}
curl '<EXTERNAL_IP>:30080/notes'
[{"id":1,"description":"hello"}]
Una vez que hayas comprobado que la aplicación se ejecuta, detenla para poder activar el rastreo en ella:
kubectl delete -f notes-app.yaml
Habilitación del rastreo
Ahora que ya tienes una aplicación Java en funcionamiento, configúrala para habilitar el rastreo.
Añade el paquete de rastreo Java a tu proyecto. Como el Agent se ejecuta en un clúster EKS, asegúrate de que los archivos Docker están correctamente configurados y que no es necesario instalar nada. Abre el archivo notes/dockerfile.notes.maven y descomenta la línea que descarga dd-java-agent:
RUN curl -Lo dd-java-agent.jar 'https://dtdg.co/latest-java-tracer'
Dentro del mismo archivo notes/dockerfile.notes.maven, comenta la línea ENTRYPOINT para una ejecución sin rastreo. A continuación, descomenta la línea ENTRYPOINT, que ejecuta la aplicación con el rastreo habilitado:
De este modo, la aplicación se instrumenta automáticamente con servicios Datadog.
Nota: Las marcas de estos comandos de muestreo, en particular la frecuencia de muestreo, no son necesariamente apropiadas para los entornos que no figuran en este tutorial. Para obtener más información sobre qué necesitas utilizar en tu entorno real, consulta Configuración del rastreo.
El Etiquetado unificado de servicios identifica servicios rastreados en diferentes versiones y entornos de despliegue, para que puedan correlacionarse en Datadog y puedas utilizarlos para buscar y filtrar. Las tres variables de entorno utilizadas para el etiquetado unificado de servicios son DD_SERVICE, DD_ENV y DD_VERSION. Para las aplicaciones desplegadas con Kubernetes, estas variables de entorno pueden añadirse en el archivo YAML de despliegue, específicamente para el objeto de despliegue, las especificaciones del pod y la plantilla del contenedor del pod.
En este tutorial, el archivo kubernetes/notes-app.yaml ya tiene definidas estas variables de entorno para la aplicación de notas para el objeto de despliegue, las especificaciones del pod y la plantilla del contenedor del pod.:
Tu aplicación con el rastreo habilitado está contenedorizada y se encuentra disponible para la extracción para clústeres EKS.
Instalación y ejecución del Agent con Helm
A continuación, despliega el Agent en EKS para recopilar los datos de rastreo de tu aplicación instrumentada.
Abre kubernetes/datadog-values.yaml para ver la configuración mínima requerida Configuración para el Agent y APM en GKE. Este archivo de configuración es utilizado por el comando que se ejecuta a continuación.
Desde el directorio /kubernetes, ejecuta el siguiente comando, introduciendo tu clave de API y el nombre de clúster:
Para despliegues más seguros que no exponen la clave de API, consulta esta guía sobre el uso de secretos. Además, si utilizas un sitio Datadog distinto de us1, sustituya datadoghq.com por tu sitio.
Inicio de la aplicación para observar el rastreo automático
Siguiendo los mismos pasos que antes, despliega la aplicación notes con kubectl create -f notes-app.yaml y busca la dirección IP externa del nodo en el que se ejecuta.
Ejecuta algunos comandos curl para ejercitar la aplicación:
curl '<EXTERNAL_IP>:30080/notes'
[]
curl -X POST '<EXTERNAL_IP>:30080/notes?desc=hello'
{"id":1,"description":"hello"}
curl '<EXTERNAL_IP>:30080/notes?id=1'
{"id":1,"description":"hello"}
curl '<EXTERNAL_IP>:30080/notes'
[{"id":1,"description":"hello"}]
Espera unos instantes y ve a APM > Traces (APM > Trazas) en Datadog, donde podrás ver una lista de trazas correspondiente a tus llamadas de API:
La base de datos en memoria integrada para este tutorial es h2 y la aplicación Spring Boot es notes. La lista de trazas muestra todos los tramos, cuándo se han iniciado, qué recurso se ha rastreado con el tramo y cuánto tiempo ha tardado.
Si no ves trazas después de varios minutos, borra cualquier filtro en el campo de búsqueda de trazas (a veces se filtra sobre una variable de entorno como ENV que no estás utilizando).
Análisis de una traza
En la página de trazas, haz clic en una traza POST /notes para ver un gráfico de llama que muestra cuánto tiempo ha tardado cada tramo y qué otros tramos han ocurrido antes de que se completara un tramo. La barra de la parte superior del gráfico es el tramo seleccionado en la pantalla anterior (en este caso, el punto de entrada inicial en la aplicación de notas).
La anchura de una barra indica el tiempo que ha tardado en completarse. Una barra de menor profundidad representa una tramo que se completa durante el tiempo de vida de una barra a mayor profundidad.
El gráfico de llama de una traza POST tiene este aspecto:
Una traza GET /notes tiene este aspecto:
Configuración del rastreo
La biblioteca de rastreo Java utiliza el Agent incorporado y el soporte de monitorización Java. La marca -javaagent:../dd-java-agent.jar en el archivo Docker indica a la máquina virtual Java dónde encontrar la biblioteca de rastreo Java para que pueda ejecutarse como un Agent Java. Para obtener más información sobre Agents Java, consulta https://www.baeldung.com/java-instrumentation.
La marca dd.trace.sample.rate configura la frecuencia de muestreo para esta aplicación. El comando ENTRYPOINT en el archivo Docker configura su valor en 1, lo que significa que el 100% de todas las solicitudes al servicio notes se envían al backend Datadog para su análisis y visualización. Para una aplicación de prueba de bajo volumen, esto está bien. Pero no lo hagas en producción o en entornos de gran volumen, ya que esto generará un volumen muy elevado de datos. En su lugar, muestrea algunas de tus solicitudes. Elige un valor entre 0 y 1. Por ejemplo, -Ddd.trace.sample.rate=0.1 envía trazas (traces) del 10% de tus solicitudes a Datadog. Consulta la documentación para obtener más información sobre parámetros de configuración del rastreo y mecanismos de muestreo.
Fíjate que la marca de la frecuencia de muestreo en el comando aparece antes que la marca -jar. Esto se debe a que se trata de un parámetro para la máquina virtual Java y no para tu aplicación. Cuando añadas el Agent Java a tu aplicación, asegúrate de especificar la marca en la ubicación correcta.
Añadir la instrumentación manual a la aplicación Java
La instrumentación automática es práctica, pero a veces prefieres utilizar tramos más precisos. La API de rastreo DD Java Datadog te permite especificar tramos en tu código mediante anotaciones o código.
Los siguientes pasos te guiarán a través de la modificación de los scripts de compilación para descargar la biblioteca de rastreo Java y añadir algunas anotaciones al código para rastrear en algunos métodos de ejemplo.
Elimina los despliegues de aplicaciones actuales:
kubectl delete -f notes-app.yaml
Abre /notes/src/main/java/com/datadog/example/notes/NotesHelper.java. Este ejemplo ya contiene código comentado que muestra las diferentes formas de configurar el rastreo personalizado en el código.
Descomenta las líneas que importan bibliotecas para permitir el rastreo manual:
Descomenta las líneas que rastrean manualmente los dos procesos públicos. Éstas muestran el uso de anotaciones @Trace para especificar aspectos como operationName y resourceName en una traza:
También puedes crear un tramo separado para un bloque de código específico en la aplicación. Dentro del tramo, añade etiquetas de servicio y de nombre de recurso y etiquetas de gestión de errores. Estas etiquetas dan como resultado un gráfico de llama que muestra tramos y métricas en visualizaciones de Datadog. Descomenta las líneas que rastrean manualmente el método privado:
Tracertracer=GlobalTracer.get();// Tags can be set when creating the spanSpanspan=tracer.buildSpan("manualSpan1").withTag(DDTags.SERVICE_NAME,"NotesHelper").withTag(DDTags.RESOURCE_NAME,"privateMethod1").start();try(Scopescope=tracer.activateSpan(span)){// Tags can also be set after creationspan.setTag("postCreationTag",1);Thread.sleep(30);Log.info("Hello from the custom privateMethod1");
Y también las líneas que establecen etiquetas en los errores:
}catch(Exceptione){// Set error on spanspan.setTag(Tags.ERROR,true);span.setTag(DDTags.ERROR_MSG,e.getMessage());span.setTag(DDTags.ERROR_TYPE,e.getClass().getName());finalStringWritererrorString=newStringWriter();e.printStackTrace(newPrintWriter(errorString));span.setTag(DDTags.ERROR_STACK,errorString.toString());Log.info(errorString.toString());}finally{span.finish();}
Actualiza tu compilación Maven abriendo notes/pom.xml y descomentando las líneas que configuran dependencias para el rastreo manual. La biblioteca dd-trace-api se utiliza para las anotaciones @Trace, y opentracing-util y opentracing-api se utilizan para la creación manual de tramos.
Reconstruye la aplicación y cárgala a ECR siguiendo los mismos pasos que antes, ejecutando estos comandos:
Siguiendo los mismos pasos que antes, despliega la aplicación notes con kubectl create -f notes-app.yaml y busca la dirección IP externa del nodo en el que se ejecuta.
Reenvía algunas solicitudes HTTP, concretamente algunas solicitudes GET.
En el explorador de trazas, haz clic en una de las nuevas solicitudes GET y verás un gráfico de llama como éste:
Observa el mayor nivel de detalle de la traza del stack tecnológico ahora que la función getAll cuenta con el rastreo personalizado.
El privateMethod alrededor del cual has creado un tramo manual aparece ahora como un bloque separado de las otras llamadas y está resaltado con un color diferente. Los otros métodos en los que has utilizado la anotación @Trace se muestran bajo el mismo servicio y color que la solicitud GET, que es la aplicación notes. La instrumentación personal es valiosa cuando hay partes clave del código que necesitan ser resaltadas y monitorizadas.
Añadir una segunda aplicación para ver trazas distribuidas
El rastreo de una única aplicación es un buen comienzo, pero el verdadero valor del rastreo consiste en ver cómo fluyen las solicitudes a través de tus servicios. Esto se llama rastreo distribuido.
El proyecto de ejemplo incluye una segunda aplicación llamada calendar que devuelve una fecha aleatoria cada vez que se invoca. El endpoint POST de la aplicación de notas tiene un segundo parámetro de consulta llamado add_date. Cuando se configura en y, la aplicación de notas llama a la aplicación de calendario para obtener una fecha y añadirla a una nota.
Configura la aplicación calendar para el rastreo añadiendo dd-java-agent al comando de inicio en el archivo Docker, como hiciste anteriormente para la aplicación de notas. Abre calendar/dockerfile.calendar.maven y comprueba que ya está descargando dd-java-agent:
RUN curl -Lo dd-java-agent.jar 'https://dtdg.co/latest-java-tracer'
Dentro del mismo archivo calendar/dockerfile.calendar.maven, comenta la línea ENTRYPOINT para ejecutar sin rastreo. A continuación, descomenta la línea ENTRYPOINT, que ejecuta la aplicación con el rastreo habilitado:
Nota: Nuevamente, las marcas, en particular la frecuencia de muestreo, no son necesariamente apropiadas para los entornos que no figuran en este tutorial. Para obtener más información sobre qué necesitas utilizar en tu entorno real, consulta Configuración del rastreo.
Crea ambas aplicaciones y publícalas en ECR. Desde el directorio docker, ejecuta:
Abre kubernetes/calendar-app.yaml y actualiza la entrada image con la dirección URL de la imagen ECR, donde introdujiste la aplicación calendar en el paso anterior:
Utilizando el método que utilizaste antes, busca la IP externa de la aplicación notes.
Envía una solicitud POST con el parámetro add_date:
curl -X POST '<EXTERNAL_IP>:30080/notes?desc=hello_again&add_date=y'
{"id":1,"description":"hello_again with date 2022-11-06"}
En el explorador de trazas, haz clic en esta última traza para ver un rastreo distribuido entre ambos servicios:
Observa que no has cambiado nada en la aplicación notes. Datadog instrumenta automáticamente tanto la biblioteca okHttp utilizada para realizar la llamada HTTP de notes a calendar, como la biblioteca Jetty utilizada para escuchar solicitudes HTTP en notes y calendar. Esto permite que la información de rastreo pase de una aplicación a la otra, registrando un rastreo distribuido.
Cuando hayas terminado de explorar, borra todos los recursos y elimina los despliegues:
Para obtener información sobre la eliminación de clústeres, consulta la documentación de EKS.
Solucionar problemas
Si no recibes trazas como esperabas, configura el modo de depuración para el rastreador de Java. Para obtener más información, consulta Habilitar el modo de depuración.