URL:     https://linuxfr.org/news/loki-centralisation-de-log-a-la-sauce-prometheus
Title:   Loki, centralisation de log à la sauce Prometheus
Authors: yannig
        ZeroHeure, BAud, palm123, Nils Ratusznik, tisaac et Ysabeau
Date:    2019-08-06T12:09:16+02:00
License: CC by-sa
Tags:    loki, grafana et prometheus
Score:   6


Cet article est une rapide introduction à Loki. Ce projet est [soutenu par Grafana](https://grafana.com/oss/loki/) et a pour but de centraliser des journaux d’activités (serveurs ou containers).


![logo de Loki](https://grafana.com/static/img/docs/logos/icon_loki.svg)
La source principale d’inspiration de Loki vient de Prometheus, avec l'idée de l’appliquer à la gestion des logs, le but étant de disposer du même mécanisme :

- utilisation des labels pour le stockage des données ;
- réclamer très peu de ressources pour son exécution.



Dans ce qui va suivre, nous allons revenir sur le principe de fonctionnement de Prometheus et donner quelques exemples d’utilisation dans le cadre d’un déploiement sous Kubernetes.

----

[Découverte de l’outil de supervision Prometheus](https://linuxfr.org/news/decouverte-de-l-outil-de-supervision-prometheus)
[Loki. Prometheus-inspired logging for cloud natives.](https://grafana.com/oss/loki)
[Loki: Prometheus-inspired, open source logging for cloud natives](https://grafana.com/blog/2018/12/12/loki-prometheus-inspired-open-source-logging-for-cloud-natives/)
[FOSDEM 2019 - Loki: Prometheus for logs](https://archive.fosdem.org/2019/schedule/event/loki_prometheus_for_logs/)

----

Un mot sur Prometheus
---------------------



Afin de bien comprendre le fonctionnement de Loki, il est important de comprendre celui de Prometheus. Le lecteur est invité à lire une publication précédente dans ces colonnes : [Découverte de l’outil de supervision Prometheus](https://linuxfr.org/news/decouverte-de-l-outil-de-supervision-prometheus). Même si le produit a évolué entretemps (la version 2.0.0 venait de sortir), ce qui est écrit reste tout à fait valable avec la dernière version (2.14).

La caractéristique de ce produit est de récupérer des métriques en provenance de points de collecte (on parle d’exporteur) et de les stocker dans une base de données de type [_Time Series_](https://en.wikipedia.org/wiki/Time_series_database) en y ajoutant des métadonnées sous forme de labels.



Origine du besoin
-----------------



Ces derniers temps, Prometheus est devenu un standard de fait dans le monde de Kubernetes : son installation est très simple à réaliser et l’ensemble des briques d’un cluster Kube dispose nativement d’un _endpoint_ Prometheus. Le moteur Prometheus est également en mesure de récupérer des métriques en provenance des applications déployées dans ce type de cluster tout en reprenant les labels définis. La surveillance des consommations applicatives est donc très simple à mettre en oeuvre.



Malheureusement, du côté des logs, il n’y a pas encore de méthode clé en main et l’utilisateur doit trouver sa propre solution :



- un service géré de centralisation des logs dans le cloud (AWS, Azure ou Google) ;
- un service de _monitoring as a service_ (type Datadog) ;
- la mise en place d’un service de centralisation.


Au niveau de la troisième solution, votre serviteur avait traditionnellement l’habitude de mettre en place Elasticsearch, avec de nombreuses réserves à propos de ce produit notamment sur sa lourdeur et la difficulté de sa mise en place.



Loki a justement été conçu dans le but de simplifier cette mise en place en répondant aux critères suivants :



- être un produit simple à démarrer ;
- consommer peu de ressources ;
- fonctionner tout seul sans intervention de maintenance particulière ;
- servir de support à l’investigation en complément de Prometheus en cas de pépin.



En revanche, cette légèreté se fait au prix de certains compromis. L’un d’eux est de ne faire aucune indexation du contenu. La recherche de texte n’est donc de ce point de vue pas très performante ni très riche et ne permet pas de faire des statistiques sur le contenu du texte. Mais comme Loki se veut être un équivalent de grep et doit servir de complément à Prometheus, ce défaut n’en est pas un.



Méthode de résolution d’incidents
---------------------------------



Pour mieux comprendre en quoi Loki n’a pas besoin d’indexation, nous allons revenir sur la méthode utilisée par les concepteurs de Loki avec le schéma suivant :
1- Alert → 2- Dashboard → 3 Adhoc Query → 4 Log Aggregation → 5 Distributed Tracing → 6 Fix!


![Méthode de résolution d’incidents](https://grafana.com/static/assets/img/blog/image9.png)


L'idée est de partir d'une source d'alerte (notification Slack, SMS, etc.). La personne en charge du suivi fait alors la démarche suivante :

- consultation des tableaux de bords Grafana ;
- consultation des métriques brutes (dans Prometheus par exemple) ;
- consultation des logs (Elasticsearch par exemple) ;
- éventuellement, consultation des traces distribuées (Jaeger, Zipkin, etc.) ;
- enfin, correction du dysfonctionnement.



Ici, dans le cas d’un empilement (stack) Grafana + Prometheus + Elasticsearch + Zipkin, l’utilisateur devra changer quatre fois d’outils. Afin de réduire les temps d’intervention, l’idée est de tout faire avec un seul outil : Grafana. À noter que Grafana propose cette notion d’exploration depuis la version 6. Il devient ainsi possible de consulter les données brutes de Prometheus directement depuis Grafana.

Depuis cet écran il est possible de consulter les logs de Loki associés aux métriques de Prometheus notamment en faisant appel à la notion de découpage de l’écran. On imagine très bien qu’une fois que Loki aura été correctement intégré dans Grafana, la suite des travaux se fera sûrement sur l’intégration de Grafana et des outils de traces distribuées.



Test de Loki en local
---------------------



Le plus simple pour tester Loki en local est de passer par Docker et l’outil docker-compose.



Le fichier docker-compose se trouve sur le dépôt de Loki. La récupération du contenu de ce dépôt se fait à l’aide de la commande git suivante :


```sh
git clone https://github.com/grafana/loki.git
```





Reste ensuite à se rendre dans le répertoire production :



```sh
cd production
```





De là, il est possible de récupérer la dernière version des images Docker :



```sh
docker-compose pull
```





Enfin, la stack de Loki se lance à l'aide de la commande suivante :



```sh
docker-compose up
```





Architecture de Loki
--------------------



Un petit dessin valant toujours mieux qu’un long discours, ci-dessous un petit schéma de principe de Loki :



![Architecture de Loki](https://grafana.com/static/assets/img/blog/image1.png)
_Un client web fait tourner des applications sur le serveur, Promtail en collecte les logs qu'il envoie à Loki, le client web envoie aussi des méta+données à Loki. Loki agrège le tout et transmet à Grafana._

Loki est démarré. Afin de consulter les composants présents, lancez la commande suivante :



```sh
docker ps
```





Dans le cas d’un démon Docker fraîchement installé, la commande doit alors renvoyer la sortie suivante :



```
.. IMAGE            ... PORTS                           NAMES
.. grafana/promtail:...                                 production_promtail_1
.. grafana/grafana:m... 0.0.0.0:3000->3000/tcp          production_grafana_1
.. grafana/loki:late... 80/tcp, 0.0.0.0:3100->3100/tcp  production_loki_1
```





On retrouve les briques suivantes :



- Promtail : un agent qui prend en charge la centralisation des logs (Promtail, pour _Tailing logs in Prometheus format_) ;
- Grafana : le célèbre outil de mise en page des données ;
- Loki : le démon de centralisation des données.


Dans le cadre d’une installation sur infrastructure classique (à base de machine virtuelle par exemple), l’agent Promtail devra être déployé sur chaque machine. Grafana et Loki pourront être éventuellement installés sur la même machine.

Déploiement dans Kubernetes
---------------------------



L’installation des briques de Loki dans Kubernetes va s’appuyer sur les éléments suivants :



- un gestionnaire de démon (DaemonSet) pour déployer l’agent Promtail sur chacune des machines du cluster ;
- un déploiement (Deployment) pour déployer la partie Loki ;
- et un dernier déploiement pour Grafana.


Par chance, Loki est disponible sous forme de paquet Helm afin de simplifier son déploiement.



### Installation de Helm



Pour la suite, l’utilisateur devra disposer de la commande `helm`. Cette dernière se récupère sur [le dépôt GitHub](https://github.com/helm/helm/releases/tag/v2.16.1) du projet. Charge à l’utilisateur de décompresser l’archive correspondante à l’architecture du poste de l’utilisateur et de placer la commande `helm` dans $PATH.


NB : La version 3.0.0 de Helm vient juste de sortir. Étant donné qu’elle change beaucoup de choses, il est conseillé au lecteur d’attendre un peu avant de s’y mettre.


### Ajout de la source Helm



La première étape va consister à ajouter le dépôt « loki » à l’aide de la commande suivante :



   helm repo add loki https://grafana.github.io/loki/charts



Une fois cette commande lancée, il devient possible de chercher les paquets portant le nom loki :



   helm search loki



Ci-dessous un exemple de résultat renvoyé :



   loki/loki          0.17.2          v0.4.0          Loki: like Prometheus, but for logs.
   loki/loki-stack    0.19.1          v0.4.0          Loki: like Prometheus, but for logs.
   loki/fluent-bit    0.0.2           v0.0.1          Uses fluent-bit Loki go plugin for gathering logs and sen...
   loki/promtail      0.13.1          v0.4.0          Responsible for gathering logs and sending them to Loki



Ces paquets ont différentes fonctions :



- le paquet loki/loki correspond au serveur Loki seul ;
- le paquet loki/fluent-bit permet de déployer un DaemonSet s’appuyant sur fluent-bin pour centraliser les logs à la place de Promtail ;
- le paquet loki/promtail contenant l’agent de centralisation des journaux d’activités ;
- le paquet loki/loki-stack permettant de déployer Loki et Promtail en une seule fois.


### Déploiement de Loki



Afin de déployer Loki dans Kubernetes, dans l’espace de nom « monitoring », lancez la commande suivante :

   helm upgrade --install loki loki/loki-stack --namespace monitoring



Pour disposer d’un espace disque persistant, ajoutez l’option ``--set loki.persistence.enabled=true`` :



   helm upgrade --install loki loki/loki-stack --namespace monitoring --set loki.persistence.enabled=true



Remarque : dans le cas où vous souhaiteriez déployer grafana en même temps, ajouter l’option ``--set grafana.enabled=true``.


Au lancement de cette commande, l’utilisateur devrait obtenir la sortie suivante :



   LAST DEPLOYED: Tue Nov 19 15:56:54 2019
   NAMESPACE: monitoring
   STATUS: DEPLOYED

   RESOURCES:
   ==> v1/ClusterRole
   NAME                       AGE
   loki-promtail-clusterrole  189d

   ...

   NOTES:
   The Loki stack has been deployed to your cluster. Loki can now be added as a datasource in Grafana.

   See http://docs.grafana.org/features/datasources/loki/ for more detail.



Un coup d’œil sur l’état des _pods_ de l’espace de nom « monitoring » terminera de nous indiquer que tout est déployé :


   kubectl -n monitoring get pods -l release=loki



Ci-dessous un exemple de résultat renvoyé :



   NAME                  READY   STATUS    RESTARTS   AGE
   loki-0                1/1     Running   0          147m
   loki-promtail-9zjvc   1/1     Running   0          3h25m
   loki-promtail-f6brf   1/1     Running   0          11h
   loki-promtail-hdcj7   1/1     Running   0          3h23m
   loki-promtail-jbqhc   1/1     Running   0          11h
   loki-promtail-mj642   1/1     Running   0          62m
   loki-promtail-nm64g   1/1     Running   0          24m



Tous les _pods_ sont démarrés. Il est maintenant temps de faire quelques tests !


Connexion à Grafana
-------------------



Sous Kubernetes, afin de pouvoir se connecter à Grafana, il est nécessaire d’ouvrir un tunnel vers son pod. Ci-dessous la commande permettant d’ouvrir le port 3000 vers le pod de Grafana :


   kubectl -n monitoring port-forward svc/loki-grafana 3000:80



Autre point important, la nécessité de récupérer le mot de passe de l’administrateur de Grafana. Ce dernier est stocké dans le **secret** **loki-grafana** dans le champ **.data.admin-user** au format base64.



Afin de le récupérer, lancez la commande suivante :



   kubectl -n monitoring get secret loki-grafana --template '{{index .data "admin-password"|base64decode}}' ; echo



Utilisez ce mot de passe conjointement avec le compte d’administration par défaut (admin).



Définition datasource loki depuis Grafana
-----------------------------------------



Première chose à faire, s’assurer que le datasource de Loki est bien présent (se rendre à l’emplacement suivant : Configuration / Datasource).


Voici un exemple de définition valide :



![Exemple de définition du datasource vers Loki](https://1.bp.blogspot.com/-fhWhxBbgEhQ/Xd1EWPqHTGI/AAAAAAAAQfo/sYfgNOMAd3wzdY1BQN5YZlLArzCnjIGyQCLcBGAsYHQ/s1410/datasource-loki.png)



Un clic sur le bouton Test permettra de s’assurer que la communication avec Loki se passe bien.


Interrogation du moteur Loki
----------------------------



Rendez-vous maintenant dans le champ « Explorer » de Grafana. Au moment de l’ingestion des logs des containers, Loki se charge d’ajouter les annotations en provenance de Kubernetes. Il devient ainsi possible de s’en servir pour récupérer les logs d’un container spécifique.



Ainsi, pour sélectionner les logs des containers promtail, la requête à rentrer sera la suivante : `{container_name="promtail"}`. Pensez également à bien sélectionner la source de données de Loki.



Cette requête renverra alors l’activité de ces containers sous la forme suivante :



![Résultat requête dans Grafana](https://1.bp.blogspot.com/-WY2ACR_ok7Y/Xd13EABDlvI/AAAAAAAAQf0/abjmBFPtl882T5GHvEVdQQ9UbAYU_0FsgCLcBGAsYHQ/s1600/requ%25C3%25AAte-loki-grafana.png)



Inclusion dans un dashboard
---------------------------



Depuis la version 6.4 de Grafana, il est possible d’inclure un extrait des logs dans un tableau de bord Grafana. L’utilisateur peut alors rapidement mettre en parallèle les courbes de fréquentation de son site avec les traces renvoyées par son application.



Ci-dessous un exemple de tableau de bord réalisant ce mélange :



![Exemple de tableau de bord avec des métriques Prometheus et des logs en provenance de Loki](https://1.bp.blogspot.com/-eb5_K1m4Wo8/Xd2C0IPpy9I/AAAAAAAAQgA/2caijspE510VyAVvnvGKbs55OhdWwdaYQCLcBGAsYHQ/s1600/dashboard-grafana-prometheus-loki.png)



Futur de Loki
==============



Lorsque j’ai commencé à écrire cet article en août, la version 0.3 de Loki venait à peine de sortir. La sortie de la version 1.0 est en quelque sorte la raison qui m’a poussé à finir mon travail :)



J’ai commencé à l’utiliser à partir de la version 0.1 et il faut bien avouer qu’à l’époque la stabilité n’était pas encore au rendez-vous. Globalement, la version 0.3 a apporté de vrais signes de maturité et les versions suivantes (0.4 puis 1.0) n’ont fait que conforter cette impression.

Dorénavant avec la version 1.0.0, plus personne ne devrait avoir d’excuse pour ne pas utiliser cet excellent outil.



Les travaux les plus intéressants ne devraient plus avoir lieu sur Loki mais plus sur l’intégration avec l’excellent Grafana. En effet, la version 6.4 de Grafana a apporté une bonne intégration avec les tableaux de bords.


La version 6.5 qui vient juste de sortir améliore encore cette intégration en permettant de convertir automatiquement le contenu de la ligne de log lorsqu’elle est au format JSON.


Ci-dessous une petite vidéo présentant ce mécanisme :



![Utilisation du nouvel affichage des lignes de Loki dans Grafana](https://grafana.com/docs/img/docs/v65/explore_log_details.gif)



Il devient aussi possible d’utiliser un des champs de la structure JSON pour par exemple :



- pointer vers un outil externe ;
- filtrer le contenu des logs.


On peut alors cliquer sur le champ _traceId_ afin de pointer vers un tableau de bord de Zipkin ou Jaeger.