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
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.