La pile Applications : ucalls, eBPF, etc.
Pour commencer, nous allons partir du plus haut niveau, où l'on trouve généralement les applications fortement imbriquées avec la couche de bibliothèques :
Chaque application possède son propre système métrique et surtout, les moyens nécessaires de remonter les statistiques ainsi que l’état de performance de son sous-système. Il s’agit le plus souvent d’un journal de traces ou d’un élément de référence, que l’on peut comparer à un état courant. Nous verrons qu’il existe également un ensemble de fonctions appelé eBPF utilisant les appels intégrés du noyau linux et qui s’appuie sur les fonctionnalités telles que :
- javacalls
- pythonscalls
- rubycalls
- phpcalls
- ucalls
Ces outils permettent de lier entre eux les mécanismes embarqués de type USDT (User-level Statically Defined Tracing), au sein de nombreux langages évolués tels que Java, Python, Ruby ou encore Php. Cela permet de créer une liste sommaire des appels effectués, au sein de ces langages. Ils sont adossés le plus souvent à un runtime imbriqué dans ces mêmes outils. Ceux-ci sont construits depuis le code source, lors de la phase d’édition de liens et marqués d’un flag labellisé USDT spécifique comme :
- --enable-dtrace
- --with-dtrace
REMARQUE : dans le cas de Java, la méthode de "sommarisation" décrite ci-dessus pour les autres langages, n’est pas activée par défaut. Elle peut être mise en œuvre lors de l’exécution du processus java, en utilisant alors l’option -XX: +ExtendedTraceProbes.
Par ailleurs, dès lors que l’on utilise les fonctionnalités eBPF (aussi appelées BCC), seul l’utilisateur root peut travailler à l’aide de ces outils.
Exemple : tracer les dix premiers appels système Ruby, on exécutera :
# ucalls -l ruby 1344 -T 10
On retrouve nombre de ces outils à différents niveaux du système d’exploitation, comme on aura l’occasion de le voir par la suite. Les outils eBPF (extended Berkeley Packet Filter), sont intégrés au sein des noyaux linux des machines virtuelles et peuvent être utiliser pour tracer l’activité interne du système. Il existe également quelques autres programmes ou fonctions construit sur la couche eBPF.
Ces outils permettent aux programmeurs d’écrire du code s’exécutant dans l’espace du noyau, au sein d’un environnement mieux sécurisé et plus restrictif. D’ailleurs, cet environnement leur permet également de créer des outils qui, d’ordinaire, nécessiteraient d’écrire un nouveau module noyau.
eBPF n’est disponible que depuis la version RHEL 7.6 (noyau 3.10.0-940.el7.x86_64), et qui n’a pour but que les opérations de traces, autorisant alors les programmes eBPF à qualifier, à journaliser et à quantifier les événements ainsi récupérés. Ces fonctions introduisent de nouveaux appels système appelés alors bpf et favorisant les opérations telles que chargement de programmes, liens de ceux-ci avec certains événements système et activation d’une cartographie eBPF, au sein du noyau linux. Grâce à ces programmes on peut facilement décrire la méthode d’accès depuis ces outils.
En résumé, les outils eBPF sont accessibles à partir du moment où l’on installe le package bcc-tools.
# yum -y install bcc-tools
Ils permettent, via des fonctions dédiées, de tracer directement les évènements spécifiques que représentent les appels système.
Exemple : tracer tous les signaux kill envoyés par les processus s’exécutant sur notre serveur :
# /usr/share/bcc/tools/killsnoop TIME PID COMM SIG TPID RESULT 10:25:23 25423. Bash 15. 25425. 0
Dans la mesure où beaucoup d’outils aujourd’hui sont écrits en langage évolués, on peut également trouver également des outils propres aux bases de données, associés à la couche eBPF et permettant de vérifier l’état d’une file d’attente interne : mysqld_qslower. Ici, il s’agit d’un script Python favorisant la création de listes et s’intéressant particulièrement aux files d’attente plus lentes selon un certain seuil passé en paramètre.
Exemple : tracer les requêtes MySQL plus lente qu’une ms (valeur par défaut), pour le processus n°2503 :
# mysqld_qslower 2503
REMARQUE : ce mécanisme utilise aussi eBPF/BCC et si l’on souhaite fixer un seuil différent et supérieur à 1ms (par défaut), il suffit de passer la valeur souhaitée en second paramètre :
# mysqld_qslower 2503 10
Il faut bien sûr que le serveur sur lequel on exécute cette commande dispose d’un serveur MySQL/MariaDB. Par ailleurs, il ne faut pas non plus négliger les journaux de traces de la base de données en question. Ceux-ci apportent le plus souvent beaucoup plus d’indications que l’on ne pense : l’instance est-elle opérationnelle ? Est-celle mise en archivage automatique ou non ?...