Dominá la observabilidad de tus contenedores: Guía práctica de 'docker logs' y 'docker stats'

DUGLAS MORENODUGLAS MORENO 👁 21

Si alguna vez te pasó de que un contenedor se queda "colgado", se reinicia sin aviso o, peor aún, tu aplicación empezó a consumir toda la RAM de tu servidor, sabés de lo que hablo. En el mundo de Docker, no podés estar adivinando qué está pasando adentro de cada proceso. Necesitás visibilidad.

En este artículo, vamos a dejar de lado las conjeturas y vamos a aprender a usar dos herramientas fundamentales que ya tenés instaladas pero que quizás no estás aprovechando al máximo: docker logs para entender el flujo de eventos y docker stats para monitorear la salud de tus recursos en tiempo real. Este post es para desarrolladores, DevOps y cualquier persona que quiera dejar de pelearse con los contenedores y empezar a gestionarlos como un profesional.

El arte de investigar: Todo sobre docker logs

Cuando una aplicación falla, lo primero que querés saber es qué escribió en la consola justo antes de morir. Docker captura todo lo que se envía a la salida estándar (stdout) y a la salida de errores (stderr) de los procesos principales del contenedor. Esto es oro puro.

Uso básico de logs

El comando más simple es el que todos conocemos. Si tenés un contenedor corriendo (supongamos que se llama mi-api), simplemente ejecutás:

docker logs mi-api

Esto te va a volcar todo el historial de logs acumulado hasta el momento. Si el contenedor tiene mucho movimiento, esto puede ser un caos de texto difícil de leer.

El poder del --follow (o -f)

Si estás debugeando un error que ocurre bajo ciertas condiciones, no querés pedirle a Docker que te tire todo el historial cada cinco minutos. Querés ver lo que está pasando ahora mismo. Para eso usamos el flag -f:

docker logs -f mi-api

Esto mantiene la conexión abierta y te va mostrando las nuevas líneas a medida que aparecen, muy parecido a lo que hace el comando tail -f en Linux. Es ideal para ver el flujo de peticiones HTTP o los errores de conexión a la base de datos en vivo.

Filtrando por tiempo: No te ahogues en un mar de datos

Uno de los errores más comunes es intentar leer logs de hace tres días para entender un error que ocurrió hace cinco minutos. Docker te permite filtrar por tiempo usando --since y --until.

Si querés ver qué pasó en la última media hora, podés usar:

docker logs --since 30m mi-api

O si preferís un formato más específico de fecha y hora:

# Ver logs desde las 14:00 de hoy
docker logs --since "2023-10-27T14:00:00" mi-api

Limitando las líneas con --tail

Si solo querés ver las últimas 20 líneas para tener un poco de contexto antes de empezar a seguir el log en vivo, combinamos --tail con -f:

docker logs --tail 20 -f mi-api

Salida esperada de un ejemplo de servidor web:

[2023-10-27 10:00:01] INFO: Server started on port 8080
[2023-10-27 10:05:12] INFO: GET /api/users 200 OK
[2023-10-27 10:05:15] ERROR: Connection timeout to database
[2023-10-27 10:05:15] DEBUG: Retrying connection (1/3)...

Monitoreo de recursos con docker stats

Si docker logs es tu herramienta de diagnóstico de software, docker stats es tu herramienta de diagnóstico de hardware (o de límites de recursos). ¿Tu contenedor está consumiendo 2GB de RAM cuando debería usar 512MB? ¿El CPU está al 100% constantemente?

La vista en tiempo real

Al ejecutar docker stats, Docker te presenta una tabla dinámica que se actualiza cada segundo. Es como el "Administrador de Tareas" o el "Monitor de Actividad", pero para tus contenedores.

docker stats

Salida esperada y qué significa cada columna:

CONTAINER ID   NAME          CPU %     MEM USAGE / LIMIT     MEM %     NET I/O           BLOCK I/O         PIDS
a1b2c3d4e5f6   mi-api        0.45%     150MiB / 7.78GiB    1.92%     1.2kB / 0B        0B / 0B           12
z9y8x7w6v5u4   db-postgres   2.10%     450MiB / 7.78GiB    5.78%     5.4kB / 12kB      128kB / 0B        8
  1. CPU %: El porcentaje de la capacidad de un núcleo de CPU que el contenedor está usando. Ojo: si tenés 4 núcleos, el valor puede llegar hasta el 400%.
  2. MEM USAGE / LIMIT: Cuánta memoria está usando actualmente comparado con el límite total del host (o el límite que le hayas asignado al contenedor).
  3. MEM %: El porcentaje de uso de memoria respecto al límite.
  4. NET I/O: El tráfico de red entrante y saliente. Crucial para detectar ataques de denegación de servicio (DoS) o transferencias masivas de datos inesperadas.
  5. BLOCK I/O: Lectura y escritura en el disco. Si este número sube sin parar, podés tener un problema de indexación en la base de datos o un proceso escribiendo logs de forma descontrolada.
  6. PIDS: Cantidad de procesos/hilos que están corriendo dentro del contenedor. Un número que crece indefinidamente puede indicar un process leak.

Monitorear un solo contenedor

No siempre necesitás ver la lista completa. Si ya sabés que el culpable es mi-api, podés limpiar el ruido ejecutando:

docker stats mi-api

Buenas prácticas y errores comunes

Para que no te lleves sorpresas en producción, tené en cuenta estos consejos:

1. No dejes los logs crecer infinitamente

Por defecto, Docker guarda los logs en archivos JSON en el disco del host. Si tu aplicación escribe muchísimos logs y no configurás una rotación, te vas a quedar sin espacio en disco.

Recomendación: Configurá la rotación de logs en tu daemon.json de Docker o mediante el archivo docker-compose.yml:

services:
  mi-api:
    image: mi-api:latest
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

2. Cuidado con el consumo de CPU en docker stats

Si ves que un contenedor tiene un uso de CPU muy alto pero el NET I/O es bajo, buscá procesos de computación intensiva o bucles infinitos en tu código. Si el BLOCK I/O es alto, revisá tus consultas a la base de datos.

3. Logs estructurados

Si vas a usar herramientas de agregación de logs (como ELK Stack o Loki) en el futuro, tratá de que tu aplicación escriba logs en formato JSON. Esto hace que sea muchísimo más fácil filtrar y buscar datos después.

Conclusión

Dominar docker logs y docker stats te saca del grupo de los que "apagan y prenden el contenedor para ver si funciona" y te mete en el grupo de los que realmente entienden qué está pasando en su infraestructura.

En resumen:

  • Usá docker logs -f --tail N para seguir el rastro de errores en vivo.
  • Usá docker logs --since para investigar incidentes pasados sin saturar la terminal.
  • Usá docker stats para vigilar la salud de la CPU, Memoria y Red.

La próxima vez que algo falle, no entres en pánico. Abrí la terminal, ejecutá estos comandos y dejá que los datos te cuenten la historia de lo que está pasando.

Comentarios (0)

Sé el primero en comentar.

Dejá tu comentario