Visualizando logs en Grafana
Los logs son algo muy importante para cualquier sysadmin, no son pocas las ocasiones en las que hay que revisarlos para buscar errores, comportamientos inesperados, intentos de acceso no autorizado, etc.
Cuando se manejan muchos servidores es conveniente tenerlos centralizados de alguna forma que nos permita desde un único punto poder visualizarlos y filtrar por algún criterio de búsqueda. Hay muchas opciones para realizar esta tarea, desde las clásicas, y aún muy usadas, como loganalyzer con rsyslog u otras más modernas como el stack ELK, en esta ocasión vamos a hablar de otro stack, compuesto por Grafana, Loki y Promtail.
Loki, es una herramienta relativamente joven, hace poco más de un año que salió de su estado Beta, pero con un desarrollo muy activo. Para quienes estén familiarizados con el uso de Grafana y Prometheus para realizar monitorización de métricas, se define como «Loki is like Prometheus, but for log».
Promtail, es el agente que se encarga de enviar los logs a Loki, y Grafana se va a encargar de visualizarlos y poder filtrar por algún criterio o por las etiquetas que definiremos.
Instalando Loki
Vamos a instalar Loki en la misma máquina donde ya tenemos instalado Grafana y Prometheus. Para ello ejecutamos:
1 2 3 4 5 6 7 8 |
useradd -r -s /usr/sbin/nologin loki wget https://github.com/grafana/loki/releases/download/v1.5.0/loki-linux-amd64.zip unzip loki-linux-amd64.zip mkdir /etc/loki mkdir /var/lib/loki cp loki-linux-amd64 /usr/local/bin/loki chown loki:loki /usr/local/bin/loki chown loki:loki /var/lib/loki -R |
Ahora creamos el fichero /etc/systemd/system/loki.service, con el siguiente contenido:
1 2 3 4 5 6 7 8 9 10 11 |
[Unit] Description=Loki Service After=network-online.target [Service] ExecStart=/usr/local/bin/loki --config.file=/etc/loki/loki-config.yaml User=loki Type=simple [Install] WantedBy=multi-user.target |
A continuación necesitamos crear el fichero de configuración /etc/loki/loki-config.yaml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
auth_enabled: false server: http_listen_port: 3100 ingester: lifecycler: address: 127.0.0.1 ring: kvstore: store: inmemory replication_factor: 1 final_sleep: 0s chunk_idle_period: 5m chunk_retain_period: 30s schema_config: configs: - from: 2020-06-28 store: boltdb object_store: filesystem schema: v9 index: prefix: index_ period: 168h storage_config: boltdb: directory: /var/lib/loki/index filesystem: directory: /var/lib/loki/chunks limits_config: enforce_metric_name: false reject_old_samples: true reject_old_samples_max_age: 168h chunk_store_config: max_look_back_period: 0s table_manager: chunk_tables_provisioning: inactive_read_throughput: 0 inactive_write_throughput: 0 provisioned_read_throughput: 0 provisioned_write_throughput: 0 index_tables_provisioning: inactive_read_throughput: 0 inactive_write_throughput: 0 provisioned_read_throughput: 0 provisioned_write_throughput: 0 retention_deletes_enabled: true retention_period: 672h |
Si queremos profundizar en las opciones de configuración podemos realizarlo aquí.
Ahora habilitamos el servicio, lo iniciamos y comprobamos que arranca correctamente:
1 2 3 |
systemctl enable loki systemctl start loki systemctl status loki |
Instalando Promtail
Como hemos indicando anteriormente promtail es el agente que se va a encargar de recoger los logs que le indiquemos en su configuración y los va a enviar a Loki. Para instalarlo:
1 2 3 4 5 6 7 |
useradd -r -s /usr/sbin/nologin promtail wget https://github.com/grafana/loki/releases/download/v1.5.0/promtail-linux-amd64.zip unzip promtail-linux-amd64.zip mkdir /etc/promtail mkdir /var/lib/promtail cp promtail-linux-amd64 /usr/local/bin/promtail chown promtail:promtail /usr/local/bin/promtail |
Ahora generamos el fichero de configuración /etc/promtail/promtail.yml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
server: http_listen_port: 9080 grpc_listen_port: 0 positions: filename: /tmp/positions.yaml clients: - url: http://pmm:3100/api/prom/push scrape_configs: - job_name: system static_configs: - targets: - localhost labels: host: pmm job: varlogs __path__: /var/log/*log - job_name: auth static_configs: - targets: - localhost labels: job: auth host: pmm __path__: /var/log/auth.log - job_name: grafana static_configs: - targets: - localhost labels: job: grafana_service host: pmm __path__: /var/log/grafana/*log |
En el que se definen 3 jobs (system, auth y grafana), cada uno de estos jobs se le pueden asignar tantas etiquetas como queramos, las etiquetas nos van a ayudar a agrupar y poder filtrar por ellas, es muy útil, por ejemplo, podemos tener los registros de acceso del fichero /var/log/auth.log, de todas nuestras máquinas con la etiqueta job: auth, lo que nos va a permitir agrupar todos estos registros de logs y hacer consultas conjuntas independientemente del host.
Ahora habilitamos el servicio para que arranque automáticamente, lo inciamos y comprobamos que arranca correctamente:
1 2 3 |
systemctl enable promtail systemctl start promtail systemctl status promtail |
Ahora nuestros logs ya están llegando a Loki.
Integrándolo en Grafana
Lo primero que debemos de hacer es agregar la fuente de datos Loki en Grafana:
Una vez agregada, pinchamos en el menú de la izquierda Explore, y seleccionamos la fuente de datos Loki.
Ya podemos seleccionar las etiquetas por las que queremos filtrar, de las que hemos definido o realizar consultas en el selector de flujos de logs. Loki utiliza LogQL, un lenguaje propio para consultar los logs. Junto con los resultados nos aparecen las métricas con el número de líneas de logs en cada instante de tiempo.
De esta forma se puede establecer búsquedas en los logs, por el nombre de archivo o por cualquiera de las etiquetas que hemos asignado y filtrar en su contenido con alguno de los siguientes criterios:
- |= líneas que contienen esa cadena
- != líneas que NO contienen esa cadena.
- |~ lineas que coinciden con una expresión regular.
- !~ lineas que NO coinciden con una expresión regular
Ejemplos de búsqueda:
Buscamos en un fichero, líneas que no contengan una respuesta 200 de apache:
1 |
{filename="/var/log/httpd/access_log", host="frontal01"} != "HTTP/1.1\" 200" |
Buscamos en los logs de mysql de cualquier host errores distintos a «timeout»:
1 |
{job="mysql"} |= "error" != "timeout" |
Es muy flexible y las combinaciones son muy variadas.
Otro aspecto a destacar es al creación de paneles personalizados de logs, con lo que podemos tener, además de las métricas de algún servicio, un panel a su lado con los logs de ese servicio.
Algo que se echa en falta es la integración con Alertmanager para poder notificarnos cuando aparezca algún error en alguno de los logs, segúna alguna condición que inquemos, aunque parece que en un futuro muy cercano será una realiadad: GrafanaCONline.
Deja una respuesta