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:
lokique almacena de manera centralizada los logs de diferentes máquinas y permite la consulta de esos datos con LogQL.promtailinstalado en cada uno de los ordenadores que enviarán datos aloki. Puede enviar los ficheros de registro ojournal.grafanapara 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/lokipara 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
nodenameyunitcon los valores que nos interesan. - Acepta líneas que contengan '
client @'. - Descarta líneas que contengan '
denied' o 'query failed'. - Utiliza el parser
patternpara extraer el valor de los campos:client,clientport,query,type,extrayserver. - 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:




