Translation Notice

This is an automatically translated version of that Article. Despite my best efforts, it might not be perfect.
Native speakers are welcome to open pull requests to correct anything that doesn't sound right.

Flow PHP - Télémétrie

Flow PHP - Télémétrie

L'observabilité - une façon de surveiller le comportement d'un système en fonction des signaux qu'il émet.

Depuis quelques années, un standard domine le marché et gagne une adoption de plus en plus large dans les services APM : OpenTelemetry.

OpenTelemetry fournit non seulement une spécification, des protocoles ou des conventions de nommage. C'est aussi un ensemble de bibliothèques et de SDK permettant une adoption « facile » dans pratiquement n'importe quel système.

Alors pourquoi ai-je décidé d'écrire ma propre bibliothèque au lieu d'utiliser les solutions existantes ?

Tout a commencé quand j'ai voulu intégrer le DataFrame de Flow PHP (ainsi que quelques bibliothèques comme postgresql ou filesystem) avec OpenTelemetry.

Le premier problème que j'ai rencontré, ce sont les dépendances. Le SDK OpenTelemetry nécessite :

Sachant qu'actuellement Flow PHP (dans sa version de base) ne nécessite que :

Le nombre de dépendances doublerait pratiquement. Pour un framework que les utilisateurs doivent ajouter à la liste des dépendances de leurs systèmes, cela devient quelque peu problématique en raison des conflits de versions potentiels.

Théoriquement, je pourrais faire dépendre Flow uniquement de open-telemetry/api et ajouter le SDK comme dépendance optionnelle. Cependant, quand j'ai commencé à examiner de plus près comment l'API est construite, j'ai réalisé qu'elle n'était pas compatible avec l'architecture que j'ai adoptée dans Flow.

Le principal problème pour moi était tous ces états globaux, singletons et autres mécanismes censés faciliter l'auto-instrumentation. Exemple : OpenTelemetry Globals.

Je pourrais probablement essayer de contourner Globals, mais en regardant les implémentations d'instrumentation basées sur OpenTelemetry, je rencontrerais rapidement des problèmes - le SDK est très étroitement couplé avec l'API, et l'API est très étroitement couplée avec l'état global.

Ici, j'ai dû faire un choix. Soit séparer le code de Flow à l'aide d'une abstraction supplémentaire, soit construire ma propre API qui servirait également d'abstraction pour la télémétrie.

Étant donné que l'API elle-même n'est pas si complexe, j'ai décidé de construire une API indépendante ainsi qu'une couche de transport conformes au protocole OTLP. C'est ainsi qu'est née une petite bibliothèque appelée flow-php/telemetry

L'API flow-php/telemetry est très non-invasive, ne repose pas sur des états globaux, s'appuie principalement sur des contrats, et fournit des implémentations très légères InMemory et Void utiles dans les tests.

Mais l'API seule ne suffit pas pour envoyer des signaux quelque part. Nous avons besoin d'un sérialiseur et d'un transport pour cela (c'est ce que fait le SDK OpenTelemetry).

Flow fournit quelque chose de très similaire : flow-php/telemetry-otlp-bridge.
Le rôle de cette bibliothèque est de :

flow-php/telemetry-otlp-bridge peut sérialiser les signaux en :

Les signaux peuvent être transmis via :

Signaux

Que sont les signaux ?

Métriques - données numériques sur l'état du système, par ex. nombre de requêtes par seconde, temps de réponse moyen, etc.

Traces / Spans - représentent des opérations individuelles dans le système, avec leurs attributs, leur durée, etc.
Une Trace est en fait une collection de Spans liés entre eux, formant un arbre d'opérations.
De plus, une Trace peut être liée à des métriques, des logs ou d'autres Traces, offrant une image plus complète de ce qui se passe dans le système.

Logs - données textuelles sur les événements du système, contenant souvent des attributs supplémentaires comme le niveau de log ou le contexte de l'événement.

Auto-instrumentation

L'un des principaux avantages d'OpenTelemetry est l'auto-instrumentation.

Selon la conception, les auteurs de bibliothèques (comme moi) devraient intégrer leurs outils avec l'API/SDK OpenTelemetry. Ainsi, si nous configurons la sérialisation et la couche de transport dans un système utilisant de telles bibliothèques, nous obtenons automatiquement une télémétrie de base sans effort supplémentaire.

Si la communauté PHP partageait la vision des créateurs de l'API/SDK - dans presque tous les projets, il suffirait de configurer le SDK pour avoir un aperçu du fonctionnement du système en production.

Pour l'instant, cependant, il n'existe pas une seule bibliothèque nativement intégrée avec OpenTelemetry.

Je ne sais pas pourquoi. Des environnements comme Java ou .NET ont une bien meilleure adoption d'OpenTelemetry que PHP.

Peut-être que si le SDK OpenTelemetry était plus populaire, je n'aurais pas décidé d'écrire ma propre bibliothèque.

Néanmoins, lentement mais sûrement, j'ai commencé à intégrer toutes les bibliothèques que je maintiens avec flow-php/telemetry.
J'ai également créé plusieurs extensions pour les frameworks/bibliothèques existants - permettant une auto-instrumentation tout aussi efficace.

Bibliothèques avec intégration native :

Extensions pour les bibliothèques existantes :

Note : Si vous développez votre propre projet open source - contactez-moi.
Ensemble, nous trouverons le moyen le plus simple d'intégrer votre outil avec la télémétrie. Nous pouvons le faire via une intégration native ou une extension.

OTEL Collector

OTEL Collector

OTEL Collector est un outil fantastique servant de hub central pour la réception / le traitement / le transfert des signaux.
En plaçant le collector entre votre système et l'APM (Application Performance Monitoring System), vous évitez le verrouillage fournisseur.

Nous évitons également les opérations I/O inutiles et bloquantes. Nos signaux sont mis en mémoire tampon, et quand le tampon se remplit ou que le script se termine, ils sont envoyés au collector.

Ci-dessous, des exemples de configuration du collector depuis le monorepo Flow :

APM

Il existe de nombreuses solutions populaires sur le marché pour surveiller les systèmes compatibles avec le protocole OTLP.
Cela inclut des outils payants et entièrement gratuits, disponibles en tant que services ou en open source. Avant de choisir le bon APM, cependant, il vaut la peine de se familiariser avec le protocole OTLP lui-même.

Bien sûr, la plupart des APM fournissent leurs propres bibliothèques pour surveiller les systèmes, mais leur utilisation vous lie très fortement à un fournisseur spécifique.

Ma solution préférée (du moins pour l'instant) pour le développement local est Aspire

Aspire est également configuré comme APM dans le monorepo Flow. Vous pouvez trouver l'exemple de configuration ici.

Démo

Vous pouvez trouver des exemples de code flow-php/telemetry sur https://flow-php.com.
Chacun d'eux peut être exécuté dans le navigateur en utilisant le Playground de Flow.

Mais il n'y a pas de meilleure façon d'apprendre un outil que de mettre les mains dedans, donc j'encourage tous ceux qui sont intéressés à installer Aspire, OTEL Collector localement, et à ajouter flow-php/telemetry ainsi que flow-php/telemetry-otlp-bridge.

Ensuite, il ne reste plus qu'à commencer à émettre des signaux !

Ci-dessous, une capture d'écran d'Aspire local montrant la télémétrie collectée pendant l'exécution des tests de l'ensemble du monorepo Flow.

About Author

Norbert Orzechowicz

Norbert Orzechowicz

Software architect with over 16 years of experience in building highly scalable transactional and analytical systems. I specialize in building bridges between business, development teams, systems architecture, and data infrastructure.

Creator of Flow, the most advanced data processing framework for PHP. In my spare time, I maintain several open-source projects and enjoy automating and optimizing everything around me.