Skip to main content

Logging

Loki este un sistem de agregare de log-uri scalabil, creat de cei de la Grafana și inspirat de Prometheus. Mai concret, este un fel de Prometheus pentru log-uri, gândit să fie eficient și ușor de utilizat, folosind DynamoDB pentru indexare și S3 pentru stocare. Loki nu indexează textul log-urilor, ci grupează log-urile în stream-uri și le indexează astfel, împărțind query-urile în bucăți mici și realizându-le în paralel.

Ca funcționalitate, Loki colectează log-uri de la mai mulți clienți (cum ar fi Promtail, Logstash, driver-ul de Docker, etc.), le indexează, și apoi le exportă către alte servicii precum Grafana sau AlertManager. În cadrul acestui laborator, vom folosi un driver Docker de logging custom pentru Loki, care se instalează în felul următor:

$ docker plugin install grafana/loki-docker-driver:latest --alias loki --grant-all-permissions
$ docker plugin ls

ID NAME DESCRIPTION ENABLED
6a20054403a8 loki:latest Loki Logging Driver true

Odată instalat driver-ul, acesta poate fi folosit la pornirea unui container sau a unui serviciu (fie din linia de comandă, fie dintr-un fișier Docker Compose) pentru a redirecționa log-urile acestuia către Loki. Pe lângă această modificare pe care trebuie să o facem deployment-ului unei aplicații, este nevoie să adăugăm serviciul de Loki (care rulează pe portul implicit 3100) și serviciul de Grafana (vom intra mai târziu în detalii despre Grafana, dar momentan ne este necesar pentru a putea vizualiza datele colectate de Loki). Ajungem astfel la următorul fișier Docker Compose, pe care îl puteți găsi în repository-ul Docker:

prometheus-nexporter-cadvisor-testapp-loki-stack.yml
version: "3.8"

services:
prometheus:
image: prom/prometheus
volumes:
- ../configs/prometheus/prometheus-nexporter-cadvisor-testapp.yml:/etc/prometheus/prometheus.yml
ports:
- 9090:9090
networks:
- monitoring
- visualizing

node_exporter:
image: prom/node-exporter
deploy:
mode: global
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
command:
- '--path.procfs=/host/proc'
- '--path.rootfs=/rootfs'
- '--path.sysfs=/host/sys'
- '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)'
ports:
- 9100:9100
networks:
- monitoring

cadvisor:
image: gcr.io/cadvisor/cadvisor
deploy:
mode: global
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
- /dev/disk:/dev/disk/:ro
ports:
- 8080:8080
networks:
- monitoring

testapp:
image: mobylab/idp-laborator4-testapp
logging:
driver: loki
options:
loki-url: http://host.docker.internal:3100/loki/api/v1/push
loki-external-labels: job=myjob,owner=radu,environment=development
ports:
- 8000:8000
- 5000:5000
networks:
- monitoring
- logging

loki:
image: grafana/loki
volumes:
- ../configs/loki/loki.yml:/etc/config/loki.yml
- ../configs/loki/wal:/wal
entrypoint:
- /usr/bin/loki
- -config.file=/etc/config/loki.yml
ports:
- 3100:3100
networks:
- logging
- visualizing

grafana:
image: grafana/grafana
volumes:
- grafana-volume:/var/lib/grafana
ports:
- 3000:3000
depends_on:
- loki
deploy:
placement:
constraints: [node.role == manager]
networks:
- visualizing

networks:
monitoring:
logging:
visualizing:

volumes:
grafana-volume:

Se poate observa adăugarea atributului logging pentru aplicația noastră, pe care am pus-o într-o rețea comună cu Loki. De asemenea, pentru partea de vizualizare a log-urilor, Loki este în aceeași rețea cu Grafana. De asemenea, se mai observă că Loki are nevoie de un fișier YAML de configurare. Puteți vedea un exemplu mai jos (care se găsește și în directorul loki din repository-ul Configs):

loki.yml
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: 2024-02-01
store: boltdb
object_store: filesystem
schema: v11
index:
prefix: index_
period: 168h

storage_config:
boltdb:
directory: /tmp/loki/index

filesystem:
directory: /tmp/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: 0

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: false
retention_period: 0

frontend:
address: 127.0.0.1
caution

Atenție la data pe care o selectați la atributul schema_config și la perioada de indexare. Dacă perioadă de indexare nu este valabilă, nu veți putea vedea log-urile.

Se observă deci că nu trebuie modificat nimic în codul aplicației ale cărei log-uri dorim să le preluam, ci doar în Docker Compose. Odată ce facem deployment-ul, putem vizualiza log-urile preluate și agregate de Loki cu ajutorul Grafana. Grafana este o suită open source de analiză și vizualizare de metrici (precum și alertare), care are suport pentru un număr mare de surse de date, printre care și Loki sau Prometheus.

Odată ce serviciul de Grafana este pornit, putem accesa dashboard-ul său la http://IP:3000/. Este nevoie întâi să ne logăm (credențialele implicite sunt admin / admin), după care putem adăuga o sursă nouă de date selectând opțiunea Add your first data source de pe ecranul principal. Ca tip de sursă de date, se selectează Loki, după care se introduce URL-ul http://loki:3100 și se salvează. În acest moment, dacă intrăm pe http://IP:3000/explore, putem observa sursa de log-uri Loki și putem să selectăm în funcție de label-uri. Odată selectat un label, se pot vedea (în timp real sau pe o perioadă determinată) log-urile dorite, așa cum se observă în imaginea de mai jos.

img