• 15 hours
  • Medium

Free online content available in this course.

course.header.alt.is_video

course.header.alt.is_certifying

Got it!

Last updated on 8/25/20

Développez des métriques spécifiques à votre application

Nous l'avons vu, de nombreuses métriques sont disponibles dans Blackfire pour vous aider à contrôler la performance de votre application. Mais au fond, ce que nous aimerions, c'est profiler particulièrement les fonctions clés de nos applications : pour cela, nous devrons créer nos propres métriques.

Prenons un cas tout simple : on souhaite garder le contrôle sur le nombre d'appels au Container de services effectués sur les pages de notre application de démonstration.

Créez la métrique "services"

Tout d'abord, quand on appelle un service Symfony, quelle fonction est appelée ? C'est la méthode "get" de la classe  Symfony\Component\DependencyInjection\Container  !

La déclaration de nouvelles métriques se passe également dans le fichier .blackfire.yml :

# Déclaration d'une nouvelle métrique
metrics:
    services:
        label: "Appels du Container de Services"
        matching_calls:
            php:
                - callee: "=Symfony\Component\DependencyInjection\Container::get"

tests:
    "Tests des appels au Container de Services"
        path: "/.*"
        assertions:
            - metrics.services.count < 30
            - metrics.services.wall_time < 20ms

Et vous devriez avoir maintenant le rapport de tests qui suit, après avoir déclenché une analyse :

Rapport de tests sur la métrique spécifique
Rapport de tests sur la métrique spécifique

Détaillons un peu ce que nous avons fait ici. Tout d'abord, nous avons une nouvelle entrée dans le fichier .blackfire.yml : "metrics". Nous pouvons définir la métrique et lui donner un label. Dans matching_calls, nous demandons à l'extension Blackfire de capturer pour nous un sélecteur de métrique à l'aide de PHP.

Sélecteur de métriques

Définir une métrique revient à définir un sous-ensemble d'appels à des fonctions. Le premier caractère définit comment interpréter la suite de l'expression :

  • =  pour matcher exactement l'expression passée ;

  • ^  pour matcher tout ce qui commence par l'expression ;

  • /  permet de passer une expression régulière ;

  • !  ne doit pas matcher cette expression.

La seconde partie sert à définir la ou les fonctions exécutée(s) que nous souhaitons capturer. Voici quelques exemples de sélecteurs :

  • =Foo::bar  : capture la fonction "bar" appartenant à la classe "Foo" ;

  • =baz  : capture la fonction "baz" ;

  • Foo::  : capture toutes les fonctions de la classe "Foo".

Le comportement par défaut de Blackfire est de collecter tous les appels d'une fonction dans un seul nœud. Cependant, parfois, les arguments passés à une fonction peuvent avoir un impact. On aimerait pouvoir les distinguer et identifier les valeurs des arguments passés. Par exemple, la fonction "query" de PDO nous permettrait de connaître exactement les requêtes SQL exécutées.

Collectez des arguments de la métrique spécifique

Dans une métrique spécifique, il est possible de collecter un seul argument qui sera disponible dans le graphe Blackfire. Pour cela, complétons la définition de notre métrique :

# Déclaration d'une nouvelle métrique
metrics:
    services:
        label: "Appels du Container de Services"
        matching_calls:
            php:
                - callee:
                    selector: "=Symfony\Component\DependencyInjection\Container::get"
                    argument: { 1: "^"}

tests:
    "Tests des appels au Container de Services":
        path: "/.*"
        assertions:
            - metrics.services.count < 30
            - metrics.services.wall_time < 20ms

 Comprenons ce que fait cette nouvelle entrée nommée argument :

  • la partie de gauche indique quel argument doit être capturé : ici, ce sera le premier argument ;

  • la partie de droite est une expression régulière qui définit les conditions de capture.

Dans notre cas, nous avons utilisé  ^ , ce qui veut dire que nous souhaitons toujours capturer l'argument. Cependant, comme pour le sélecteur, vous pouvez préciser les conditions de capture de l'argument. 

Revenons donc à nos moutons... euh à nos graphes :D !

Si vous déclenchiez une nouvelle analyse, le graphe devrait vous surprendre : mais où sont donc passés les appels au Container?

Eh bien maintenant, chaque appel à la fonction  Symfony\Component\DependencyInjection\Container::get  se différencie en fonction de l'argument passé (le nom du service, comme vous le savez déjà ;)). Par conséquent, chaque nœud a une empreinte très faible sur la performance ! Parcourez la liste des fonctions pour retrouver les appels de services :

Un appel de fonction et son argument grâce aux métriques spécifiques
Un appel de fonction et son argument grâce aux métriques spécifiques

En résumé

Avec Blackfire, vous avez accès à de nombreuses métriques fournies par défaut. Si elles ne suffisent pas, vous pouvez définir les vôtres. Pour cela, il faut définir la métrique dans le fichier .blackfire.yml dans la section metrics.

Le sélecteur est simple et puissant, grâce à la possibilité d'utiliser des expressions régulières.

Enfin, il est également possible de capturer un argument de la fonction dont la position est définie à l'aide d'un index numérique (1 veut dire le premier argument) et suivie d'une expression régulière qui définit les conditions de capture de l'argument.

Example of certificate of achievement
Example of certificate of achievement