Archives de catégorie : Monitoring

Formation prometheus/grafana, promql suite

Lors de l’article précédent, nous avions découvert l’installation de la stack prometheus/grafana. Continuons pour découvrir aujourd’hui quelques rudiments du promql. Vous pouvez vous rendre sur cette page si vous souhaitez consulter toute cette formation prometheus/grafana gratuite.

Nous avions vu le principe de label dans prometheus à travers le langage promql. Ainsi, chaque ligne de métriques dispose d’autant de cardinalités qu’elles disposent de labels différents. Par exemple, si la métrique node_load_5 prend un label instance et un label datacenter, nous avons autant de cette métrique que d’instance pour l’ensemble des datacenters. C’est pourquoi certaines métriques peuvent être très lourdes en matière de traitement des métriques (des load-balancers par exemple). Et lorsque l’on utilise ces métriques il est nécessaires de les filtrer pour les exploiter.

Pour filtrer les métriques, il suffit de placer des requêtes sur les labels de la métrique en question. Par exemple sur le datacenter ou l’instance spécifiquement.

Ainsi on pourra utiliser des expressions régulières de cette manière :

node_network_receive_bytes_total{device=="eth0"}
node_network_receive_bytes_total{device=~"eth.+"}
node_network_receive_bytes_total{device=~"eth0|lo"}
node_network_receive_bytes_total{device!~"eth0|lo"}

Ainsi :

  • Le premier cas s’attache à une équivalence stricte.
  • Le second à une regex qui permettra de rappatrier toutes les métriques node_network_receive_bytes_total mais dont le label device commence par « eth » et est suivi d’au moins un caractère ou plus.
  • Le troisième dans le cas où pour la même métrique on souhaite rappartier soit les devices « eth0 » ou « lo ».
  • Enfin la différence en appliquant une regex.

D’autres opérations : le BY

Commençons par le regroupement grâce à l’opérateur « by » qui permet de faire l’équivalent de « GROUP BY » en SQL. Ainsi sur certaines fonctions comme les sommes, les comptages… vous pourrez regrouper ce calcul par un ou plusieurs labels. Par exemple pour compter le nombre de lignes de la métrique node_cpu_seconds_total par cpu, nous procéderons de la sorte :

count(node_cpu_seconds_total) by (cpu)

Ce qui nous permet, après avoir engendré un résultat d’une ligne par cpu, la possibilité de calculer le nombre de CPU :

count(count(node_cpu_seconds_total) by (cpu))

Et donc pour compter cela par serveur, il faudra ajouter le label « instance » à notre calcul

count(count(node_cpu_seconds_total) by (cpu,instance)) by (instance)

On compte donc dans un premier temps le nombre de ligne par cpu unqiuement pour regrouper cette métrique disposant de plusieurs lignes. Puis on compte le nombre de fois où l’on retrouve cette ligne regroupée pour avoir le nombre de cpu par instance.

Le facteur temps : offset et vector

Parmi les principaux éléments de temps importants dans prometheus, il en existe 2 :

  • le vector : c’est la plage de temps sur laquelle certains calculs vont être réalisés (une somme, une moyenne, une dérivée…)
  • l’offset : il s’agit du point de référence auquel vous souhaitez réaliser le calcul. Par exemple, il peut être intéressant de se placer 24h en arrière pour comparer avec les métriques actuelles…

Le range vector est intéressant pour les calculs mais aussi pour commencer pour voir le nombre de valeur sur lesquels on réalise un calcul. Ainsi si on passe un range vector de 3m à partir de maintenant sur une métrique on l’écrit comme ceci :

node_cpu_seconds_total[3m]

Cette requête va vous permettre d’afficher toutes les valeurs de la métrique node_cpu_seconds au cours de 3 dernières minutes. Plus le scrape est fréquent et plus vous avez de valeurs.

Les valeurs de cette requête sont classées par timestamp en format epoch. Vous pouvez néanmoins les convertir en format « humain » grâce à la commande date :

date -d "@1574340307.27"

Ainsi, pour calcculer une moyenne au cours des 3 dernières minutes, vous pouvez le faire de cette manière :

avg_over_time(node_cpu_seconds_total[3m])

Pour les offset, il suffit d’ajouter le mot offset. Prenons un exemple. Nous voulons comparer le nombre de requêtes actuelles avec celui d’il y a 5 minutes. Comme nous avons besoin de 2 courbes, nous allons faire deux requêtes.

La première qui collecte l’information sur le moment :

sum(http_requests_total)by (code)

Ensuite la seconde en demandant un offset placé 5 minutes en arrière :

sum(http_requests_total offset 5m)by (code)

Simple non ?

Les opérateurs

Dans les éléments simples à connaître pour débuter avec prometheus, il y a les opérateurs. Il s’agit de simple test conditionnels.

Par exemple, nous voulons savoir si une métrique est supérieur à 0.

Ainsi parmi les résultats, comme pour les labels, prometheus ne retournera que les métriques correspondantes. Et bien cûr cela peut se faire sur des résultats de fonctions (calculs).

Et on pourra aussi combiner les tests. Voici la liste des opérateurs promql disponibles :

    == (equal)
    != (not-equal)
    > (greater-than)
    < (less-than)
    >= (greater-or-equal)
    <= (less-or-equal)
    and (intersection)
    or (union)
    unless (complement)

Je vous propose un exemple simple :

node_load1 > 1.0 and node_load1<1.6

Dans ce cas nous retenons uniquement les métriques node_load inférieures à 1.6 et supérieure à 1.0. nous aurions aussi pu l’écrire de la manière suivante :

node_load1 > 1.0 <1.6

J’espère que cet article vous permettra de débuter le promql tranquillement et vous lèvera quelques doutes. N’hésitez pas à consulter les tutoriels prometheus/grafana sur la chaine xavki.

Débuter avec Prometheus et se former

Le monitoring est un domaine qui existe depuis de nombreuses années pour gérer les infrastructures. Il existait avant le web mais son intérêt c’est accru d’année en année. La tolérance aux pannes étant devenue de plus en plus faible, les outils de monitoring ont évolué également avec le temps.

L’arrivée des infrastructure à base de microservices et la nécessaité de baser le monitoring sur de plus en plus d’éléments « métiers » a aussi joué ces dernières années. Si le monitoring système était bien présent auparavant, la partie applicative est devenu un enjeu important pour toute société ayant le moindre site web ou même fournissant des services en interne.

Parfois, le monitoring système est même réduit au minimum au bénéfice du service rendu final.

Vous pouvez retrouver mes prises de notes sur Prometheus en plus des vidéos de la chaine sur ce dépôt gitlab.

Prometheus et Grafana, la stack du moment

La collecte et la mise en valeur de métriques passent souvent par la combinaison de plusieurs outils. Je vous propose de découvrir aujourd’hui une partie de la stack prometheus/grafana qui est l’une des plus à la mode en ce moment.

Pourquoi ? en grande partie par sa simplicité de mise en place et son déploiement. Prometheus constitue la base de données (timeseries). Il stocke les données sur de courtes périodes (son point faible reste la rétention sur des volumes importants). Attention, il reste très performant sur de longues périodes si vous ne collectez pas trop de métriques.

Sa force ? être capable d’aller chercher lui-même l’information sur les serveurs. Alors que de nombreux autres outils fonctionnent avec des agents qui envoient l’information vers la base centralisée, Prometheus va chercher l’information.

Attention, néanmoins, vous devez mettre en place ce que l’on appelle des exporters. Il s’agit de petits binaires, souvent développés en GO (mais vous pouvez aussi développer el votre en bash ou en python). Ces derniers affichent les informations sur une route à savoir un port et un path de la machine (par défaut on utilise couramment la route /mettrics). On parle là des données où les outils ne mettent pas déjà à disposition une route pour prometheus.

Car de nombreux outils mettent à dispositions des options pour mettre en place cette route. Les données, dans tous les cas, sont affichées au format openmetrics. Un standard, facile à scraper et à utiliser.

Prometheus est aussi souvent utiliser pour ses capacités d’autodiscovery notamment dans kubernetes ou docker mais pas seulement (consul, aws, dns…).

Comment installer Prometheus ?

Bien sûr vous pouvez retrouver la documentation de prometheus ici. Cette timeseries database est tellement courante que de nombreuses distributions vous la fournissent dans les dépôts standards. Par exemple sur les OS à base de Debian :

sudo apt-get install prometheus

Sinon, bien sûr, vous pouvez l’installer facilement avec l’aide de docker pour la lancer sous forme de conteneur :

docker run -d --name prometheus \
-v $PWD/etc/:/etc/prometheus/ \
 -v $PWD/data/:/prometheus/ \
-p 9090:9090 quay.io/prometheus/prometheus:v2.0.0

Attention néanmoins à ne pas oublier qu’il s’agit d’une application stateful et que du coup vous devrez stocker des éléments en dehors du conteneur en montant un volume. Ainsi comme dans l’exemple précédent, je vous invite à monter un volume pour la configuration et un autre pour les datas. Stocker sa configuration en dehors du conteneur vous permettra de facilement relancer un conteneur similaire avec les mêmes options.

Quelques défintions pour cette TSDB particulière

Comme tout outil, Prometheus dispose de son propre langage et ses propres notions et définitions.

Sa configuration est stockée dans un fichier (par défaut prometheus.yml) au format yaml.

./prometheus --config.file=prometheus.yml

Dans ce fichier de configuration on retrouver :

  • Une partie « global » qui définit des settings par défaut par exemple :
    • scrape_interval : fréquence de collecte des métriques
    • evaluation_interval : fréquence de check des alertes
    • scrape_timeout : durée d’attente des métriques (temps de réponse de la route)
  • rule files :volet relatif à la configuration des alertes
  • scrape config : éléments relatifs aux routes mise à disposition de prometheus :
    • dynamiques ou non
    • ip/url et port
    • nom du job de scrape

Et toutes les données sont donc exportées au format openmetrics :

up{instance="192.168.62.3:9100",job="node_exporter",service="myapp"} 1

Dans cet exemple, « up » est une métrique (notamment par défaut la route prometheus), 1 sa valeur.

On découvre également ce que l’on appelle des labels comme par exemple : instance, job, service. Mais bien sûr vous pouvez aussi créer vos propres labels.

L’outil n’est pas une simple database car il récupère lui-même ses informations et met également à votre disposition une interface graphique. Par défaut, affichée sur le port 9090, elle affiche :

  • la configuration pris en compte sur le moment
  • les routes collectées
  • la possibilié de requêter les données en utilisant le langage PromQL (prometheus query language)
  • la possibilité de réaliser des graphiques (un peu rudimentaires que l’on remplacera souvent par grafana).

Node Exporter : le plus courant

On l’a dit, notre TSDB va chercher elle même ses métriques. Soit sur des outils intégrés aux applicatifs soit par le biais d’exporter. Ces outils tournent au niveau local, collecte la données et l’expose sur un port et une route (souvent /metrics par défaut).

Node exporter est l’un des plus commun. en effet, il permet de collecter des informations de bases sur le système : les disques, leurs volumes, le réseau, les process…

Pour l’installer vous devez faire votre choix :

  • par un paquet de votre distribution
  • par un conteneur docker spécifique
  • par le binaire.

Ainsi sous debian vous pouvez l’installer avec :

sudo apt-get install prometheus-node-exporter

Avec docker :

docker run -d \
  --net="host" \
  --pid="host" \
  -v "/:/host:ro,rslave" \
  -p 9100:9100 \
  --name node_exporter \
  quay.io/prometheus/node-exporter \
  --path.rootfs=/host

Et pour le faire avec le binaire source :

  • récupérez le binaire et préparez les répertoires et user
sudo useradd -rs /bin/false node_exporter
https://prometheus.io/download/#node_exporter
wget https://github.com/prometheus/node_exporter/releases/download/v0.18.1/node_exporter-0.18.1.linux-amd64.tar.gz
tar -xvzf node_exporter-0.18.1.linux-amd64.tar.gz
mv node_exporter-0.18.1.linux-amd64/node_exporter /usr/local/bin/
chown node_exporter:node_exporter /usr/local/bin/node_exporter
  • créez le service systemd pour lancer le processus et le gérer
cat /etc/systemd/system/node-exporter.service
[Unit]
Description=Node Exporter
After=network-online.target
[Service]
User=node_exporter
Group=node_exporter
Type=simple
ExecStart=/usr/local/bin/node_exporter
[Install]
WantedBy=multi-user.target
  • puis activez le service systemd
systemctl daemon-reload
systemctl enable node_exporter
systemctl start node_exporter

Maintenant vous disposez de la route <ip>:9100/metrics sur la machine sur laquelle vous avez installé node exporter.

Il ne vous reste plus qu’à dire à prometheus de venir récupérer cette source d’informations. Bien sûr la machine prometheus doit pouvoir accéder à la route de node exporter. Ajoutez alors à votre configuration prometheus les lignes suivantes :

  - job_name: node-exporter
    static_configs:
      - targets: ['l<ip>:9100']

Labels et Filtres

Les labels et les filtres sont le quotidien de la personne qui utilise prometheus à travers les requêtes PromQL.

Les labels sont assimilables à des tags. C’est à dire une information que l’on va ajouter au fur et à mesure des scrape pour nous aider à isoler certaines données et les travailler plus facilement.

Ainsi, pour un scrape donnée (appelé aussi job), vous allez pouvoir ajouter un label nommé « environnement » :

  - job_name: node_exporter
      static_configs:
      - targets: [ '192.168.1.1:9100' ]
        labels:
          environnement: developpement

Dans le cas, d’utilisation d’autodiscovery, Prometheus autodécouvre des instances à monitorer et leurs informations (aws ec2 on retrouve les tags etc, les noms de services de consul etc). Et vous allez pouvoir ajouter ces informations complémentaires du discovery à votre liste de labels en utilisant le relabel.

scrape_configs:
  - job_name: Consul
    consul_sd_configs:
      - server: '192.168.57.10:8500'
        datacenter: 'mydc'
    relabel_configs:
      - source_labels: [__meta_consul_service]
        target_label: job

Dans cet exemple, l’information nom de service de consul vient compléter le label nommé « job ».

Les filtres permettent d’affiner les requêtes promql et limiter les résultats. Par exemple pour ne prendre en compte que le device eth0 :

node_network_receive_bytes_total{device="eth0"}

Le filtering se fait donc dans les labels mentionnés entre les accolades et la valeur mentionnées.

On peut également utiliser les regex pour plus de fléxibilités :

node_network_receive_bytes_total{device=~"eth.+"}
node_network_receive_bytes_total{device=~"eth0|lo"}

Voici donc la fin de ces premiers pas avec prometheus. Totu devops doit avoir quelques notions dans ce domaine. Je vous propose de retrouver les tutorials prometheus ici.