---
title: Principes et implémentation d’OpenTelemetry dans des projets PHP
description: Retour sur la conférence de Danielle KAYUMBI HODIEB sur « OpenTelemetry » (AFUP Day 2024) – Principes et implémentation dans des projets PHP
---

[Le Blog technique d'Adimeo ](https://www.adimeo.com/blog-technique)

# [Principes et implémentation d’OpenTelemetry dans des projets PHP](https://www.adimeo.com/blog-technique/opentelemetry-projets-php-afup-day-2024)

 Rédigé par [Maurice Nguyen](https://www.adimeo.com/blog-technique/author/maurice-nguyen) | Jul 23, 2024 6:00:00 AM

En tant que [développeurs](https://www.adimeo.com/blog/chronique-d-un-developpeur-etre-developpeur-informatique-) ou [DevOps](https://www.adimeo.com/blog/devops-une-r-evolution-en-marche), nous avons déjà été quelques fois confrontés **au crash de nos applications** en production.

Les causes peuvent être nombreuses : **erreurs dans le code source** malgré l’implémentation de [tests unitaires](https://www.adimeo.com/blog-technique/la-verite-sur-les-tests-unitaires) ou fonctionnels, **les attaques type déni de service** ou **les failles de sécurité** pour ne citer que celles-ci.

Dans cette situation, les impacts peuvent être désastreux que ce soit d’un point de vue business ou pour la réputation de l’entreprise. La panne qu’a subie AWS en 2021 en est le parfait exemple. L’équipe infra avait déployé un job automatique pour scaler les services managés. Ce déploiement en production a engendré un trop grand volume de requêtes, créant **une congestion dans le système**.

## La clé du succès : l’observabilité

Pour éviter que ce genre de situation n’arrive, il est nécessaire d’**anticiper** au maximum les sources d’erreurs, de les **comprendre** et d’**agir** rapidement pour limiter les impacts sur le système.

Deux problématiques se présentent alors :

- Quelle est la **cause de la panne** ? Erreurs de l’application ou causées par des services tiers, latences et goulots d’étranglement, etc.
- Comment **envoyer rapidement des alertes** ?

Il faut donc **observer le système** ! Par exemple, **monitorer les opérations** sur des intervalles de temps est possible, mais cette méthode a ses limites car elle se concentre sur **l’analyse de données prédéfinies** récoltées de différents systèmes.

Pour mieux anticiper les pannes, **l’analyse de manière continue** en se basant sur les expériences passées est la clé. C’est ce qu’on appelle **l’observabilité**. Elle se repose sur les **données télémétriques** qui vont permettre de récolter les données émises par les composants et ainsi **comprendre les comportements du système**.

Les données télémétriques se composent :

- des **traces** qui permettent de suivre le parcours de la requête,
- des **métriques** qui fournissent des informations quantitatives sur l'état et la performance des systèmes, comme le taux de requêtes, le temps de réponse, l'utilisation des ressources, etc.,
- des **logs** qui sont les messages émis par les systèmes pour le diagnostic et l’analyse des incidents.

Une fois ces données générées, collectées et exportées, on va pouvoir les exploiter dans un framework d’observabilité comme **OpenTelemetry**.

 

## Qu’est-ce-qu’OpenTelemetry ?

[OpenTelemetry](https://opentelemetry.io/) est un **projet open source** visant à fournir une suite unifiée d'outils pour la **collecte**, la **transformation** et **l'exportation** de données télémétriques.

Il aide à **surveiller les performances** et à **diagnostiquer les problèmes** dans des environnements distribués. En 2019, OpenTelemetry intègre la Cloud Native Computing Foundation (CNCF), une organisation à but non lucratif créée pour promouvoir et soutenir les technologies cloud-native. Le SDK (Software Development Kit ou en français kit de développement logiciel) est disponible dans de nombreux langages tels que [C++](https://opentelemetry.io/docs/languages/cpp/), [PHP](https://opentelemetry.io/docs/languages/php/), [Java](https://opentelemetry.io/docs/languages/java/), [Python](https://opentelemetry.io/docs/languages/python/) et [Ruby](https://opentelemetry.io/docs/languages/ruby/) pour ne citer qu’eux.

## Les fondamentaux d’OpenTelemetry

Les fondamentaux de cette solution sont au nombre de deux : le **tracing distribué** et les **collectors**.

### Le tracing distribué

Le **tracing distribué** va permettre de **suivre le parcours de la requête de la source à la destination** quel que soit les systèmes par lesquels elle a transité contrairement au système traditionnel où on ne peut suivre la requête que dans un seul système. Pour cela, on va avoir trois éléments de base : les **logs**, les **spans** et les **traces**.

**>** Les **logs** respectent en général le standard syslog à savoir une date d’émission du log, la criticité (« DEBUG », « INFO », « ERROR », « CRITICAL », etc.) mais cela ne suffit pas car il manque les **informations contextuelles**. C’est là qu’entrent en jeu les **spans** et les **traces**.

**>** Un **span** va permettre de tracer une opération spécifique au niveau du code.

En voici un exemple :

```

{ 
    "trace_id": "0af7651916cd43dd8448eb211c80319c", 
    "span_id": "b7ad6b7169203331", 
    "parent_span_id": "348a2b12bc1c632a", 
    "name": "get_cart_details", 
    "start_time": "2023-05-01T12:45:00.000Z", 
    "end_time": "2023-05-01T12:45:10.000Z", 
    "status": "OK", 
    "attributes": { 
        "http.method": "GET", 
        "user_id": 1111, 
        "card_id": 2222 
    }, 
    "links": [], 
    "trace_state": "" 
}

```

Il se compose obligatoirement d’un nom, d’une date de début, d’une date de fin et des attributs tels que les paramètres injectés à la requête et ainsi avoir plus de contexte.

Pour injecter un span, il est conseillé de le faire dans une **classe bien spécifique** (dans un controller, un handler, un manager, etc.).

Ci-dessous un exemple d’injection de span dans un controller [Symfony](https://www.adimeo.com/blog/quest-ce-que-symfony-et-quels-sont-ses-avantages) :

```

namespace App\Controller; 
 
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; 
use Symfony\Component\HttpFoundation\JsonResponse; 
use Symfony\Component\Routing\Annotation\Route; 
use App\Service\OpenTelemetryService; 
use OpenTelemetry\Context\Context; 
use Symfony\Component\Security\Core\Security; 
 
class CartController extends AbstractController 
{ 
    private $openTelemetryService; 
    private $security; 
 
    public function __construct(OpenTelemetryService $openTelemetryService, Security $security) 
    { 
        $this->openTelemetryService = $openTelemetryService; 
        $this->security = $security; 
    } 
 
    /** 
     * @Route("/api/cart/{cartId}", name="get_cart_details", methods={"GET"}) 
     */ 
    public function getCartDetails(int $cartId): JsonResponse 
    { 
 // Injection du span 
        $tracer = $this->openTelemetryService->getTracer(); 
        $span = $tracer->spanBuilder('get_cart_details') 
            ->setParent(Context::getCurrent()->getSpan()) 
            ->startSpan(); 
 
        try { 
            $user = $this->security->getUser(); 
 
            if (!$user) { 
                throw new \Exception('Unauthenticated user'); 
            } 
 
            $userId = $user->getId(); 
 
            $span->setAttribute('http.method', 'GET'); 
            $span->setAttribute('user_id', $userId); 
            $span->setAttribute('cart_id', $cartId); 
 
            $cartDetails = [ 
                'cart_id' => $cartId, 
                'user_id' => $userId, 
                'items' => [ 
                    ['product_id' => 1, 'quantity' => 2], 
                    ['product_id' => 2, 'quantity' => 1], 
                ], 
                'total_price' => 300.00, 
            ]; 
 
            $span->end(); 
 
            return new JsonResponse($cartDetails); 
 
        } catch (\Exception $e) { 
            $span->recordException($e); 
            $span->end(); 
 
            return new JsonResponse(['error' => 'Unable to retrieve cart details'], 500); 
        } 
    } 
} 
```

**>** Une **trace** quant à elle est une collection de spans. Elle va permettre de suivre le parcours de la requête à travers les différents services. Entre chaque trace, on va avoir le **contexte** (trace context) et c’est sa propagation qui va permettre de maintenir la corrélation entre les signaux (via des en-têtes HTTP par exemple).

### Les collectors

Les **collectors**, quant à eux, vont permettre de **récupérer**, **traiter** et **exporter** les données **vers des backend d’observabilité** ([Prometheus](https://prometheus.io/docs/introduction/overview/), [Zipkin](https://zipkin.io/) ou des services cloud comme [AWS X-Ray](https://aws.amazon.com/fr/xray/) et [Google Cloud Trace](https://cloud.google.com/trace?hl=fr) par exemple). Ils vont se baser en général sur le protocole **OTLP** (**O**pen**T**e**L**emety **P**rotocol) qui va décrire le mécanisme d’encodage et de transport des données télémétriques et une fois ces données exportées, on va pouvoir utiliser des outils APM (Application Performance Management) tels que [Datadog](https://docs.datadoghq.com/fr/opentelemetry/), [New Relic](https://docs.newrelic.com/docs/more-integrations/open-source-telemetry-integrations/opentelemetry/opentelemetry-introduction/) ou [Elastic APM](https://www.elastic.co/guide/en/observability/current/apm-open-telemetry.html) et ainsi avoir la map des services dans laquelle la requête a transité.

Un exemple de map sur Datadog permettant de mettre en exergue des métriques sur les temps de réponse et les services qui ont crashé.

En conclusion de cet article, vous l’aurez très certainement compris, **l’observabilité** est très importante car elle va permettre d’**anticiper** les erreurs et donner la possibilité aux équipes d’**agir** le plus rapidement possible.

Pour la mise en place de ce framework, trois étapes sont essentielles :

- La **prévention** (Prevent) à travers la qualité du code. Cela passe par la mise en place de **tests unitaires**, de **tests fonctionnels**, de **tests d’intégration** et de **l’analyse statique**, l’implémentation de [**design patterns**](https://www.adimeo.com/blog-technique/design-patterns-a-quoi-ca-sert-et-comment-les-utiliser), du [**concept SOLID**](https://www.adimeo.com/blog-technique/principes-solid) ou du [**TDD**](https://www.adimeo.com/blog-technique/avantage-test-driven-development-tdd) (Test Driven Development).
- La **découverte **(Discover) via la mise en place du **monitoring** pour **détecter le plus rapidement possible** les erreurs qui peuvent se déclencher dans vos applications.
- La **résolution** (Resolve) qui dépend de votre **expertise technique** et mais aussi de la **communication** au sein de vos équipes qui est primordiale à cette étape.

Pour en savoir plus, je vous propose d’autres contenus :

- La [documentation officielle](https://opentelemetry.io/docs/) d’OpenTelemetry
- Le [guide officiel](https://opentelemetry.io/docs/languages/php/) pour l’intégration d’OpenTelemetry dans vos applications PHP
- Le [dépôt GitHub](https://github.com/open-telemetry/opentelemetry-php) contenant le code source ainsi que quelques exemples

Et si cet article vous a plu, je vous propose de poursuivre votre lecture avec d’autres **retours sur les conférences « Afup day 2024 »** de Nancy :

- [Architecture à mettre en place pour un SaaS en fonction du client](https://www.adimeo.com/blog-technique/architecture-saas-afup-day-2024)
- [Maintien et scalabilité d'une application vieille de 20 ans](https://www.adimeo.com/blog-technique/scalabilite-maintien-application-20-ans-afup-day-2024)
- [Game-changing CSS : les techniques pour des sites Web performants](https://www.adimeo.com/blog-technique/game-changing-css-afup-day-2024)
- [Container, the hard way : un voyage à travers la complexité des conteneurs](https://www.adimeo.com/blog-technique/complexite-conteneurs-afup-day-2024)
- [Comprendre le TDD : principes, architecture hexagonale et types de tests](https://www.adimeo.com/blog-technique/test-driven-development-afup-day-2024)
- [Introduction à l’Event Sourcing en PHP](https://www.adimeo.com/blog-technique/event-sourcing-php-afup-day-2024)

*Crédit photo : Arsenii Palivoda*

[Voir l'article complet](https://www.adimeo.com/blog-technique/opentelemetry-projets-php-afup-day-2024)

```json
{
  "@context" : "http://schema.org",
  "@type" : "BlogPosting",
  "author" : {
    "@type" : "Person",
    "name" : "Maurice Nguyen"
  },
  "dateModified" : "2024-08-19T06:52:34.854Z",
  "datePublished" : "2024-07-23T06:00:00Z",
  "headline" : "Principes et implémentation d’OpenTelemetry dans des projets PHP",
  "image" : {
    "@type" : "ImageObject",
    "height" : 853,
    "url" : "https://adimeo.com/hubfs/article-opentelemetry.webp",
    "width" : 1280
  },
  "mainEntityOfPage" : "https://www.adimeo.com/blog-technique/opentelemetry-projets-php-afup-day-2024",
  "publisher" : {
    "@type" : "Organization",
    "logo" : {
      "@type" : "ImageObject",
      "height" : 60,
      "url" : "/hs/hsstatic/content_shared_assets/static-1.4092/img/default-amp-logo.png",
      "width" : 60
    },
    "name" : "Le Blog technique d'Adimeo"
  }
}
```