Aller au contenu principal

Introduction

Quels sont les outils pour comprendre ce qui se passe sur un serveur qui “semble” lent? Pour répondre, voici une liste des principaux outils en ligne de commande pour diagnostiquer un serveur GNU/Linux.

Escargot géant africain (Achatina fulica)

Cette liste est extraite d’un article écrit par Brendan D. Gregg paru sur le blog technique de Netflix. Contrairement à l’article original je ne présenterai pas uptime (qui donne la charge moyenne pendant la dernière minute écoulée, ainsi que celle des 5 et des 15 dernières minutes), top , ou dmesg | tail, pour me concentrer uniquement sur des outils moins connus.

Liste des outils

vmstat 1

vmstat affiche des informations sur l’état de la mémoire. vmstat 1 ajoute en plus une ligne de mise à jour de ces informations toutes les secondes.

procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 2  0 3504512 743984 1847300 4610056    3   10  1538  2221   20   20 31 17 51  1  0
 0  0 3504512 736676 1847316 4616228    0    0     0    17 1884 4703  4  3 93  0  0
 1  0 3504512 728116 1847320 4624320    2    0     2    90 1433 3385  3  2 94  0  0
 0  0 3504512 734148 1847332 4616124    0    0     3   125 1451 3574  4  2 94  0  0
 2  0 3504512 733700 1847336 4616124    0    0     0     5 1443 3480  4  2 94  0  0

Les colonnes à surveiller:

  • r: nombre de processus en cours (running) ou en attente;
  • free: mémoire disponible en kilobytes;
  • si et so: swap in et swap out.
  • us, sy, id, wa, et st: moyenne sur l’ensemble des processeurs des valeurs suivantes
    • user time
    • system time
    • idle
    • wait
    • stolen time

À noter que la première ligne affiche les valeurs moyennes depuis le démarrage de la machine. D’ailleurs vmstat (sans le 1) n’affiche que cette ligne.

Autres options:

  • -w: affiche sur plus de largeur, ce qui améliore la visibilité des nombres dans les colonnes;
  • le nombre à la fin de la commande indique l’intervalle de rafraîchissement (ici 1 = toutes les secondes);
  • si deux nombre apparaissent, le deuxième indique le nombre de rafraîchissement à effectuer avant de s’arrêter.

mpstat -P ALL 1

mpstat -P ALL 1 affiche l’occupation des processeurs, toute les secondes.

18:01:48     CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
18:01:49     all    8.08    0.00    4.04    0.00    0.00    1.01    0.00    0.00    0.00   86.87
18:01:49       0    8.08    0.00    4.04    0.00    0.00    1.01    0.00    0.00    0.00   86.87
^C

Average:     CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
Average:     all    5.12    0.00    1.71    0.00    0.00    0.68    0.00    0.00    0.00   92.49
Average:       0    5.12    0.00    1.71    0.00    0.00    0.68    0.00    0.00    0.00   92.49

Si la charge reste haute et toujours sur le même processeur, on est en présence d’une application non threadée, qui bloque le processeur.

Comme vmstat, cette commande prend deux nombres en arguments (période et nombre de rafraîchissements)

pidstat 1

Affichage par processeur (avant dernière colonne) les processus les plus gourmands en détaillant la répartition user time, system time et wait.

Linux 4.19.97-v7+ (thelibrary)  05/16/2020      _armv7l_        (4 CPU)

04:41:01 PM   UID       PID    %usr %system  %guest   %wait    %CPU   CPU  Command
04:41:02 PM     0       522    0.96    0.00    0.00    0.00    0.96     2  tmux: server
04:41:02 PM     0     29866    0.96    3.85    0.00    0.00    4.81     1  pidstat

04:41:02 PM   UID       PID    %usr %system  %guest   %wait    %CPU   CPU  Command
04:41:03 PM     0      9173    0.00    3.00    0.00    0.00    3.00     0  top
04:41:03 PM     0     29856    0.00    1.00    0.00    0.00    1.00     0  kworker/u8:0-events_unbound
04:41:03 PM     0     29858    1.00    0.00    0.00    0.00    1.00     2  kworker/2:2-events
04:41:03 PM     0     29866    3.00    2.00    0.00    0.00    5.00     1  pidstat
^C

Average:      UID       PID    %usr %system  %guest   %wait    %CPU   CPU  Command
Average:        0       522    0.49    0.00    0.00    0.00    0.49     -  tmux: server
Average:        0      9173    0.00    1.47    0.00    0.00    1.47     -  top
Average:        0     29856    0.00    0.49    0.00    0.00    0.49     -  kworker/u8:0-events_unbound
Average:        0     29858    0.49    0.00    0.00    0.00    0.49     -  kworker/2:2-events
Average:        0     29866    1.96    2.94    0.00    0.00    4.90     -  pidstat

Cette commande se rapproche de la commande top mais au lieu de rafraîchir l’écran en effaçant les informations précédentes, elle affiche continuellement des nouvelles données. Ce qui est le cas de la plupart des commandes fournies ici.

pidstat est aussi une commande qui prend deux nombres en arguments (période et nombre de rafraîchissements).

iostat -xz 1

Cette command affiche la charge sur les disques (sur les périphériques de type block plus exactement).

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           1,00    0,00    2,25    0,00    0,00   96,75

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sda               0,00     0,00    6,00    0,00   636,00     0,00   212,00     0,00    0,00    0,00    0,00   0,00   0,00
dm-0              0,00     0,00    6,00    0,00   636,00     0,00   212,00     0,00    0,00    0,00    0,00   0,00   0,00
dm-1              0,00     0,00    6,00    0,00   636,00     0,00   212,00     0,00    0,00    0,00    0,00   0,00   0,00

^C

Les informations les plus importantes sont:

  • r/s, w/s, rkB/s, wkB/s: les lectures/écrites, en nombre et en bande passante par seconde;
  • await: l’attente moyenne en milli-seconde avant la réponse à une requête, ce qui est un bon indicateur de problème, si l’attente est trop longue;
  • avgqu­sz: taille moyenne de la queue d’attente du périphérique;
  • %util: l’utilisation du périphérique.

À noter que iostat -xy 1 affiche aussi des informations sur l’utilisation moyenne de tous les processeurs.

Note sur les options:

  • il est possible de spécifier un périphérique (exemple: iostat -xz sda 1)
  • -x: affiche plus de statistiques;
  • -z: n’affiche pas les périphériques inactifs pendant la période d’analyse;
  • -h: statistiques pour les humains;
  • -t: affiche l’heure;
  • encore une commande à deux nombres pour arguments.

free -m (ou mieux free -m -h)

Cette command affiche simplement l’état de la mémoire.

              total        used        free      shared  buff/cache   available
Mem:          7.3Gi       2.2Gi       2.0Gi       468Mi       3.1Gi       4.3Gi
Swap:          15Gi       1.0Mi        15Gi

sar -n DEV 1

Cette commande affiche la bande passante utilisée par chaque interface réseau.

^C

16:37:46        IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s   %ifutil
16:37:47           lo     12.86     12.86      1.65      1.65      0.00      0.00      0.00      0.00
16:37:47         eth0      7.14      7.14      0.41      1.48      0.00      0.00      0.00      0.01
16:37:47         eth1      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00

Average:        IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s   %ifutil
Average:           lo      6.68      6.68      1.07      1.07      0.00      0.00      0.00      0.00
Average:         eth0     23.06     36.29      1.83     43.52      0.00      0.00      0.00      0.36
Average:         eth1     33.11     19.87     42.08      2.10      0.00      0.00      0.00      0.03

La dernière colonne est particulièrement intéressante puisqu’elle affiche le taux d’usage, qui permet de voir si une interface est saturée.

Sar est une commande à deux nombres pour arguments.

sar -n TCP,ETCP 1

Cette commande affiche un résumé des métriques TCP et des erreurs réseaux.

^C

16:49:36     active/s passive/s    iseg/s    oseg/s
16:49:36         0.00      0.00     50.00     47.06

16:49:36     atmptf/s  estres/s retrans/s isegerr/s   orsts/s
16:49:36         0.00      0.00      0.00      0.00      0.00

Average:     active/s passive/s    iseg/s    oseg/s
Average:         0.00      0.00     13.98     13.74

Average:     atmptf/s  estres/s retrans/s isegerr/s   orsts/s
Average:         0.00      0.00      0.00      0.00      0.00

Les colonnes indiquent:

  • active/s: le nombre de connexions ouvertes par la machine elle même par seconde;
  • passive/s: le nombre de connexions entrantes par seconde;
  • retrans/s: le nombre de retransmission.

Si ce dernier nombre est élevé, cela signifie qu’il y a certainement un problème réseau.

La commande sar possède de nombreuses option pour analyser le réseau:

  • -n EDEV:
  • -n EIP (ou -n EIP6): les erreurs au niveau de la couche ip v4 (ou v6)

Les arguments à l’option -n peuvent se combiner (par exemple: -n EDEV,EIP,EIP6) et surtout n’oublier l’argument 1 pour calculer et afficher les résultats toutes les minutes.

Conclusion

Pour obtenir plus d’informations, la page manuelle (aka man) de chaque commande viendra compléter cet article qui ne fait qu’effleurer le sujet.

Aucun de ces outils ne s’appuient sur BPF, une technologie qui est en passe de devenir le passage obligé pour l’analyse de performance des machines en temps réel.

En attendant les outils basés sur BPF, ceux présentés ici ont l’avantage d’être disponibles sur toutes les machines, y compris celles ayant des noyaux âgés.

Un Pihole à usage multiple

Pihole est un logiciel fantastique pour supprimer la publicité, le traçage et bloquer l’accès à des sites indésirables. Il peut aussi être utilisé pour bloquer l’accès à certain site de façon temporaire.

Trou noir dans lequel la publicité est envoyée par Pihole

Par exemple, pour ne pas être tenté d’aller surfer sur Twitter pendant les heures de travail, ou pour empêcher ses enfants de rester trop longtemps sur Youtube, il peut être utile de bloquer l’accès à ces sites uniquement à certaines heures.

L’interface web de pihole est peu pratique pour un tel usage. Il vaut mieux utiliser la ligne de commande et cron. Le programme pihole permet en effet d’ajouter et de supprimer des sites via la ligne de commande.

Le script

Voici donc un mini script pour ajouter ou supprimer des sites à la blacklist.

#!/bin/bash
                            set -e

                            readonly SCRIPTNAME=$(basename $0)
                            readonly PIHOLE=/usr/local/bin/pihole

                            readonly LIST='(^|\.)dailymotion\.com$
                            (^|\.)vimeocdn\.com$
                            (^|\.)vimeo\.com$
                            (^|\.)googlevideo\.com$
                            (^|\.)youtube\.(de|fr|be|com)
                            '

                            action () {
                            local action=$1
                            local del=""
                            if [[ "${action}" == "allow" ]]
                            then
                            del='--delmode'
                            fi
    $PIHOLE --regex $del -q "'"${LIST}"'"
                            }

                            readonly ARG1=$1
                            case "$ARG1" in
    block)
        action block
        ;;
    allow)
        action allow
        ;;
    *)
                            echo "Usage: $SCRIPTNAME {block|allow}" >&2
                            exit 3
        ;;
                            esac

Example de crontab

Pour autoriser uniquement l’accès aux sites entre 17 heure et 18:30 le week-end:

0 17 * * 1,2,3,4,5 /usr/local/bin/dynamic-regex-list.sh allow >  /dev/null 2>&1
30 18 * * 1,2,3,4,5 /usr/local/bin/dynamic-regex-list.sh block >  /dev/null 2>&1

Dans cet exemple, le script a été nommé dynamic-regex-list.sh et placé dans le répertoire /usr/local/bin/.

Le problème

Si, comme moi, la première chose que vous faites après le démarrage d’une Raspberry PI sur distribution Raspbian c’est de désinstaller tous les logiciels inutiles, alors j’ai trouvé le logiciel qu’il vous faut: pi-gen. Il s’agit ni plus ni moins du logiciel utilisé pour construire les images Raspbian.

Correctement configuré, il vous permettra de construire une distribution Raspbian aux petits oignons.

Raspberry 3 dans son boitier

La solution

La première étape consiste à récupérer le contenu du dépôt git sur github.

git clone https://github.com/RPi-Distro/pi-gen

Il y a ensuite quelques éléments à modifier:

  1. le fichier Dockerfile afin de contourner un bug qui empêche les machines 64 Bits la construction des images;
  2. le fichier config pour écraser quelques valeurs par défaut;
  3. les «/stages/» qui sont les différentes étapes de constructions de l’image Raspbian.

Utiliser Docker

J’ai simplement remplacé la première ligne afin de construire les images avec des programmes 32 bits:

diff --git a/Dockerfile b/Dockerfile
index 2e53149..d680d7f 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-FROM debian:buster
+FROM i386/debian:buster
 
 ENV DEBIAN_FRONTEND noninteractive

Quelques paramètres de base

Le fichier config contient quelques paramètres de base de l’installation:

  • l’utilisateur par défaut et son mot de passe: FIRST_USER_NAME et FIRST_USER_PASS;
  • si ssh est actif au démarrage (il ne l’est pas par défaut): ENABLE_SSH;
  • les paramètres wifi: WPA_ESSID, WPA_PASSWORD et WPA_COUNTRY;
  • l’image à construire doit-elle être compressée ou pas: DEPLOY_ZIP;
  • la timezone, qui est située à Londres par défaut, et donc décalée d’une heure avec Paris et Berlin: TIMEZONE_DEFAULT;
  • la liste des stages à exécuter (cf. ci-après), configurée ainsi chez moi: STAGE_LIST="stage0 stage1 stage2".

La liste complètes des paramètres est lisibles dans le fichier README du projet.

Configuration des stages

Les stages sont les étapes successives de construction de l’image Raspbian. Il y a cinq étapes. L’image est bootable après l’étape 1. L’étape 2 contient la configuration de la timezone, l’installation et la configuration du client ntp, la création du premier utilisateur, etc.

Les stages 3, 4 et 5 installent des logiciels supplémentaires dont X11, un environnement bureautique, etc.

De mon côté j’ai construit le stage 2, mais en le modifiant pour y enlever des paquets que je n’utiliserai pas. Pour cela j’ai modifié les fichiers nommés XX-packages présents dans les sous répertoires du répertoires stage2.

Il est aussi de créer son propre stage sur mesure, et de l’inclure dans le paramètre STAGE_LIST. Là encore le fichier README est votre ami.

Construction des images

Construire l’image Raspbian est ensuite aussi simple que:

./build-docker.sh

L’image sera créée dans le répertoire deploy. Ensuite, il suffit d’un cat /path-to/deploy/yourimage-name.img > /dev/sdX/dev/sdX est votre carte SD, et vous voilà prêt à démarrer votre Raspberry avec votre distribution construite sur mesure!

Encore un mini post avec une série de mini trucs. Rien d’extra ordinairement nouveau ici, mais c’est pratique de publier en vrac des notes prises au fil des jours pour pouvoir ensuite les retrouver facilement.

Git

git diff-tree --no-commit-id --name-only -r master..develop pour lister les fichiers modifiés entre deux commits, ou deux branches (ici master et develop).

Ansible

J’ai eu du mal à trouver comment exécuter en local_action une commande du module shell. La solution: utiliser _raw_params comme ci-dessous:

- name: Build frontend
                            local_action:
                            module: shell
                            _raw_params: grunt build
                            args:
                            chdir: "{{ build_root_path }}/src/views/"
                        

Mysql

Quelques commandes en vrac, suffisamment explicites pour ne pas avoir à les commenter, à garder sous le coude:

SHOW FULL PROCESSLIST;
                            SET GLOBAL general_log = 1;
SHOW TABLE LIKE 'prefix%';
                        

Configuration

Je ne suis pas un fanatique de la configuration à outrance des logiciels utilisables dans un terminal. J’essaie généralement de me contenter de la configuration par défaut, afin de ne pas être pris au dépourvu ensuite lorsque je dois utiliser ces mêmes logiciels sur un serveur distant, où ces personnalisations seront absentes.

Dernièrement j’ai fait une exception pour tmux. Dans 90% des cas, lorsque je découpe une fenêtre, je souhaite rester dans le même répertoire duquel j’ai lancé la découpe. En revanche, lorsque j’ouvre une nouvelle fenêtre, je souhaite retourner dans mon HOME, ce qui est le comportement par défault. C’est très pratique sur mon ordinateur personnel, et si je n’ai pas cette fonctionnalité sur un serveur, je peux m’en passer aisément. J’ai donc créé un fichier ~/.tmux.conf avec la configuration suivante:

bind '"' split-window -c "#{pane_current_path}"
bind % split-window -h -c "#{pane_current_path}"
                        

Je n’utilise emacs que sur mon ordinateur personnel. Pour me me connecter à une base de données mariadb (ou mysql) en utilisant un autre port que le port standard, ce qui arrive systématiquement en utilisant des base de données hébergé dans des containers, j’ai dû ajouter la ligne suivante:

Voici quelques astuces que j’ai découvertes ces derniers mois et que j’ai pensées à noter pour plus tard, et aussi pour les partager:

Ligne de commande

  • Quand la commande realpath n’est pas disponible, la commande readlink -f peut la remplacer;
  • pwd -P résout les liens symboliques;
  • less -i rend la recherche insensible à la case (taper -i) à l’intérieur d’un less marche aussi;
  • git log --oneline -- path/to/directory/ liste rapidement toutes les commits qui ont affecté un répertoire.

Sudo

sudo une-commande-qui-genere-du-texte >> fichier-not-writable ne marchera pas, parce que sudo est utilisé par la commande seulement, pas pour la redirection. Il faut utiliser sudo tee

sudo une-commande-qui-genere-du-texte | tee -a fichier-not-writable

Environnement hostile (netcat non disponible)

Pour tester si un port est ouvert en bash, lorsque ni netcat, ni telnet ne sont pas disponible ou installable:

 (echo > /dev/tcp/skinner/22) >/dev/null 2>&1 \
    && echo "It's up" || echo "It's down"

Javascript

document.getElementsByTagName('img') retourne une [[https://developer.mozilla.org/en-US/docs/Web/API/NodeList][Nodelist]], et non un [[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array][array]]. Heureusement l’opérateur ... va vous aider:

[...document.getElementsByTagName('img')].forEach(t => {t.remove()})

Ansible:

  • Attention à ne pas confondre: database: "{{ ansible_env.MYSQL_DATABASE }}" et user: "{{ lookup('env', 'MYSQL_USER') }}":
    • env récupère une variable de l’environnement de la machine source;
    • ansible_env récupère une variable de l’environnement de la machine cible.
  • Le module rsync peut être utilisé derrière un bastion ssh uniquement avec l’option use_ssh_args: yes

Besoin

Par défaut, Docker stocke ses images dans le répertoire /var/lib/docker. Lorsqu’on commence à utiliser Docker de façon plus soutenue, les images s’accumulent et le contenu de ce répertoire prend de plus en plus de place. Or par défaut, avec une distribution debian, le répertoire /var est dans une partition séparée, qui peut devenir assez vite trop petite.

La première solution consiste à modifier la taille de ses partitions. L’autre solutions, moins radicale, consiste à déplacer le répertoire contenant les images Docker. C’est ce qu’effectue le code dans le snippet qui suit.

Après avoir stoppé le service Docker, la configuration du service est modifiée pour indiquer le nouveau répertoire (dans ce snippet le nouveau répertoire est /home/docker), puis l’ancien répertoire est copié vers le nouveau, et effacé, et enfin le service est redémarré.

Code

service docker stop
echo '{
"data-root": "/home/docker"
}' >  /etc/docker/daemon.json
mkdir /home/docker
rsync -aP /var/lib/docker/ /home/docker
rm -rf /var/lig/docker
service docker start

Introduction

Que l’on soit freelance ou salarié, on n’a pas toujours le choix des outils de gestion de projets que l’on doit utiliser. Parmi les outils imposés que je dois me coltiner au jour le jour, Jira est dans mon top des outils les plus désagréables (euphémisme pour rester poli).

Heureusement, des gentils développeurs de Netflix ont créé un outil, go-jira, qui permet d’éviter l’utilisation de l’interface web du mastodon, et d’utiliser la ligne de commande depuis son terminal pour gérer ses tickets.

Installation

L’outil a été développé avec le langage Go. Il s’installe donc comme tous les logiciels écrits dans ce langage, avec la commande go get qui télécharge le code, le compile et l’installe dans un répertoire donné. Il suffit donc de taper: go get gopkg.in/Netflix-Skunkworks/go-jira.v1/cmd/jira pour obtenir un exécutable qui sera copié dans le sous répertoire bin du répertoire défini par la variable GOPATH.

Pour exécuter facilement ce binaire, deux options. Soit créer un alias pointant vers le fichier directement (alias jira=~/go/bin/jira à ajouter dans son ~/.bash_aliases); soit ajouter ${GOPATH}/bin dans son path, ce qui revient à accepter tous les logiciels compilés avec la commande go get.

Première utilisation

La première commande à exécuter avant toute chose est de s’authentifier auprès d’une instance Jira. Dans mon cas personnel, cela donne ceci:

jira login -e https://jira.nom-du-client.com/ -u "Michael Parienti"

J’ai fourni deux paramètres:

  1. l’url de l’instance jira où se se connecter avec l’option -e
  2. mon identifiant avec l’option -u

Un mot de passe est demandé et, si le mot de passe est correct, un cookie est enregistré dans un sous répertoire ~/.jira. Ce cookie vous permettra de ne pas avoir à vous authentifier pour les prochaines commandes. Néanmoins, d’après mon expérience, sa durée de vie est plus courte que celle d’une session avec un navigateur.

Pour rentrer dans le vif du sujet, voici un exemple de commande plus concrète qui change le statut d’un ticket.

jira -e https://jira.nom-du-client.com/  transition  "In Progress" PREFIX-10693

Je re utilise ici l’option -e pour renseigner le serveur jira, puis je donne le nom de la commande (transition), le nouveau statut (In Progress) et enfin le numéro du ticket que je veux modifier.

Configurer l’outil

Pour éviter de fournir chaque fois certaines options qui restent identiques d’un appel à l’autre, il est nécessaire d’utiliser des fichiers de configuration.

L’outil va chercher tous les répertoires et fichiers .jira.d/config.yml de façon hiérarchique.

Vous pouvez donc enregister sous votre répertoire maison, dans ~/.jira.d/config.yml, toutes les options communes à vos projets.

Dans mon cas ce fichier ressemble à ceci:

editor: emacs -nw
user: Michael Parienti

Ici j’ai seulement configuré mon éditeur par défaut et mon identifiant, qui est commun à toutes les instances jira que j’utilise.

Dans le répertoire (~/projects/nom-du-client/.jira.d/config.yml) j’enregistre l’url de l’instance jira utilisée par le projet:

endpoint: https://jira.nom-du-client.com/

Cela m’évite de fournir ce paramètre à chaque fois. Tous les exemples qui suivent dans cet article utilisent un endpoint défini dans un fichier de configuration.

Exemples de commandes

Voici une liste de commandes qui accèdent en lecture à Jira:

jira view PREFIX-10693
jira transitions PREFIX-10693
jira list --query "priority = Blocker"
jira list --query "Component = XYZ AND priority = Blocker"

Ces commandes respectives:

  1. affiche le ticket PREFIX-10693
  2. affiche la liste des changements de statut possibles pour ce ticket
  3. liste tous les tickets qui ont la priorité Blocker
  4. liste tous les tickets qui ont la priorité Blocker et qui ont le composant XYZ

Voici une liste de commandes qui modifient des tickets:

jira take PREFIX-10693
jira unassign PREFIX-10692
jira comment PREFIX-10693
jira comment --noedit -m "Un commentaire judicieux" PREFIX-10693
jira close PREFIX-10693

Ces commandes respectivement:

  1. M’assigne le ticket PREFIX-10693
  2. Enlève le propriétaire au ticket PREFIX-10692
  3. Ajoute un commentaire au ticket PREFIX-10693; l’éditeur par défaut va s’ouvrir
  4. Ajoute le commentaire "Un commentaire judicieux" au ticket PREFIX-10693 sans ouvrir d’éditeur
  5. Ferme le ticket PREFIX-10693

La liste de toutes les commandes disponibles est la suivante: «acknowledge, assign, attach, create attach get, attach list, attach remove, backlog, block, browse, close, comment, component add, components, create, createmeta, done, dup, edit, editmeta, epic add, epic create, epic list, epic remove, export-templates, fields, in-progress, issuelink, issuelinktypes, issuetypes, labels add, labels remove, labels set, list, login, logout, rank, reopen, request, resolve, start, stop, subtask, take, todo, transition, transitions, transmeta, unassign, unexport-templates, view, vote, watch, worklog add, worklog list, session».

Une aide est disponible pour chacune d’entre elles.

Créer ses propres commandes

Un autre point fort de l’outil go-jira est la possibilité de créer ses propres commandes.

L’exemple basique, fourni par la documentation, consiste à lister les tickets dont nous sommes le propriétaire:

custom-commands:
  - name: mine
    help: display issues assigned to me
    script: |-
      {{jira}} list --query "resolution = unresolved and assignee=currentuser() ORDER BY created"

Dans mon fichier de configuration global, j’ai créé une commande pour fermer un ticket et enlever le propriétaire au ticket, et une autre commande pour ajouter un commentaire rapidement:

custom-commands:
  - name: bye
    help: Close and unassign a ticket
    args:
      - name: TICKET
        required: true
    script: |-
      {{jira}} close {{args.TICKET}} ; {{jira}} unassign {{args.TICKET}}
  - name: sl-comment
    help: Comment a ticket with a single line comment
    args:
      - name: TICKET
        required: true
      - name: COMMENT
        required: true
    script: |-
      {{jira}} comment --noedit -m "{{args.COMMENT}}" {{args.TICKET}}

La commande sl-comment ne sert qu’à m’éviter de fournir l’argument --noedit que j’oublie tout le temps. La comment bye est un raccourci pratique pour supprimer les très vieux bugs qui ne sont plus d’actualité.

Les exemples ci-dessus sont simples. Il est aussi possible de spécifier très précisément les options et les arguments de chaque commande, en particulier leur type.

Et plus encore

L’outil propose d’autres fonctionnalités que je n’ai pas abordées, parce que je ne les utilise pas (encore) ou par manque de temps:

  • les fichiers de configurations peuvent être des scripts exécutables, et ainsi rendus dynamiques;
  • tout ce qui affiché peut être configuré via l’utilisation de templates (patron en bon français);
  • l’authentification peut s’appuyer sur des outils extérieurs; j’utilise personnellement pass.

Conclusion

Cet article n’est qu’une introduction à l’outil go-jira. Moi même j’utilise encore l’interface web pour avoir une vue d’ensemble sur les tickets d’un sprint.

J’utilise ensuite l’outil en ligne de commande pour les opérations simples comme le changement de propriétaire ou de statut d’un ticket. Mon objectif reste néanmoins de me passer de plus en plus de la lourde interface web.

Présentation des outils

Comme beaucoup de monde, je passe pas mal de temps à chercher la solution de monitoring idéale. Il faut dire que la liste des solutions est longue. En ce moment, je teste le combo Telegraf pour générer les données (charge, disque, mémoire, etc.) et InfluxDB, pour les stocker. C’est un choix temporaire.

Ces deux outils sont écrits par la même société, et sont distribués sous une licence libre. Leurs installations sont assez similaires : télécharger les fichiers .deb ou .rpm disponibles sur les sites, et les installer à la main.

Installation d’un serveur InfluxDB

Si vous êtes sur une distribution debian sid, vous pouvez installer directement la version sid d’InfluxDB. C’est mieux, parce qu’ainsi l’arborescence standard sera respectée :

  • utilisation par défaut du répertoire /var/lib/influxdb au lieu /var/opt/influxdb
  • fichier de configuration dans /etc/influx/ au lieu /etc/opt/influxdb

Le seul inconvénient, c’est que vous aurez une version plus ancienne d’InfluxDB (0.9.2), qui vous obligera à installer une version plus ancienne de Telegraf (0.1.4).

Concernant la configuration d’InfluxDB, il faudra prendre garde aux directives :

  • reporting-disabled à mettre à true (pas utile pour la version empaquetée par Debian ;
  • les trois bind-address à écrire sous la forme 127.0.0.1:port si vous ne souhaitez pas exposer votre serveur InfluxDB aux connexions distantes en TCP ;

Il faut ensuite créer une base et un utilisateur dédiés à Telegraf. On lance la commande influx (ou /opt/influxdb/influx si vous avez installé le paquet à la main), qui va se connecter au serveur InfluxDB. La création d’une base, et d’un utilisateur avec les permission d’accéder à cette base se déroule comme suit :

> CREATE DATABASE TelegrafDB;
> CREATE USER TelegraphUser WITH PASSWORD 'PasswordSuperDurADeviner';
> GRANT ALL ON TelegrafDB TO TelegraphUser;
> SHOW DATABASES ;
name: databases
---------------
TelegrafDB
> SHOW USERS ;
TelegraphUser   false

Les deux dernières instructions servent à vérifier que tout c’est bien passé parce que, par défaut, le client influx n’est pas très bavard. Je vous ai mâché le travail, mais tout cela est assez bien documenté.

Installation de Telegraf

Ensuite il faut installer Telegraf, cette fois-ci uniquement via un fichier dev ou rpm récupérable sur le site, et le configurer pour qu’il puisse se connecter au serveur InfluxDB. Le fichier /etc/opt/telegraf/telegraf.conf est assez explicite, je n’ai pas besoin d’entrer dans le détail, mais voici quelques points à noter:

  • vous pouvez définir précisément les interfaces réseau dont vous souhaitez récupérer les informations;
  • idem pour les disques durs;

Il est possible aussi d’y activer des plugins pour récupérer des statistiques sur certains logiciels, grâce à des plugins. Ces plugins sont fournis avec Telegraf. La documentation de chaque plugins est lisible dans leur code source, dans la variable sampleConfig. Voir un exemple pour Memcached.

Après un redémarrage de Telegraf, la base InfluxDB créée précédemment va commencer à se peupler.

Au bout de quelques minutes vous pourrez vérifier cela avec les commandes suivantes, à exécuter dans le client InfluxDB :

> USE TelegrafDB
> SHOW SERIES
> SHOW MEASUREMENTS
> SELECT value FROM mem_free
> SELECT value FROM net_bytes_sent
> SELECT mean(value) FROM mem_free WHERE time > now() - 1h GROUP BY time(1m)

Vous pouvez aussi explorer vos données en faisant pointer votre navigateur sur le port 8083 de la machine qui héberge votre serveur InfluxDB. Dans les cas deux, cela n’est que du texte. Pour afficher des jolis graphes, il va falloir utiliser un autre outil, et c’est à ce moment que Grafana entre en jeu.

Grafana

L’installation de Grafana se déroule avec un dpkg -i sur le fichier téléchargé sur le site du projet. Par défaut Grafana n’est pas lancé, et ne se lancera pas automatiquement au démarrage de l’ordinateur.

La configuration s’effectue dans le fichier /etc/grafana/grafana.ini. Pour ma part, j’ai modifié :

  • reporting_enabled = false
  • les directives admin_user et admin_password
  • les directives allow_*

Au premier lancement, Grafana va créer et remplir sa base de données de configuration (par défaut dans un fichier Sqlite dans /var/lib/grafana) et créer le premiers utilisateur (que vous avez défini dans le fichier de configuration). Conséquence rigolote : il ne sert à rien de modifier les identifiants de l’administrateur dans le fichier de configuration après le premier démarrage ; ce fichier ne sera plus utilisé pour l’authentification.

En ouvrant votre navigateur sur l’url http://127.0.0.1:3000/ vous pourrez entrer les coordonnées de l’administrateur que vous avez défini dans le fichier de configuration, et vous tomberez alors sur une magnifique page vide. C’est là que les choses deviennent intéressantes.

En cliquant sur la petite icone Grafana en haut à gauche, vous allez ouvrir un menu latéral. La deuxième ligne de ce menu s’appelle «Data Sources». En cliquant dessus, vous allez entrer dans la configuration des sources des données. De là, en cliquant sur le bouton «Add New», dans le menu horizontal du haut, vous allez pouvoir créer votre première source de données, qui sera la base Telegraf du serveur InfluxDB.

Capture du formulaire pour créer une nouvelle «datasource»

Le formulaire de création de cette source de données est assez simple lorsqu’on vient de créer sa base Telegraf quelques minutes plus tôt:

  • l’url de connexion (ne ce serait pas http://127.0.0.1:8086/ ?)
  • le nom de la base
  • l’utilisateur et le mot de passe de l’utilisateur à la base

En cas de doute, consulter le fichier /etc/opt/telegraf/telegraf.conf pour retrouver les identifiants utilisés pour se connecter à la base qui stocke vos données. Une fois la connexion ajoutée, vous pouvez la tester.

Maintenant, créons notre premier tableau de bord. Dans le menu vertical de gauche, cliquons sur Dashboard. Cela affiche la «Home», et surtout le menu Dashboard dans le haut de la page. En cliquant sur «Home» cela ouvre la liste (vide) des Dashboards. En bas de la liste, vous avez «+New» d’afficher. C’est là qu’il faut cliquer.

Le bouton caché pour créer un nouveau tableau de bord

Cela nous affiche un nouvel écran, vide, mais différemment vide. Il y a une barre assez fine, vert fluo tout à gauche.

Petite barre cliquable

C’est encore là qu’il faut cliquer. Vous pouvez aller dans «Add Panel > Graph», et…

Le menu caché

… vous avez un superbe graphe qui s’affiche !

C’est joli, pour faire joli

Ne vous réjouissez pas trop vite car les données de ce graphe n’a aucun sens. Il s’agit juste de vous montrer que vous êtes sur la bonne voie. En cliquant sur le titre «no title» du graphe, un menu apparait. Dans ce menu, il faut cliquer sur «edit».

Un autre menu caché

Courage, vous êtes déjà sur l’onglet «Metrics», vous êtes presque! En bas à droite, il faut choisir la Datasource que vous avez ajouté auparavant.

Vous tombez alors sur une requête prédéfinie. Il faut clique sur la partie «From» pour choisir la bonne données à afficher. Dans mon cas, j’ai choisi system_load1.

Votre premier graphe dans Grafana

Cette fois, vous y êtes : vous venez d’afficher dans Grafana les premières données issues d’InfluxDB !

Je vous laisse continuer tout seul. Vous pouvez faire, à partir de là:

  • afficher plusieurs données sur le même graphe (bouton «Add Query»);
  • créer d’autres panneaux, avec d’autres graphes contenant d’autres données;
  • changer le style des graphes.

En quelques minutes vous pourrez afficher un petit tableau bord avec la charge serveur, l’espace disque, l’occupation mémoire et le trafic réseau.

Premier tableau de bord

Limitations

Ceci était une première expérimentation avec le couple InfluxDB + Telegraf pour générer des statistiques, et l’outil Grafana pour afficher les statistiques récoltées.

À partir de là deux pistes restent à explorer. En premier on pourrait vouloir découvrir plus finement les options de configuration d’InfluxDB (la durée de stockage des données), et de Telegraf (utilisation de ses plugins).

Telegraf reste un projet récent, et manque encore de maturité. Par exemple, les statistiques sur les entrées sont stockées en quantité totale, et non pas en quantité par seconde, informations fournies par d’autres outils en ligne de commande comme iotop ou iostat.

Grafana, quant à lui, demande un petit temps d’adaptation. L’objectif de cet article est de faciliter sa prise en main. Mais ensuite il est assez facile à utiliser.

Il existe d’autres outils pour afficher des statistiques. Facette est l’un d’entre eux. Malheureusement Facette n’est pas encore adapté au dernier format des données InfluxDB. Donc la comparaison entre Facette et Grafana, ce sera pour une autre fois.

Soit une machine, par exemple liée à une application web de type réseau social, chargée d’envoyer des courriers électroniques. Il existe différents types de courriers dans notre application. Exemple :

  • les courriers d’inscriptions;
  • les courriers de notifications («vous avez un nouveau contact»);
  • les courriers d’invitations.

Plusieurs milliers courriers d’invitations peuvent être envoyés d’un seul coup (de nos jours, les gens ont beaucoup de contacts). Le traitement de ces milliers de courrier ne doit pas bloquer un courrier de confirmation d’inscription, qui doit être reçu quelques secondes après que l’utilisateur se soit inscrit sur le site.

C’est pour cela que chaque type de courrier va être envoyé à un serveurs SMTP dédié, chez un prestataire externe, qui est chargé de délivrer le courrier à son destinataire final. Mais en local, sur notre serveur, il est nécessaire aussi de paralléliser l’envoi des courriers.

Comme notre serveur utilise [Postfixhttp://www.postfix.org] pour relayer les courriers, nous allons utiliser la fonctionnalité [MULTI_INSTANCEhttp://www.postfix.org/MULTI_INSTAN...] de Postfix, pour pouvoir disposer en local de différentes instance de Postfix, qui fonctionneront en parallèle, chacune possédant sa propre queues.

Postfix est déjà installé et configuré sur notre serveur. Cette configuration sera dédiée à l’envoi des mails depuis la machine (via la commmande sendmail). Pour installer des nouvelles instances il faut lancer :

postmulti -e init

Cette commande ajoute deux lignes dans les fichiers main.cf :

multi_instance_wrapper = ${command_directory}/postmulti -p --
multi_instance_enable = yes

Ensuite on créé la première instance supplémentaire :

postmulti -I postfix-1 -G secondary -e create

Les arguments de la commande sont :

  • -I: nom de l’instance; c’est aussi le répertoire
  • -G: le groupe de l’instance; il sera possible d’effectuer des opérations sur toutes les instances d’un groupe.

Cette commande:

  1. crée des fichiers master.cf et main.cf dans le répertoire /etc/postfix-1;
  2. rajoute la directives multi_instance_directories dans le fichiet /etc/postfix/main.cf; cette clé contient le répertoire de configuration de la nouvelle instance (/etc/postfix-1 donc);
  3. crée sur le serveurs tous les fichiers nécessaires à Postfix pour gérer cette deuxième instance; en particulier dans le répertoires /var/lib/postfix-1 et /var/spool/postfix-1.

C’est le moment d’aller modifier les fichiers nouvellement créés, main.cf et master.cf, du répertoire de configuration de la nouvelle instance pour personnaliser les paramètres de la nouvelle instance selon vos souhaits.

Dans mon cas, je souhaite que la nouvelle instance écoute sur le port 10025 au lieu du port 25. Il faut donc ajouter la ligne suivante dans le fichier main.cf :

# À la place de 'smtp      inet  n       -       -       -        -      smtpd'
127.0.0.1:10025     inet  n       -       n       -       -       smtpd

Dans ma situation, j’ai aussi modifié le fichier main.cf pour envoyer les courriers au bon serveur SMTP.

Pour démarrer la nouvelle instance, la commande à lancer est :

postmulti -i postfix-1 -p start

Sous Debian (et Ubuntu), vous aurez un mesasge d’erreur indiquant que le fichier dynamicmaps.cf est manquant. Cela se résout simplement avec un lien symbolique :

ln -s /etc/postfix/dynamicmaps.cf /etc/postfix-1/

Pour pourrez créer autant d’instance Postfix que nécessaire à vos besoins.

Pour tester la configuration de chaque nouvelle instance, les commandes habituelles de Postfix sont disponibles. Il faut seulement leur passer en argument le répertoire de configuration de l’instance à tester, avec l’option -c ou -C en fonction de la commande :

mailq -C /etc/postfix-1
sendmail -C /etc/postfix-1
postsuper -c /etc/postfix-1
postconf -c /etc/postfix-1
postqueue -f -c /etc/postfix-1

Les dernières commandes à connaître pour manipuler une instance sont assez simple à retenir :

postmulti -i postfix-1 -p stop
postmulti -i postfix-1 -e disable
postmulti -i postfix-1 -e destroy

À noter qu’il est possible de lancer ces instructions à un groupe d’instance, en utilisant l’option -g suivi d’un nom du groupe, au lieu de l’option -i et du nom de l’isntance.

Toutes les commandes et toutes leurs options sont détaillées dans la page manuelle de la configuration Multi-instances.