OpenTelemetry : le feedback utilisateur à la portée de tous.

Pour mieux comprendre le sujet de cet article, il est vivement recommandé d’avoir lu mon précédent article sur la télémétrie.


OpenTelemetry : une solution gratuite et open source pour faire de la télémétrie facilement et de manière ultra flexible.


Un jouet (beaucoup) trop cher

Aussi controversée qu’elle soit, la télémétrie, c’est juste génial !

C’est la manière la plus efficace d’avoir du feedback honnête de la part de ses utilisateurs, et ainsi de pouvoir améliorer son application pour la rendre la plus croustillante possible.

J’ai déjà parlé de ses nombreux avantages dans un précédent article, en vous donnant toutes les clefs pour l’aborder. Allez d’abord le lire pour mieux comprendre la suite de cet article.

J’ai mis 3 plombes à faire cette miniature, ce n’est pas pour ne l’utiliser qu’une seule fois !

C’est bon ? Parfait. Vous en avez retenu quoi ?

Ben, c’est cool, tu m’as expliqué tout le processus, les plans, la présentation… Mais au final, je fais quoi avec mon code ?

C’est vrai que mon article est surtout une vue d’ensemble de la télémétrie et ne rentre pas dans les détails techniques, et ce pour une raison très simple.

C’est un bordel sans nom !

Il ne s’agit pas juste d’un petit transfert de données à l’arrache, mais d’un système complexe avec énormément de pièces interconnectées. Pour une solution de base, on va retrouver au minimum :

  • Un extracteur pour récupérer les données en question.
  • Un processeur pour les modifier avant envoi.
  • Un exportateur pour les transmettre à nos serveurs.
  • Un collecteur pour les modifier après envoi.
  • Un autre exportateur pour les stocker dans la base.
  • Une base de données, bien sûr.
  • Un (ou plusieurs) logiciel pour les présenter et mieux les étudier.

Vous comprenez bien que pour mettre tout ça en place, vous en avez pour votre temps et votre argent !

On parle de semaines de travail pour étudier, coder, tester et faire communiquer tous ces éléments.

Sans parler de l’architecture de fou furieux derrière un tel système.

Parce que si c’est mal foutu, le jour où vous allez changer de backend, où que vous vouliez l’intégrer sur une nouvelle application, c’est cuit, il faudra tout recommencer. RIP.

Image de freepik.com
Pas besoin de coder ça, il y a juste à choper une solution du marché qui fait le travail à notre place.

Il est vrai que ce genre solution existe, encore faut-il les trouver ! Il y a quelques critères à prendre en compte :

  • Adaptée à votre code source : si l’API ne fonctionne pas dans votre langage, vous pouvez faire une croix dessus.
  • Adaptée à votre backend : si l’API ne peut pas communiquer avec votre backend, c’est mort.
  • Adaptée à vos besoins : si l’API ne vous permet pas de faire ce que vous voulez (par exemple, des tests A/B), adios.

Donc pour trouver une solution complète qui fasse exactement ce que vous voulez faire, il faut vraiment que les étoiles soient alignées.

D’accord, mais si au lieu de prendre une solution complète, on prenait chaque pièce individuellement et on les faisait communiquer ensemble, c’est tout bénef, non ?

Pas mal, mais comment faire ?

Une solution serait de programmer soi-même des pièces intermédiaires pour tout rattacher (récupérer les données de X pour les envoyer à Y).

Mais honnêtement, ça fait un peu MacGyver. Quitte à faire un foutoir pareil, autant tout coder soi-même.

Roh, tu fais ton difficile là…

Peut-être, mais au final, je pense avoir trouvé la solution à tous ces problèmes. Vous ne me croyez pas ? Laissez-moi vous présenter OpenTelemetry.


La révolution de la télémétrie

OpenTelemetry est une solution open source permettant de prendre en charge tout le processus de télémétrie, de l’extraction des données jusqu’à leur arrivée dans la base.

Il a 3 avantages qui, mis ensemble, en font une solution absolument monstrueuse :

  • Tout-en-un : prends en charge toutes les étapes du processus de télémétrie pour ne pas avoir besoin d’utiliser des outils tiers.
  • Universel : adapté à tous les langages et tous les backends.
  • Infiniment personnalisable : vous pouvez l’adapter pour absolument tous les besoins.

Et en plus de ça, c’est totalement gratuit, open source, et assez simple à utiliser. Donc vous n’avez plus aucune excuse !


Une solution à toutes épreuves

Mouais, ça pue l’arnaque ton truc…

C’est vrai que ça fait un peu remède miracle vendu sur un marché d’Istanbul. Mais je vais vous faire un petit historique, vous allez mieux comprendre.

Avant, le monde de la télémétrie était dominé par deux monstres qui se sont battus en duel pendant des millénaires :

  • OpenTracing développé par la CNCF (Cloud Native Computing Foundation). Il s’agit d’une bibliothèque de spécifications ultra-flexible pouvant être implémentée dans n’importe quel langage. Cependant, l’implémentation devait être faite par les développeurs, ce qui demandait pas mal de bricolage et/ou de composants externes.
  • OpenCensus développé par Google. Il s’agit d’un ensemble d’outils et de frameworks ultra-riches permettant de prendre en charge le processus de télémétrie d’une application de A à Z. Cependant, ils sont spécifiques à certains langages, et pas adaptés aux besoins les plus précis.

On voit bien la différence de philosophie. OpenTracing est super flexible, mais trop minimaliste, et OpenCensus est super puissant, mais trop rigide. Il fallait bien choisir son camp.

Du coup, la CNCF et Google ont décidé de fusionner les deux projets pour pouvoir bénéficier de tous avantages en même temps.

C’est ainsi qu’est né OpenTelemetry : une spécification énorme qui découle sur un ensemble d’implémentations.

Voici comment ça se présente :


Spécification/API

Il s’agit d’un ensemble de règles permettant d’uniformiser la manière dont OpenTelemetry est implémenté pour que le processus de télémétrie se déroule toujours de la même manière, peu importe le système ou le langage.

C’est le niveau d’abstraction le plus haut possible. Même pas de code, juste de la documentation et une API finement étudiées pour que vous puissiez retrouver les mêmes fonctionnalités et le même niveau d’extensibilité dans toutes les implémentations.


SDK

Il s’agit des implémentations concrètes d’OpenTelemetry développée par le CNCF et la communauté, afin de ne pas partir de zéro.

Implémentations existantes d’OpenTelemetry.

Dans ces SDK, on va retrouver un tas d’outils qui, une fois assemblés, vont permettre de prendre en charge tout le processus de télémétrie. Pour ne citer que les principaux :

  • Traceur/Activité : pour instrumentaliser le code et extraire les données.
  • Processeurs : pour les traiter avant transmission.
  • Échantillonneur : pour filtrer ce que l’on veut extraire.
  • Exportateur : pour les transmettre vers le backend.

Et la magie du truc, c’est que comme ces SDK suivent la spécification à la lettre, vous pouvez très facilement étendre, modifier ou remplacer ces éléments pour créer votre propre système sur mesure sans passer par des rituels incas.

Quelques exemples :

  • Créer vos propres processeurs, de manière à pouvoir traiter les données comme bon vous semble.
  • Adapter l’exportateur à votre backend particulier.
  • Ajouter un échantillonneur basé sur la taille des pieds de vos utilisateurs (pourquoi pas).
  • Développer votre propre SDK from scratch. Let’s go !

Peu importe ce que vous faites, tant que vous respectez la spécification, toutes les pièces s’emboiteront comme des LEGO.


Collecteur

Il s’agit d’une pièce centrale tournant sur un de vos serveurs, qui permet de traiter les données après transmission, pour ensuite les réexporter vers votre backend.

C’est pratique, notamment si vous avez besoin de filtrer, agréger ou regrouper les données.

Vous n’êtes pas obligé de l’utiliser, mais c’est bon de savoir que ça existe. Je ne vais cependant pas plus en parler ici.


Vous comprenez maintenant pourquoi OpenTelemetry est une solution de premier choix. C’est un tout-en-un ultra riche, ultra flexible, et qui uniformise le processus (complexe) de la télémétrie. Sweet 👌

Cependant, ce n’est pas en claquant des doigts qu’il deviendra l’outil de rêve pour votre projet. Il y a quand même un peu de bricolage à faire, et c’est ce qu’on va voir maintenant.


Hello World !

Vas-y, je suis hypé, dis-moi comment on fait.

J’y arrive, mais avant, petit avertissement. À l’heure où j’écris ces lignes, OpenTelemetry n’est pas officiellement sorti, la plupart des SDK ne sont qu’en préproduction.

Pour ici, ce n’est pas bien grave, cependant, je vous déconseille de les utiliser en production pour le moment. Voyez cet article comme un genre de bac à sable pour vous faire la main 😉

Dans mon exemple, j’utiliserais le SDK pour .NET, mais souvenez-vous, tous les SDK descendent de la même API, donc peu importe le langage que vous utilisez, c’est sensiblement la même chose.

Le but du jeu est assez simple : envoyer une donnée de notre application vers un backend avec OpenTelemetry.

Attends une minute, je n’ai pas de serveur dédié à la télémétrie moi !

Moi non plus, mais un backend n’a pas besoin d’être un truc de fou. Une invite de commande suffit. C’est rudimentaire, certes, mais ça suffit pour vous présenter le principe.


Installation

La première étape est bien sûr d’intégrer le SDK à votre code source. Pour cela, suivez simplement la documentation correspondant à votre langage.

Pour .NET, il s’agit simplement d’un paquet Nuget pour OpenTelemetry, et un autre pour l'exportateur vers une invite de commande.

dotnet add package OpenTelemetry --prerelease
dotnet add package OpenTelemetry.Exporter.Console --prerelease
Remarquez que je précise le flag --prerelease dans la commande pour que dotnet installe le paquet malgré le fait qu’il ne soit encore en version stable.

Instrumentalisation

La première chose à faire est de déclarer une source d’activité, le traceur de l'environnement .NET.

using System;
using System.Diagnostics;
using OpenTelemetry;
using OpenTelemetry.Trace;
using OpenTelemetry.Resources;

namespace OpenTelemetryExamples
{
    class Program
    {
        static readonly ActivitySource ActivitySource = new ActivitySource("MySource");
        
        static void Main(string[] args) { }
    }
}
L'implémentation pour .NET est un peu particulière car elle utilise le composant Système.Diagnostics pour l'instrumentalisation. Donc n'oubliez pas de l'ajouter !

Il s’agit d’une instance permettant de créer des activités, qui vont nous permettre d’instrumentaliser notre code pour récupérer les données à envoyer au backend (appelés traces).

Ici par exemple, je vais créer une activité qui va récupérer la trace nommée UselessTracecontenant la valeur "Hello World !".

static void RunProgram()
{
    string sayHello = "Hello World !";

    using (var activity = ActivitySource.StartActivity("MyActivity"))
    {
        activity?.SetTag("UselessTrace", sayHello);
    }
}
J’ai utilisé un using, car quand une activité récupère une trace, elle la transmet à sa source. Donc on peut s’en débarrasser une fois le travail accompli.

Vous noterez qu’en télémétrie, il est important de nommer les choses. C’est pour ça que la source d’activité, l’activité et la trace ont toutes les 3 un nom.

Il faut se souvenir que le collecteur/backend va devoir faire le tri à la fin, donc si vous nommez les choses n’importe comment (comme ici 😖), vous vous tirez une balle dans le pied.

Une bonne pratique, c’est de n’avoir qu’une seule source d’activité par plan de télémétrie. Ça rend le tout beaucoup plus simple à gérer derrière !


Transmission

Les données sont à nous, il n’y a plus qu’à les ramener.

Pour cela, on va créer un Tracer Provider qui va prendre en charge tout le reste du processus de télémétrie. Voici à quoi ça ressemble :

static void InitialiseTracerProvider()
{
    TracerProvider tracerProvider = Sdk.CreateTracerProviderBuilder()
        .AddSource("MySource")
        .AddConsoleExporter()
        .Build();
}

Le principe est simple et repose sur un monteur (builder pattern). En gros, on va créer un objet de base que l’on va venir configurer avec tout un tas de méthodes. Ici, on en a 4 :

  1. CreateTracerProviderBuilder() : création du monteur.
  2. AddSource("MySource") : ajout de la source d’activité.
  3. AddConsoleExporter() : ajout d’un exportateur vers une invite de commande.
  4. Build() : création et récupération du tracer provider.
Et maintenant ?

C’est tout ! Vous n’avez plus qu’à lancer votre programme, OpenTelemetry va extraire les données pour les envoyer dans votre terminal.

using System;
using System.Diagnostics;
using OpenTelemetry;
using OpenTelemetry.Trace;
using OpenTelemetry.Resources;

namespace OpenTelemetryExamples
{
    class Program
    {
        static readonly ActivitySource ActivitySource = new ActivitySource("MySource");
        
        static void Main(string[] args) 
        { 
            InitialiseTracerProvider();
            RunProgram();
        }

        static void InitialiseTracerProvider()
        {
            TracerProvider tracerProvider = Sdk.CreateTracerProviderBuilder()
                .AddSource("MySource")
                .AddConsoleExporter()
                .Build();
        }

        static void RunProgram()
        {
            string sayHello = "Hello World !";

            using (var activity = ActivitySource.StartActivity("MyActivity"))
            {
                activity?.SetTag("UselessTrace", sayHello);
            }
        }
    }
}

Ok, ce n’est qu’un Hello World ! dans une console, mais, quel que soit le contexte, le principe reste exactement le même.

C’est pour cela que l’utilisation d’un monteur est particulièrement intéressante, elle permet d’ajouter les pièces que l’on veut au tracer provider.

Quelques exemples :

  • Exportation des données via le protocole de communication OpenTelemetry.
  • Utilisation d’un processeur pour mesurer la date et la durée de l’opération.
  • Utilisation d’un échantillonneur pour ne récupérer qu’une donnée sur deux.

Voilà, maintenant que vous avez les bases, je peux vous laisser voler de vos propres ailes.

Quoi !? C’est tout ?

Oui, pour moi en tout cas. Car OpenTelemetry est tellement riche que je pourrais en écrire une trilogie.

Néanmoins, si le sujet vous intéresse, faites-le-moi savoir en commentaire et en partageant l’article, et j’en ferais un second beaucoup plus pointu, avec beaucoup plus de code 😈

Mais le mieux, c’est encore d’essayer par vous-même. Je vous invite donc à aller feuilleter la spécification et bricoler des petits trucs. Il n’y a rien de plus formateur !


Merci d’avoir lu cet article jusqu’au bout, je sais que ce n’est pas le sujet le plus passionnant, mais j’ai pris énormément de plaisir à l’écrire. Promis, la prochaine fois, on revient aux sources.

Partagez cet article autour de vous, car c’est la meilleure manière de soutenir le blog et ça ne coute pas un rond.

Suivez-moi sur Twitter @ITExpertFr pour recevoir mes meilleurs conseils au quotidien, je vous jure, vous n’attendez que ça !

Et pour ceux qui veulent plus d’outils et de méthodes pour optimiser leur processus développement, voici quelques articles pour vous :

Quant à moi, je vous laisse, il faut que j’aille réusiner un programme écrit à l’époque de Christophe Colomb, souhaitez-moi bonne chance.

À bientôt pour un nouvel article sur le blog des développeurs ultra-efficaces. Tchao !