Este tutorial te guiará a través de los pasos necesarios para activar el rastreo en una aplicación Go de ejemplo instalada en un contenedor. En este escenario, el Datadog Agent también está instalado en un contenedor.
Para otros escenarios, incluyendo la aplicación y el Agent en un host, la aplicación y el Agent en la infraestructura en la nube y en aplicaciones escritas en otros lenguajes, consulta los otros tutoriales de activación de rastreo.
Consulta Rastreo de aplicaciones Go para obtener documentación general sobre la configuración del rastreo para Go.
El repositorio contiene una aplicación Go multiservicio preconfigurada para ejecutarse dentro de contenedores de Docker. La aplicación de ejemplo consiste en una aplicación básica de notas y una aplicación de calendario, cada una con una API REST para añadir y cambiar datos. Los archivos YAML docker-compose se encuentran en el directorio docker.
Este tutorial utiliza el archivo all-docker-compose.yaml, que crea contenedores para las aplicaciones de notas y calendario y el Datadog Agent.
Inicio y ejecución de la aplicación de ejemplo
Crea los contenedores de la aplicación ejecutando:
docker-compose -f all-docker-compose.yaml build
Inicia los contenedores:
docker-compose -f all-docker-compose.yaml up -d
Comprueba que los contenedores se están ejecutando con el comando docker ps. Deberías ver algo como esto:
ID DE CONTENEDOR IMAGEN COMANDO CREADO ESTADO PUERTOS NOMBRES
0a4704ebed09 docker-notes "./cmd/notes/notes" About a minute ago Up About a minute 0.0.0.0:8080->8080/tcp notes
9c428d7f7ad1 docker-calendar "./cmd/calendar/cale..." About a minute ago Up About a minute 0.0.0.0:9090->9090/tcp calendar
b2c2bafa6b36 gcr.io/datadoghq/agent:latest "/bin/entrypoint.sh" About a minute ago Up About a minute (unhealthy) 8125/udp, 8126/tcp datadog-ag
La aplicación de ejemplo notes es una API REST básica que almacena datos en una base de datos en memoria. Utiliza curl para enviar algunas solicitudes API:
curl localhost:8080/notes
devuelve [] porque todavía no hay nada en la base de datos
curl -X POST 'localhost:8080/notes?desc=hello'
añade una nota con la descripción hello y un valor de ID de 1. Devuelve {"id":1,"description":"hello"}
curl localhost:8080/notes/1
devuelve la nota con el valor id de 1: {"id":1,"description":"hello"}
curl -X POST 'localhost:8080/notes?desc=otherNote'
añade una nota con la descripción otherNote y un valor de ID de 2. Devuelve {"id":2,"description":"otherNote"}
curl localhost:8080/notes
devuelve el contenido de la base de datos: [{"id":1,"description":"hello"},{"id";2,"description":"otherNote"}]
Ejecuta más llamadas a la API para ver la aplicación en acción. Cuando hayas terminado, apaga y elimina los contenedores y asegúrate de que se han eliminado:
docker-compose -f all-docker-compose.yaml down
docker-compose -f all-docker-compose.yaml rm
Activación del rastreo
A continuación, configura la aplicación Go para habilitar el rastreo. Dado que el Agent se ejecuta en un contenedor, no es necesario instalar nada.
Para activar el rastreo, elimina los comentarios de las siguientes importaciones en apm-tutorial-golang/cmd/notes/main.go:
Elimina los comentarios de los campos depends_on para datadog-agent en el contenedor notes.
Fíjate que en la sección del servicio notes, la variable de entorno DD_AGENT_HOST se establece en el nombre de host del contenedor del Agent. Tu sección del contenedor notes tiene el siguiente aspecto:
Más adelante, configurarás las secciones y variables de calendar en este tutorial.
Inicio de los contenedores para explorar la instrumentación automática
Ahora que la biblioteca de rastreo está instalada, reinicia tus contenedores de aplicación e inicia para empezar a recibir trazas. Ejecuta los siguientes comandos:
docker-compose -f all-docker-compose.yaml build
docker-compose -f all-docker-compose.yaml up -d
Para empezar a generar y recopilar trazas, inicia de nuevo la aplicación con make run.
Para saber si el Agent está funcionando, observa los resultados continuos en el terminal, o abre el Events Explorer en Datadog y observa el evento de inicio del Agent:
Utiliza curl para volver a enviar solicitudes a la aplicación:
curl localhost:8080/notes
[]
curl -X POST 'localhost:8080/notes?desc=hello'
{"id":1,"description":"hello"}
curl localhost:8080/notes/1
{"id":1,"description":"hello"}
curl localhost:8080/notes
[{"id":1,"description":"hello"}]
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 de trazas, haz clic en una traza POST /notes para ver una gráfica de llamas 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 de la gráfica es el tramo seleccionado 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:
Una traza GET /notes tiene este aspecto:
Configuración del rastreo
Puedes configurar la biblioteca de rastreo para añadir etiquetas a la telemetría que envía a Datadog. Las etiquetas ayudan a agrupar, filtrar y mostrar datos de forma significativa en dashboards y gráficos. Para añadir etiquetas, especifica las variables de entorno al ejecutar la aplicación. El proyecto Makefile incluye las variables de entorno DD_ENV , DD_SERVICE y DD_VERSION, que están configuradas para activar el etiquetado de servicios unificado:
Datadog dispone de varias bibliotecas completamente compatibles para Go que permiten el rastreo automático cuando se implementan en el código. En el archivo cmd/notes/main.go, puedes ver que las bibliotecas go-chi, sql y http tienen alias según las correspondientes bibliotecas de Datadog: chitracesqltrace y httptrace respectivamente:
En cmd/notes/main.go, las bibliotecas de Datadog se inicializan con la opción WithServiceName. Por ejemplo, la biblioteca chitrace se inicializa de la siguiente manera:
El uso de chitrace.WithServiceName("notes") garantiza que todos los elementos rastreados por la biblioteca estén bajo el nombre de servicio notes.
El archivo main.go contiene más ejemplos de aplicación para cada una de estas bibliotecas. Para ver una extensa lista de bibliotecas, consulta Requisitos de compatibilidad de Go.
Uso del rastreo personalizado con contexto
En los casos en que el código no esté incluido en una biblioteca compatible, puedes crear tramos manualmente.
Elimina los comentarios de la función makeSpanMiddleware en notes/notesController.go. Genera un middleware que engloba una solicitud en un tramo con el nombre suministrado. Para utilizar este función, comenta 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
Elimina los comentarios de las siguientes líneas:
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"
Hay varios ejemplos de rastreo personalizado en la aplicación de ejemplo. Aquí hay un par de ejemplos más. Elimina los comentarios para habilitar estos tramos:
La función doLongRunningProcess crea tramos secundarios a partir de un contexto primario:
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:
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")}
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.
Para activar el seguimiento en la aplicación de calendario:
Elimina los comentarios de las siguientes líneas en cmd/calendar/main.go:
Abre docker/all-docker-compose.yaml y elimina los comentarios del servicio calendar para configurar el host de Agent y el etiquetado de servicios unificado para la aplicación y para Docker:
En la sección del servicio notes, elimina los comentarios de la variable de entorno CALENDAR_HOST y la entrada calendar en depends_on para establecer las conexiones necesarias entre las dos aplicaciones. Tu servicio de notas debería tener este aspecto:
En el Trace Explorer, haz clic en esta última traza notes 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.
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.