Este tutorial te guía a través de los pasos para activar el rastreo en una aplicación Go de ejemplo instalada en un clúster en AWS Elastic Container Service (ECS). En este escenario, el Datadog Agent también está instalado en el clúster.
Para otros casos, incluyendo la aplicación y el Agent en un host, la aplicación en un contenedor y el Agent en un host, la aplicación y el Agent en infraestructura en la nube y aplicaciones escritas en otros lenguajes, consulta Tutoriales: Activación del rastreo. Algunos de esos otros tutoriales, por ejemplo, los que utilizan contenedores o EKS, repasan las diferencias vistas en Datadog entre la instrumentación automática y personalizada. Este tutorial pasa directamente a un ejemplo personalizado instrumentado totalmente.
Este tutorial también utiliza temas de nivel intermedio de AWS, por lo que requiere que tengas cierta familiaridad con las redes y aplicaciones de AWS. Si no estás tan familiarizado con AWS, y estás tratando de aprender lo básico de la configuración de APM en Datadog, utiliza uno de los tutoriales de host o contenedor.
Consulta Rastreo de aplicaciones Go para obtener documentación general sobre la configuración del rastreo para Go.
Un usuario de AWS IAM con permiso AdministratorAccess. Debes añadir el perfil a tu archivo de credenciales local utilizando las claves de acceso y claves de acceso secreto. Para obtener más información, lee Configuración del SDK de AWS para Go V2.
Instalar la aplicación Go de ejemplo
A continuación, instala una aplicación de ejemplo para rastrear. El código de ejemplo para este tutorial se puede encontrar en github.com/DataDog/apm-tutorial-golang.git. Clona el repositorio git ejecutando:
El repositorio contiene una aplicación Go multiservicio preconfigurada para ejecutarse dentro de contenedores de Docker. Los archivos YAML docker-compose para crear los contenedores se encuentran en el directorio docker. Este tutorial utiliza el archivo service-docker-compose-ECS.yaml, que crea contenedores para los servicios notes y calendar que componen la aplicación de ejemplo.
Configuración inicial del ECS
La aplicación requiere una breve configuración inicial, incluyendo la adición de tu perfil de AWS (ya configurado con los permisos correctos para crear un clúster de ECS y leer en ECR), región de AWS y el repositorio de Amazon ECR.
Abre terraform/EC2/global_constants/variables.tf. Sustituye los valores de las variables siguientes por la información correcta de tu cuenta de AWS:
Tu aplicación (sin el rastreo activado) está en un contenedor y está disponible para que ECS la extraiga.
Despliegue de la aplicación
Inicia la aplicación y envía algunas solicitudes sin rastreo. Después de haber visto cómo funciona la aplicación, la instrumentarás utilizando la biblioteca de rastreo y el Datadog Agent.
Para comenzar, utiliza un script de Terraform para realizar el despliegue en Amazon ECS:
Desde el directorio terraform/EC2/deployment, ejecuta los siguientes comandos:
terraform init
terraform apply
terraform state show 'aws_alb.application_load_balancer'
Nota: Si el comando terraform apply devuelve un mensaje de bloqueo de CIDR, el script para obtener tu dirección IP no ha funcionado en tu máquina local. Para solucionarlo, establece el valor manualmente en el archivo terraform/EC2/deployment/security.tf. Dentro del bloque ingress del load_balancer_security_group, cambia la línea cidr_blocks que está comentada y actualiza la línea de ejemplo now-uncommented con la dirección IP4 de tu máquina.
Anota el nombre del DNS del equilibrador de carga. Utilizarás ese dominio base en las llamadas a la API de la aplicación de ejemplo. Espera unos minutos a que se inicien las instancias.
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 -X GET 'BASE_DOMAIN:8080/notes'
[]
curl -X POST 'BASE_DOMAIN:8080/notes?desc=hello'
{"id":1,"description":"hello"}
curl -X GET 'BASE_DOMAIN:8080/notes?id=1'
{"id":1,"description":"hello"}
curl -X GET 'BASE_DOMAIN:8080/notes'
[{"id":1,"description":"hello"}]
curl -X PUT 'BASE_DOMAIN:8080/notes?id=1&desc=UpdatedNote'
{"id":1,"description":"UpdatedNote"}
curl -X GET 'BASE_DOMAIN:8080/notes'
[{"id":1,"description":"UpdatedNote"}]
curl -X POST 'BASE_DOMAIN:8080/notes?desc=NewestNote&add_date=y'
{"id":2,"description":"NewestNote with date 12/02/2022."}
Este comando llama tanto al servicio notes como a calendar.
Una vez que hayas visto que la aplicación está funcionando, ejecuta el siguiente comando para detenerla y limpiar los recursos de AWS para que puedas habilitar el rastreo:
terraform destroy
Activación del rastreo
A continuación, configura la aplicación Go para habilitar el rastreo.
Para activar el soporte de rastreo:
Para activar el rastreo automático, elimina los comentarios de las siguientes importaciones en apm-tutorial-golang/cmd/notes/main.go:
Los pasos anteriores habilitaron el rastreo automático con bibliotecas completamente compatibles. En los casos en los que el código no entre dentro de una biblioteca compatible, puedes crear tramos manualmente.
Abre notes/notesController.go. Este ejemplo ya contiene código comentado que demuestra las diferentes formas de configurar el rastreo personalizado en el código.
La función makeSpanMiddleware en notes/notesController.go genera middleware que envuelve una solicitud en un tramo (span) con el nombre suministrado. Elimina los comentarios de las siguientes líneas:
notes/notesController.go
r.Get("/notes",nr.GetAllNotes)// GET /notes
r.Post("/notes",nr.CreateNote)// POST /notes
r.Get("/notes/{noteID}",nr.GetNoteByID)// GET /notes/123
r.Put("/notes/{noteID}",nr.UpdateNoteByID)// PUT /notes/123
r.Delete("/notes/{noteID}",nr.DeleteNoteByID)// DELETE /notes/123
notes/notesController.go
r.Get("/notes",makeSpanMiddleware("GetAllNotes",nr.GetAllNotes))// GET /notes
r.Post("/notes",makeSpanMiddleware("CreateNote",nr.CreateNote))// POST /notes
r.Get("/notes/{noteID}",makeSpanMiddleware("GetNote",nr.GetNoteByID))// GET /notes/123
r.Put("/notes/{noteID}",makeSpanMiddleware("UpdateNote",nr.UpdateNoteByID))// PUT /notes/123
r.Delete("/notes/{noteID}",makeSpanMiddleware("DeleteNote",nr.DeleteNoteByID))// DELETE /notes/123
Elimina también el comentario de la siguiente importación:
notes/notesController.go
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer"
La función doLongRunningProcess crea tramos (spans) secundarios a partir de un contexto primario. Elimina los comentarios para habilitarla:
notes/notesHelper.go
funcdoLongRunningProcess(ctxcontext.Context){childSpan,ctx:=tracer.StartSpanFromContext(ctx,"traceMethod1")childSpan.SetTag(ext.ResourceName,"NotesHelper.doLongRunningProcess")deferchildSpan.Finish()time.Sleep(300*time.Millisecond)log.Println("Hello from the long running process in Notes")privateMethod1(ctx)}
La función privateMethod1 demuestra la creación de un servicio completamente independiente de un contexto. Elimina los comentarios para habilitarla:
notes/notesHelper.go
funcprivateMethod1(ctxcontext.Context){childSpan,_:=tracer.StartSpanFromContext(ctx,"manualSpan1",tracer.SpanType("web"),tracer.ServiceName("noteshelper"),)childSpan.SetTag(ext.ResourceName,"privateMethod1")deferchildSpan.Finish()time.Sleep(30*time.Millisecond)log.Println("Hello from the custom privateMethod1 in Notes")}
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 en ECS, estas variables de entorno se configuran dentro de la definición de tarea para los contenedores.
Para este tutorial, el archivo /terraform/EC2/deployment/main.tf ya tiene definidas estas variables de entorno para las aplicaciones de notas y calendario. Por ejemplo, para notes:
También puedes ver que se configuran las etiquetas (labels) de Docker para los mismos valores de etiquetas unificadas de servicios service , env y version. Esto también te permite obtener métricas de Docker una vez que tu aplicación se esté ejecutando.
Reconstrucción y carga de la imagen de la aplicación
Tu aplicación de multiservicio con rastreo activado está en contenedores y se encuentra disponible para su extracción por ECS.
Despliegue del Agent en ECS
A continuación, despliega el Datadog Agent para recopilar los datos de traza de tu aplicación instrumentada. Para un entorno de ECS, no debes descargar nada para ejecutar el Agent. En su lugar, sigue estos pasos para crear una definición de tarea de Datadog Agent, carga la definición de tarea en AWS, y crea un servicio de Agent en tu clúster utilizando esa definición de tarea.
Abre terraform/EC2/dd_agent_task_definition.json, que proporciona una configuración básica para ejecutar el Agent con el rastreo de APM activado. Proporciona la clave de API de tu organización de Datadog y el sitio de Datadog según corresponda:
En la salida, anota el valor taskDefinitionArn, que se utilizará en el paso siguiente.
Crea el servicio del Agent en el clúster ejecutando este comando, al brindar el ARN de definición de tarea del paso anterior, tu perfil de AWS y la región de AWS:
Vuelve a desplegar la aplicación y ejercita la API:
Vuelve a implementar la aplicación en Amazon ECS utilizando los mismos comandos de Terraform que antes, pero con la versión instrumentada de los archivos de configuración. Desde el directorio terraform/EC2/deployment, ejecuta los siguientes comandos:
terraform init
terraform apply
terraform state show 'aws_alb.application_load_balancer'
Anota el nombre del DNS del equilibrador de carga. Utilizarás ese dominio básico en las llamadas de la API a la aplicación de ejemplo.
Espera unos minutos a que se inicien las instancias. Espera unos minutos para asegurarte de que los contenedores para las aplicaciones están listos. Ejecuta algunos comandos curl para ejercitar la aplicación instrumentada:
curl -X GET 'BASE_DOMAIN:8080/notes'
[]
curl -X POST 'BASE_DOMAIN:8080/notes?desc=hello'
{"id":1,"description":"hello"}
curl -X GET 'BASE_DOMAIN:8080/notes?id=1'
{"id":1,"description":"hello"}
curl -X GET 'BASE_DOMAIN:8080/notes'
[{"id":1,"description":"hello"}]
curl -X PUT 'BASE_DOMAIN:8080/notes?id=1&desc=UpdatedNote'
{"id":1,"description":"UpdatedNote"}
curl -X GET 'BASE_DOMAIN:8080/notes'
[{"id":1,"description":"hello"}]
curl -X POST 'BASE_DOMAIN:8080/notes?desc=NewestNote&add_date=y'
{"id":2,"description":"NewestNote with date 12/02/2022."}
Este comando llama tanto al servicio notes como a calendar.
Espera unos instantes y echa un vistazo a tu interfaz de usuario de Datadog. Navega a APM > Traces (APM > Trazas). La lista de trazas muestra algo como esto:
Hay entradas para la base de datos (db) y la aplicación notes. La lista de trazas muestra todos los tramos, cuándo se iniciaron, qué recurso se rastreó con el tramo y cuánto tiempo tardó.
Si no ves trazas, borra cualquier filtro en el campo de búsqueda Traces (Trazas) (a veces filtra en una variable de entorno como ENV que no estás usando).
Análisis de una traza
En la página Traces (Trazas), haz clic en una traza POST /notes, para ver una gráfica de llamas que muestra cuánto tiempo tardó cada tramo y qué otros tramos ocurrieron antes de que se completara un tramo. La barra de la parte superior de la gráfica es el tramo que seleccionaste en la pantalla anterior (en este caso, el punto de entrada inicial en la aplicación de notas).
El ancho de una barra indica el tiempo que ha tardado en completarse. Una barra más angosta representa un tramo que se completa durante el tiempo de vida de una barra de mayor ancho.
La gráfica de llamas de una traza POST tiene este aspecto:
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. Haz clic en la traza de la última llamada a la API, la que ha añadido una fecha a la nota, para ver una traza distribuida entre ambos servicios:
Esta gráfica de llamas combina interacciones de múltiples aplicaciones:
El primer tramo es una solicitud POST enviada por el usuario y gestionada por el enrutador chi a través de la biblioteca go-chi compatible.
El segundo tramo es una función createNote que fue rastreada manualmente por la función makeSpanMiddleware. La función creó un tramo a partir del contexto de la solicitud HTTP.
El siguiente tramo es la solicitud enviada por la aplicación de notas utilizando la biblioteca http compatible y el cliente inicializado en el archivo main.go. Esta solicitud GET se envía a la aplicación de calendario. Los tramos de la aplicación de calendario aparecen en azul porque son servicios independientes.
Dentro de la aplicación de calendario, un enrutador go-chi gestiona la solicitud GET y la función GetDate se rastrea manualmente con su propio tramo bajo la solicitud GET.
Por último, la llamada db púrpura es su propio servicio de la biblioteca sql compatible. Aparece en el mismo nivel que la solicitud GET /Calendar porque ambas son llamadas por el tramo primario CreateNote.
Cuando hayas terminado de explorar, limpia todos los recursos y elimina los despliegues:
terraform destroy
Solucionar problemas
Si no recibes trazas como esperabas, configura el modo de depuración para el trazador de Go. Lee Activar el modo de depuración para obtener más información.