Introducción a la monitorización con Grafana y Loki
Grafana Loki es un agregador de logs eficiente, escalable y con el que es muy sencillo trabajar.
Se inspira en Prometheus pero en lugar de guardar métricas guarda mensajes de log (o de systemd-journald
). Y a diferencia de otras soluciones (como OpenSearch) no indexa el contenido de cada mensaje sino únicamente sus metadatos con unas etiquetas idénticas a las que se utilizan en Prometheus.
Así no se requiere mucha CPU al ingerir los datos y dado que los datos se guardan comprimidos ocupan mucho menos espacio que al utilizar systemd-journald
(que no es que sea especialmente eficiente al utilizar el espacio de disco).
Cuando se desea consultar información Loki puede procesar con gran velocidad los datos seleccionados para presentar los resultados.
La pila estará compuesta por:
loki
que almacena de manera centralizada los logs de diferentes máquinas y permite la consulta de esos datos con LogQL.promtail
instalado en cada uno de los ordenadores que enviarán datos aloki
. Puede enviar los ficheros de registro ojournal
.grafana
para explorar y visualizar los datos.
Instalación básica de loki
Los desarrolladores proporcionan binarios y paquetes para las principales distribuciones. En el momento de escribir esta introducción la última versión publicada es 2.9.2
así que podremos descargar el paquete loki_2.9.2_amd64.deb
.
Por ejemplo, utilizando un contenedor LXD podremos instalar la aplicación:
root@loki:~# wget https://github.com/grafana/loki/releases/download/v2.9.2/loki_2.9.2_amd64.deb root@loki:~# apt install ./loki_2.9.2_amd64.deb
Y modificar el fichero de configuración /etc/loki/config.yml
para que:
- Se utilice el directorio
/var/loki
para guardar los datos. - Se utilice TSDB para guardar la información en lugar del formato anterior (
boltdb-shipper
). - El periodo de retención de datos sea de 30 días.
- Se utilicen hasta 4 CPUs y se incrementan algunos límites.
Así la configuración que utilizamos en el centro es:
auth_enabled: false server: http_listen_port: 3100 grpc_listen_port: 9096 # No queremos tantos mensajes log_level: warn common: instance_addr: 127.0.0.1 path_prefix: /var/loki storage: filesystem: chunks_directory: /var/loki/chunks rules_directory: /var/loki/rules replication_factor: 1 ring: kvstore: store: inmemory compactor: working_directory: /var/loki/retention shared_store: filesystem compaction_interval: 10m retention_enabled: true retention_delete_delay: 2h retention_delete_worker_count: 150 schema_config: configs: - from: "2023-11-20" index: period: 24h prefix: index_ object_store: filesystem schema: v12 store: tsdb query_scheduler: # the TSDB index dispatches many more, but each individually smaller, requests. # We increase the pending request queue sizes to compensate. max_outstanding_requests_per_tenant: 32768 querier: # Each `querier` component process runs a number of parallel workers to process queries simultaneously. # You may want to adjust this up or down depending on your resource usage # (more available cpu and memory can tolerate higher values and vice versa), # but we find the most success running at around `16` with tsdb max_concurrent: 16 ruler: alertmanager_url: http://localhost:9093 # By default, Loki will send anonymous, but uniquely-identifiable usage and configuration # analytics to Grafana Labs. These statistics are sent to https://stats.grafana.org/ # # Statistics help us better understand how Loki is used, and they show us performance # levels for most users. This helps us prioritize features and documentation. # For more information on what's sent, look at # https://github.com/grafana/loki/blob/main/pkg/usagestats/stats.go # Refer to the buildReport method to see what goes into a report. # # If you would like to disable reporting, uncomment the following lines: #analytics: # reporting_enabled: false # Ver: https://github.com/grafana/loki/issues/5123 # frontend: max_outstanding_per_tenant: 4096 # Ver: https://community.grafana.com/t/maximum-of-series-500-reached-for-a-single-query/64117/4 # limits_config: max_query_series: 10000 max_query_parallelism: 4 retention_period: 30d
Loki guarda los datos comprimidos con muchísima más eficiencia que systemd-journald
. Así que puede resultar recomendable reducir en /etc/systemd/journald.conf
el valor por defecto de SystemMaxUse
(que en Ubuntu son 4GB) en todas aquellas máquinas que estén utilizando promtail
para enviar los datos a Loki.
El despliegue del centro está guardando los journald
de unos pocos servidores. El servidor que más volumen de información registra es un gateway
que tiene activo el registro de consultas de bind9
y en una hora punta puede generar aproximadamente 1GiB de datos de journald
por hora.
Sin embargo los datos de todo un mes para ese servidor y otros pocos que registran un menor volumen de información en Loki consumen aproximadamente 1.6GB.Y estos datos se pueden guardar en disco (como estamos haciendo nosotros) o enviar a un object storage
como MinIO (o algún servicio cloud) para conseguir mayores capacidades.
Instalación de promtail
La instalación de promtail
se puede hacer a partir de los paquetes proporcionados en cada lanzamiento. Bastará con descargar e instalar la última versión disponible.
wget https://github.com/grafana/loki/releases/download/v2.9.2/promtail_2.9.2_amd64.deb apt install ./promtail_2.9.2_amd64.deb
Pero después será necesario editar /etc/group
y añadir el usuario promtail
al grupo adm
para que gane acceso a los ficheros de registro y a journal
.
vcarceler@cirdan-2204:~$ cat /etc/group | grep adm
adm:x:4:syslog,vcarceler,promtail
vcarceler@cirdan-2204:~$
Para enviar los ficheros de registro /var/log/*log
a Loki (que está en 192.168.0.24
) se puede utilizar la siguiente configuración:
server: http_listen_port: 9080 grpc_listen_port: 0 positions: filename: /tmp/positions.yaml clients: - url: http://192.168.0.24:3100/loki/api/v1/push scrape_configs: - job_name: system static_configs: - targets: - localhost labels: job: varlogs __path__: /var/log/*log
Y para enviar los datos de systemd-journald
la configuración que utilizamos es:
server: http_listen_port: 9080 grpc_listen_port: 0 positions: filename: /tmp/positions.yaml clients: - url: http://192.168.0.24:3100/loki/api/v1/push scrape_configs: - job_name: journal journal: max_age: 12h path: /var/log/journal labels: job: systemd-journal relabel_configs: - source_labels: ['__journal__systemd_unit'] target_label: 'unit' - source_labels: - __journal__hostname target_label: nodename
Al configurar promtail
para enviar journal
a Loki de esta manera se añaden automáticamente las etiquetas nodename
y unit
para clasificar los datos por máquina y servicio.
Consultas desde Grafana
Finalmente podremos acceder a Grafana (la instalación es muy sencilla) para representar nuestros datos.
Después podremos explorar los registros seleccionando las etiquetas que queramos. Por ejemplo: nodename
y unit
.
Debajo de la representación temporal de las entradas de log podremos encontrar los datos:
A partir de aquí se podrán utilizar todas las funciones de LogQL para consultar la información que nos interese. Filtrando líneas que contengan (o no contengan) lo que nos interese, extrayendo campos (con los parsers JSON
,logfmt
, pattern
o regular expression
) y aplicando metric queries
para generar métricas a partir de las líneas de log.
Por ejemplo, sabiendo que BIND9 registra las consultas de los clientes con el siguiente formato:
client @0x7f7c7cc06c68 192.168.21.63#44327 (pool.ntp.org): query: pool.ntp.org IN A + (192.168.21.10)
La siguiente consulta:
topk(25, sum by(client) (count_over_time({nodename="$nodename", unit="named.service"}
|= `client @`
!= `denied`
!= `query failed`
| pattern `client @<_> <client>#<clientport> (<query>): query: <_> IN <type> +<extra> (<server>)` | __error__="" [$__range])))
- Selecciona el stream que tiene las etiquetas
nodename
yunit
con los valores que nos interesan. - Acepta líneas que contengan '
client @
'. - Descarta líneas que contengan '
denied
' o 'query failed
'. - Utiliza el parser
pattern
para extraer el valor de los campos:client
,clientport
,query
,type
,extra
yserver
. - Cuenta las líneas haciendo una suma para cada valor de
client
(la IP del ordenador que consulta al DNS). - Retornando los 25 ordenadores que han hecho más consultas.
Lo que permite representar el siguiente panel con una visualización pie chart:
Y así podremos componer el dashboard que muestre la información que nos sea útil, como el que hemos hecho para mostrar información sobre las consultas que recibe nuestro DNS (dashboard disponible en: https://grafana.com/grafana/dashboards/20079-loki-bind9/).
Más información: