Comment monitorer rapidement du code PHP

Quand nous écrivons du code, nous nous demandons souvent s’il est performant ou s’il n’y a pas de memory leak. Il existe de très bons outils pour vérifier ponctuellement si nos assertions sont justes. Blackfire.io en est un bon exemple, cependant ce dernier ne peut pas nous aider à vérifier si dans le temps, notre code n’est pas en train de leaker ou de devenir de plus en plus lent.

Dans cet article, nous allons voir comment mesurer la consommation mémoire d’un consumer et/ou les temps de réponse d’un service tiers.

Nous pouvons contrôler ces informations via memory_get_usage et microtime, mais il est assez peu pratique de lire tous les résultats dans une console ou un fichier. Quoi de mieux que ce genre de graphique pour suivre l’évolution des performances de son code ?

bench

Sur ce graphique, j’ai monitoré les temps de réponse d’un composant de notre infrastructure. Notre connexion vers ce composant a un timeout à 10ms. J’ai voulu vérifier lors de forte charge l’occurrence de ces timeout (en rouge) ainsi que les temps de réponse moyens (en vert).

Pour ce faire, nous allons utiliser trois outils que j’aime beaucoup : Docker, InfluxDB et Grafana. InfluxDB est une base de données orientée TimeSeries. Grafana est une UI pour visualiser ces données.

Nous commençons par démarrer deux containers :

docker run --name bench-grafana -p 3000:3000 grafana/grafana
docker run --name bench-influx -p 8086:8086 influxdb:1.5

Note : Si votre projet est déjà dans docker, il ne faudra pas oublier d’attacher ces containers sur le network existant en ajoutant l’option --network my_app_default

Considérons le code PHP suivant :

while (true) {
    do_something();
}

function do_something() {
    // Simulate slowness
    usleep(random_int(1000, 100000));

    // Simulate random memory consumption
    static $memory = null;
    $memory = str_repeat("x", random_int(10 * 1000, 1000 * 1000));
}

On va ajouter le client PHP pour InfluxDB.

composer require influxdb/influxdb-php

Et nous n’avons plus qu’à mettre à jour notre boucle :

require __DIR__.'/vendor/autoload.php';

// If the code is run into Docker, replace the host with "bench-influx"
$client = new InfluxDB\Client('127.0.0.1');
$database = $client->selectDB('bench');
$database->create(new InfluxDB\Database\RetentionPolicy('test', '5d', 1, true));

while (true) {
    $t = microtime(true);

    do_something();

    $points = [
        new InfluxDB\Point(
            'duration',
            microtime(true) - $t
        ),
        new InfluxDB\Point(
            'memory',
            memory_get_usage()
        ),
    ];

    $database->writePoints($points);
}

voilà!

Il ne reste plus qu’à nous connecter à Grafana via l’URL http://127.0.0.1:3000 et avec les identifiants admin/admin.

Il faudra cependant configurer la base de données :

  • Type : InfluxDB
  • Host : L’IP de votre host (docker inspect -f '{{range .NetworkSettings.Networks}}{{.Gateway}}{{end}}' bench-influx) si vous n’avez pas de network ou bench-influx dans un network
  • Le nom de la base : bench.

Ensuite, il suffit de jouer un peu avec l’éditeur de query pour afficher ce genre de graphique :

bench

Conclusion

Grâce à Docker, InfluxDB et Grafana, il est vraiment facile et rapide d’avoir une vision claire sur le comportement d’un programme sans pour autant polluer notre ordinateur de logiciel supplémentaire. Cependant, ici tout est éphémère : les données seront perdues dès que les containers seront éteints.

blog comments powered by Disqus