<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Grafana on Fcch Blog | Apuntes, guías y recordatorios</title><link>https://blog.fcch.xyz/tags/grafana/</link><description>Recent content in Grafana on Fcch Blog | Apuntes, guías y recordatorios</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><copyright>Fcch Technology Blog</copyright><lastBuildDate>Thu, 17 Sep 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.fcch.xyz/tags/grafana/index.xml" rel="self" type="application/rss+xml"/><item><title>Apuntes monitoreo con Grafana, Loki y Promtail</title><link>https://blog.fcch.xyz/post/infrastructure/grafana-monitoring-stack/</link><pubDate>Thu, 17 Sep 2026 00:00:00 +0000</pubDate><guid>https://blog.fcch.xyz/post/infrastructure/grafana-monitoring-stack/</guid><description>
&lt;p&gt;A lo largo de la vida profesional es normal ver muchos tipos de implementaciones en cuanto a desarrollo e infraestructura, en pocas palabras para infraestructura es normal que no exista monitoreo de servicios en servidores de alguna organización, esto es más común en servidores on-premise, por este motivo me hice algunas preguntas.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.fcch.xyz/images/grafana-stack/grafana-stack-logo.png" alt=""&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;¿Cuánto tiempo toma armar un sistema de monitoreo?&lt;/li&gt;
&lt;li&gt;¿Qué tan complicado puede ser implementar un sistema de monitoreo?&lt;/li&gt;
&lt;li&gt;¿Qué capacidades de cómputo necesito para tener un sistema de monitoreo?&lt;/li&gt;
&lt;li&gt;¿Cuántos sistemas de monitoreo existen y puedo utilizar?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Para este artículo hice una prueba de concepto aprovechando una rebaja en servidores VPS de &lt;a href="https://contabo.com/en/"&gt;&lt;strong&gt;CONTABO&lt;/strong&gt;&lt;/a&gt;, armamos infraestructura simple, instalamos algunos honeypots para obtener datos, generamos tráfico para obtener métricas y crear gráficas.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left"&gt;Servidor&lt;/th&gt;
&lt;th style="text-align: left"&gt;Característica&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;CPU&lt;/td&gt;
&lt;td style="text-align: left"&gt;AMD 4 Cores&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;RAM&lt;/td&gt;
&lt;td style="text-align: left"&gt;8GB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;SSD&lt;/td&gt;
&lt;td style="text-align: left"&gt;150 GB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;OS&lt;/td&gt;
&lt;td style="text-align: left"&gt;Debian Trixie 13&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="por-qué-tenemos-que-monitorear"&gt;¿Por qué tenemos que monitorear?&lt;/h2&gt;
&lt;p&gt;Tenemos que monitorear porque necesitamos enterarnos de lo que sucede en nuestra infraestructura antes de que los problemas aparezcan, los reclamos lleguen y existan incidentes de seguridad, monitorear nos permite:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Detectar ataques en curso&lt;/strong&gt;, desde ataques de fuerza bruta, escaneos de puertos, IPs maliciosas.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Identificar problemas antes de que escalen&lt;/strong&gt;, errores 5xx en servidores web, certificados SSL a punto de vencer, servicios caídos.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Entender el comportamiento del servidor&lt;/strong&gt;, tráfico y demanda de red, patrones de uso, dominios más consultados.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tener evidencia para tomar decisiones&lt;/strong&gt;, datos reales sobre qué está pasando, no suposiciones.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Responder más rápido ante incidentes&lt;/strong&gt;, con dashboards centralizados la información está a un vistazo.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Muchas veces se piensa que armar un sistema de monitoreo trata de un sistema complejo que necesita de hardware especializado, licencias de uso para el software y conocimientos avanzados de seguridad, pero la idea es tener lo mínimo necesario para no estar a ciegas (para infraestructuras pequeñas).&lt;/p&gt;
&lt;h2 id="sistemas-de-monitoreo"&gt;Sistemas de monitoreo&lt;/h2&gt;
&lt;p&gt;Existen diferentes tipos de sistemas de monitoreo, algunos de propósito general, otros con propósito específico:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.zabbix.com/"&gt;&lt;strong&gt;Zabbix&lt;/strong&gt;&lt;/a&gt;, plataforma de monitoreo de infraestructura que permite supervisar servidores, redes, aplicaciones, bases de datos y servicios. Utiliza agentes, SNMP y otros protocolos para recopilar métricas y generar alertas.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.nagios.org/"&gt;&lt;strong&gt;Nagios&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;- &lt;a href="https://icinga.com/"&gt;Icinga&lt;/a&gt;&lt;/strong&gt;, soluciones de monitorización de infraestructura y servicios. Permiten verificar disponibilidad, estado y rendimiento mediante plugins. Icinga nació como un fork de Nagios y mantiene compatibilidad con gran parte de su ecosistema.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pandorafms.com/"&gt;&lt;strong&gt;PandoraFMS&lt;/strong&gt;&lt;/a&gt;, plataforma de monitorización integral para infraestructura, redes, servidores, aplicaciones y servicios. Permite recopilar métricas, generar alertas, visualizar estados y realizar monitorización tanto local como remota.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://grafana.com/docs/grafana/latest/"&gt;&lt;strong&gt;Grafana&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;- &lt;a href="https://grafana.com/docs/loki/latest/"&gt;Loki&lt;/a&gt; - &lt;a href="https://grafana.com/docs/loki/latest/send-data/promtail/"&gt;Promtail&lt;/a&gt;&lt;/strong&gt;, stack orientado principalmente a observabilidad y gestión de logs. &lt;strong&gt;Grafana&lt;/strong&gt; proporciona dashboards con visualización, &lt;strong&gt;Loki&lt;/strong&gt; almacena y consulta logs, &lt;strong&gt;Promtail&lt;/strong&gt; recopila y envía los logs hacia &lt;strong&gt;Loki&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://wazuh.com/"&gt;&lt;strong&gt;Wazuh&lt;/strong&gt;&lt;/a&gt;, permite monitorizar endpoints, analizar logs, detectar amenazas, realizar análisis de vulnerabilidades, file integrity monitoring (FIM) y generar alertas de seguridad.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.elastic.co/elastic-stack"&gt;&lt;strong&gt;ELK Stack&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;(Elasticsearch, Kibana, Beats y Logstash)&lt;/strong&gt;, plataforma de gestión y análisis de logs y datos. Elasticsearch almacena e indexa datos, Logstash realiza ingesta y transformación, Beats recopila información desde sistemas y servicios, y Kibana proporciona visualización, dashboards y análisis.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;No queremos alargar este artículo, el monitoreo simple que haremos será con &lt;a href="https://grafana.com/docs/grafana/latest/"&gt;Grafana&lt;/a&gt; &lt;strong&gt;-&lt;/strong&gt; &lt;a href="https://grafana.com/docs/loki/latest/"&gt;Loki&lt;/a&gt; &lt;strong&gt;-&lt;/strong&gt; &lt;a href="https://grafana.com/docs/loki/latest/send-data/promtail/"&gt;Promtail&lt;/a&gt;, con datos de los registros de sistema, utilizando agentes con acceso a los datos de los servicios que queremos monitorear.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Nota importante:&lt;/strong&gt; Actualmente, &lt;strong&gt;Promtail&lt;/strong&gt; está en proceso de reemplazo dentro del ecosistema Grafana por &lt;a href="https://grafana.com/docs/alloy/latest/"&gt;Grafana Alloy&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="grafana---loki---promtail"&gt;Grafana - Loki - Promtail&lt;/h2&gt;
&lt;p&gt;La solución se compone de tres herramientas del ecosistema de &lt;a href="https://grafana.com/"&gt;Grafana&lt;/a&gt;, todas de código abierto:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left"&gt;Componente&lt;/th&gt;
&lt;th style="text-align: left"&gt;Función&lt;/th&gt;
&lt;th style="text-align: left"&gt;Puerto&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;&lt;strong&gt;Promtail&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;Agente que recolecta logs del sistema y los envía a Loki&lt;/td&gt;
&lt;td style="text-align: left"&gt;9080&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;&lt;strong&gt;Loki&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;Motor de almacenamiento e indexación de logs&lt;/td&gt;
&lt;td style="text-align: left"&gt;3100&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;&lt;strong&gt;Grafana&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;Interfaz web para visualización y dashboards&lt;/td&gt;
&lt;td style="text-align: left"&gt;3000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;El flujo es simple: &lt;strong&gt;Promtail&lt;/strong&gt; lee los archivos de log y el journal de systemd, los envía a &lt;strong&gt;Loki&lt;/strong&gt; que los almacena e indexa, y &lt;strong&gt;Grafana&lt;/strong&gt; consulta a Loki para mostrar la información en dashboards.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.fcch.xyz/images/grafana-stack/grafana-loki-promtail-workflow.png" alt=""&gt;&lt;/p&gt;
&lt;h3 id="por-qué-solo-grafana---loki---promtail"&gt;¿Por qué solo Grafana - Loki - Promtail?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;No requiere agentes de métricas adicionales&lt;/strong&gt;, toda la información proviene de logs que ya existen en el servidor.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bajo consumo de recursos&lt;/strong&gt;, Loki no indexa el contenido completo de los logs, solo los labels, lo que lo hace mucho más ligero que Elasticsearch.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Instalación simple&lt;/strong&gt;, los tres componentes se instalan desde el repositorio oficial de Grafana con &lt;code&gt;apt&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LogQL&lt;/strong&gt;, el lenguaje de consultas de Loki es potente y permite extraer métricas directamente de los logs.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="qué-vamos-a-monitorear"&gt;¿Qué vamos a monitorear?&lt;/h3&gt;
&lt;p&gt;Nuestra prueba solo va a monitorear servicios como SSH, Nginx, Fail2ban y Docker.&lt;/p&gt;
&lt;h3 id="1-ssh"&gt;1. &lt;a href="https://www.openssh.org/"&gt;SSH&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Muchos conocemos SSH, nos permite conectar de forma remota a un servidor que tiene instalado este servicio, el puerto por defecto es el 22. Monitorear este servicio es muy importante porque permite detectar:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Intentos de login fallidos&lt;/strong&gt;, fuerza bruta.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Logins exitosos&lt;/strong&gt;, verificar que solo acceden usuarios autorizados.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;IPs de origen&lt;/strong&gt;, de cada intento.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Usuarios probados&lt;/strong&gt;, por atacantes.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://blog.fcch.xyz/images/grafana-stack/grafana-ssh-dashboard.png" alt=""&gt;&lt;/p&gt;
&lt;h3 id="2-nginx"&gt;2. &lt;a href="https://nginx.org/en/docs/index.html"&gt;Nginx&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Para servidores web lo mínimo que conviene monitorear es el tráfico:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Requests por segundo/minuto&lt;/strong&gt;, detectar alta o baja demanda de tráfico.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Códigos de estado HTTP&lt;/strong&gt;, cuántos errores 4xx y 5xx se están produciendo.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Top IPs&lt;/strong&gt;, identificar quién está generando más tráfico.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Top URLs&lt;/strong&gt;, qué recursos son los más solicitados.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Error logs&lt;/strong&gt;, visualizar errores del servidor en tiempo real.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://blog.fcch.xyz/images/grafana-stack/grafana-nginx-dashboard-v2.png" alt=""&gt;&lt;/p&gt;
&lt;h3 id="3-fail2ban"&gt;3. &lt;a href="https://fail2ban.readthedocs.io/en/latest/"&gt;Fail2ban&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Protección contra ataques de fuerza bruta, complementa el monitoreo mostrando las acciones de defensa automática:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;IPs baneadas&lt;/strong&gt;, quién fue bloqueado y cuándo.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;IPs detectadas&lt;/strong&gt;, intentos sospechosos antes del baneo.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tendencias&lt;/strong&gt;, si los ataques están aumentando o disminuyendo.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://blog.fcch.xyz/images/grafana-stack/grafana-fail2ban-dashboard-v1.png" alt=""&gt;&lt;/p&gt;
&lt;h3 id="4-docker"&gt;4. &lt;a href="https://www.docker.com/"&gt;Docker&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Para un monitoreo de contenedores simple, podemos pedirle a docker que escriba sus registros de sistema en journal de systemd, con una configuración no muy compleja podremos monitorear los contenedores, códigos de estado, volúmenes.&lt;/p&gt;
&lt;p&gt;Por defecto el &lt;strong&gt;Logging Driver&lt;/strong&gt; de Docker está configurado para &amp;quot;&lt;strong&gt;json-file&lt;/strong&gt;&amp;quot;, esta configuración debe estar con &amp;quot;&lt;strong&gt;journald&lt;/strong&gt;&amp;quot;, se puede verificar con algunos comandos.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Ver el driver de logs activo&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;docker info --format &lt;span class="s1"&gt;&amp;#39;{{.LoggingDriver}}&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Ver si ya existe el archivo de config del daemon&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;sudo cat /etc/docker/daemon.json 2&amp;gt;/dev/null &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;No existe daemon.json todavía&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Comúnmente el archivo &amp;quot;&lt;strong&gt;daemon.json&lt;/strong&gt;&amp;quot;, si es necesario se debe crear.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo tee /etc/docker/daemon.json &amp;gt; /dev/null &lt;span class="s"&gt;&amp;lt;&amp;lt;&amp;#39;EOF&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; &amp;#34;log-driver&amp;#34;: &amp;#34;journald&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;EOF&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Si el archivo ya existe con otros datos, no se debe sobrescribir, se debe editar el contenido en base al comando anterior. Ruta del archivo a editar &lt;strong&gt;/etc/docker/daemon.json&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Recomendable validar si el JSON es correcto.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo python3 -c &lt;span class="s2"&gt;&amp;#34;import json; json.load(open(&amp;#39;/etc/docker/daemon.json&amp;#39;)); print(&amp;#39;JSON válido&amp;#39;)&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Aplicando cambios y verificando los datos:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo systemctl restart docker
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;docker info --format &lt;span class="s1"&gt;&amp;#39;{{.LoggingDriver}}&amp;#39;&lt;/span&gt; &lt;span class="c1"&gt;# Salida: &amp;#34;journald&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Nota importante:&lt;/strong&gt; El driver de registro de sistema se asigna al crear contenedores, es posible que se deba recrear contenedores existentes para que se creen con el nuevo driver.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Para un contenedor suelto&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;docker stop &amp;lt;nombre&amp;gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; docker rm &amp;lt;nombre&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# y volver a lanzarlo&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Si usas docker compose&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;docker compose up -d --force-recreate
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Por último se deben verificar los cambios:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;docker inspect --format &lt;span class="s1"&gt;&amp;#39;{{.HostConfig.LogConfig.Type}}&amp;#39;&lt;/span&gt; &amp;lt;nombre_o_id&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Con estos detalles podemos crear un dashboard para contenedores también.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.fcch.xyz/images/grafana-stack/grafana-docker-dashboard-v1.png" alt=""&gt;&lt;/p&gt;
&lt;h2 id="instalación-de-grafana-y-sus-componentes"&gt;Instalación de Grafana y sus componentes&lt;/h2&gt;
&lt;p&gt;Los tres componentes se instalan desde el repositorio oficial de Grafana mediante &lt;code&gt;apt&lt;/code&gt; en Debian. Los paquetes &lt;code&gt;.deb&lt;/code&gt; ya incluyen los archivos de unidad para systemd.&lt;/p&gt;
&lt;h3 id="repositorio-de-grafana"&gt;Repositorio de Grafana&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo apt install -y apt-transport-https wget gnupg
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo mkdir -p /etc/apt/keyrings
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;sudo wget -O /etc/apt/keyrings/grafana.asc https://apt.grafana.com/gpg-full.key
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;sudo chmod &lt;span class="m"&gt;644&lt;/span&gt; /etc/apt/keyrings/grafana.asc
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Crear el archivo &lt;code&gt;/etc/apt/sources.list.d/grafana.sources&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;X-Repolib-Name: grafana
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;Types: deb
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;Components: main
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;Suites: stable
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;URIs: https://apt.grafana.com
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;Signed-By: /etc/apt/keyrings/grafana.asc
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;Enabled: yes
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Actualizamos e instalamos los paquetes:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo apt update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo apt install -y grafana loki promtail
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="archivos-de-configuración"&gt;Archivos de configuración&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Grafana&lt;/strong&gt;, archivo de configuración en &lt;code&gt;/etc/grafana/grafana.ini&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Loki&lt;/strong&gt;, archivo de configuración en &lt;code&gt;/etc/loki/config.yml&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Promtail&lt;/strong&gt;, archivo de configuración en &lt;code&gt;/etc/promtail/config.yml&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="crear-directorios-de-datos-para-loki"&gt;Crear directorios de datos para Loki&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo mkdir -p /var/lib/loki/&lt;span class="o"&gt;{&lt;/span&gt;chunks,rules,compactor&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo chown -R loki:loki /var/lib/loki
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="habilitar-e-iniciar-servicios"&gt;Habilitar e iniciar servicios&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;sudo systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; grafana-server loki promtail
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;sudo systemctl start grafana-server loki promtail
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="configuración-adicional-para-loki"&gt;Configuración adicional para Loki&lt;/h2&gt;
&lt;p&gt;La configuración de Loki define cómo se almacenan e indexan los registros de sistema.&lt;/p&gt;
&lt;p&gt;Puntos importantes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Retención de 7 días&lt;/strong&gt; (&lt;code&gt;168h&lt;/code&gt;): suficiente para un servidor personal y no consume demasiado disco.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Esquema v13 con TSDB&lt;/strong&gt;, el formato más reciente y eficiente para indexación.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Almacenamiento en filesystem&lt;/strong&gt;: ideal para un solo servidor, sin necesidad de almacenamiento distribuido.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Telemetría deshabilitada&lt;/strong&gt;, no envía datos de uso a Grafana Labs.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="configuración-de-promtail"&gt;Configuración de Promtail&lt;/h2&gt;
&lt;p&gt;Promtail es el agente que recolecta los registros de sistema, su configuración define qué archivos leer y cómo procesarlos.&lt;br&gt;
La sección &lt;code&gt;scrape_configs&lt;/code&gt; define los jobs de recolección, cada job apunta a una fuente de registro de sistema y asigna labels que permiten filtrar en Grafana:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left"&gt;Job&lt;/th&gt;
&lt;th style="text-align: left"&gt;Fuente&lt;/th&gt;
&lt;th style="text-align: left"&gt;Labels clave&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;journal&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;code&gt;/var/log/journal&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;code&gt;unit&lt;/code&gt;, &lt;code&gt;host&lt;/code&gt;, &lt;code&gt;level&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;nginx-*-access&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;code&gt;/var/log/nginx/*-access.log&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;code&gt;domain&lt;/code&gt;, &lt;code&gt;log_type=access&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;nginx-*-error&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;code&gt;/var/log/nginx/*-error.log&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;code&gt;domain&lt;/code&gt;, &lt;code&gt;log_type=error&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;fail2ban&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;code&gt;/var/log/fail2ban.log&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;code&gt;service=fail2ban&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;Nota importante:&lt;/strong&gt; Debian 13 (Trixie) ya no incluye &lt;code&gt;rsyslog&lt;/code&gt; por defecto. No existe &lt;code&gt;/var/log/syslog&lt;/code&gt; ni &lt;code&gt;/var/log/messages&lt;/code&gt;. Todos los logs del sistema se gestionan a través de systemd-journald, por eso se usa el scraper de tipo &lt;code&gt;journal&lt;/code&gt; en Promtail para leer logs de SSH y otras unidades systemd.&lt;/p&gt;
&lt;h2 id="verificación-del-stack"&gt;Verificación del stack&lt;/h2&gt;
&lt;p&gt;Una vez instalado y configurado, se puede verificar que todo funciona correctamente:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;curl http://localhost:3000/login
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="dashboards-del-proyecto"&gt;Dashboards del proyecto&lt;/h2&gt;
&lt;p&gt;El proyecto incluye dashboards listos para importar:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Login Users&lt;/strong&gt;: seguridad SSH con paneles de logins exitosos, fallidos, top IPs atacantes y usuarios probados.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Web Server&lt;/strong&gt;: monitoreo completo de Nginx y Fail2ban con requests por segundo, códigos de estado HTTP, top URLs, top IPs y error logs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Registry Health&lt;/strong&gt;: disponibilidad de providers del Terraform Registry (usando datasource Infinity).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://blog.fcch.xyz/images/grafana-stack/grafana-status-services-dashboard.png" alt=""&gt;&lt;/p&gt;
&lt;h2 id="escalando-a-múltiples-servidores"&gt;Escalando a múltiples servidores&lt;/h2&gt;
&lt;p&gt;Esta misma solución se puede escalar para monitorear múltiples servidores instalando solo Promtail en cada servidor remoto y apuntándolo al Loki central.&lt;/p&gt;
&lt;p&gt;Solo hay que cambiar &lt;code&gt;instance_addr&lt;/code&gt; de &lt;code&gt;127.0.0.1&lt;/code&gt; a &lt;code&gt;0.0.0.0&lt;/code&gt; en Loki y proteger el acceso con firewall.&lt;/p&gt;
&lt;h2 id="conclusión"&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;No hace falta una infraestructura compleja para tener visibilidad sobre lo que pasa en un servidor. Con Grafana, Loki y Promtail se puede implementar un sistema de monitoreo basado en logs que cubre lo esencial: seguridad de acceso, tráfico web, protección contra ataques y estado de certificados.&lt;/p&gt;
&lt;p&gt;Lo importante es empezar con lo mínimo. Un dashboard con intentos de SSH fallidos y errores de Nginx ya es infinitamente mejor que no tener nada.&lt;/p&gt;
&lt;p&gt;¿Cuánto tiempo nos tomó? Puedo decir que me tomó más tiempo crear el artículo que desplegar todo lo necesario:&lt;/p&gt;
&lt;p&gt;Instalación y configuración del servidor, con Ansible 20 minutos, ya tenía un proyecto con todo lo necesario, el sistema de monitoreo fueron como 5 horas y un poco más, ya que no conocíamos la herramienta, tocó leer, probar y preguntar a la IA también.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Nota importante:&lt;/strong&gt; Este artículo se hizo largo, en otro dejaré las configuraciones de cada servicio incluyendo la configuración del reverse proxy de Nginx para tener más detalle de cada configuración.&lt;/p&gt;
&lt;h2 id="referencias"&gt;Referencias&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://grafana.com/"&gt;Grafana&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://grafana.com/docs/loki/latest/"&gt;Loki - Documentación Oficial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://grafana.com/docs/loki/latest/send-data/promtail/"&gt;Promtail - Documentación Oficial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://grafana.com/docs/loki/latest/query/"&gt;LogQL - Lenguaje de Consultas de Loki&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>