Le tracing est une méthode d'observation du flux de requêtes à travers un système distribué, où chaque étape de traitement est enregistrée comme un événement séparé avec un horodatage. Selon OpenTelemetry, 2025, une trace combine le chemin complet d'une requête du point d'entrée jusqu'à la réponse finale, en passant par tous les microservices et appels externes. Cela permet aux développeurs d'identifier les goulots d'étranglement, les retards et les défaillances dans les architectures complexes de backends mobiles.
Points clés
Le tracing est une méthode d'observation distribuée où chaque requête entrante est suivie à travers tous les services et composants du système. Contrairement aux métriques, qui affichent des valeurs agrégées (temps de réponse moyen, nombre d'erreurs), le tracing préserve le contexte complet d'une seule requête spécifique.
Chaque étape de traitement — un appel à la base de données, une requête HTTP vers un autre microservice, l'exécution d'une tâche en arrière-plan — est enregistrée comme une unité séparée avec un horodatage, un statut et des attributs. Selon Google Dapper (publication originale de 2010), le tracing permet de localiser les retards dans les systèmes distribués avec la précision d'un seul appel.
Le tracing est particulièrement important pour les applications mobiles où le backend se compose de dizaines de microservices. Une action utilisateur — comme la connexion à un compte — peut passer par une passerelle API, un service d'authentification, une base de données et un service Push. Sans tracing, déterminer quel composant ralentit la réponse est pratiquement impossible.
L'unité de base du tracing est un span. Chaque span représente une opération logique : une requête HTTP, une requête SQL, un appel gRPC, une sérialisation JSON. Un span contient un identifiant unique, un identifiant parent, le nom de l'opération, l'heure de début, la durée, le statut et un ensemble d'attributs.
Tous les spans liés à une même requête racine sont regroupés dans une trace. Le span racine représente le point d'entrée — une requête HTTP du client mobile vers l'API. Les spans enfants forment un arbre, où chaque span référence son parent via le champ parent_span_id.
La durée d'une trace est égale à la somme des durées des segments temporels uniques de tous les spans. Si deux spans enfants s'exécutent en parallèle, leur temps n'est pas additionné — ceci est essentiel pour analyser correctement les retards causés par des appels parallèles aux microservices.
Chaque span peut contenir des attributs — des paires clé-valeur avec des méta-informations : URL de la requête, ID utilisateur, version de l'API, nom de l'hôte. Les attributs sont utilisés pour filtrer et regrouper les traces. En plus des attributs, les spans prennent en charge les événements — des horodatages avec des descriptions textuelles, comme « échec de cache » ou « nouvelle tentative de connexion ».
Le distributed tracing résout le problème de la liaison des spans créés dans différents processus et sur différentes machines. Le mécanisme est basé sur la propagation de contexte : lorsque le service A appelle le service B, un en-tête contenant l'ID de la trace actuelle et l'ID du span parent est ajouté à la requête sortante.
Les protocoles standard de propagation de contexte sont W3C Trace Context (en-têtes traceparent et tracestate) et Zipkin B3 (en-têtes X-B3-TraceId, X-B3-SpanId). W3C Trace Context a été adopté comme standard par le consortium W3C en 2021 et est pris en charge par tous les principaux fournisseurs de télémétrie.
À la réception de la requête, le service B extrait le trace_id de l'en-tête et crée un span enfant avec ce trace_id. Ainsi, une fois la requête terminée, tous les spans des différents services sont combinés en une seule trace côté collecteur. Pour cela, chaque service doit être instrumenté avec la même bibliothèque de tracing.
Dans le développement mobile, la propagation de contexte couvre non seulement le backend mais aussi l'interaction client-serveur. Une application mobile peut envoyer un trace_id dans l'en-tête de chaque requête API, permettant de lier une action client au traitement serveur. Le SDK OpenTelemetry pour iOS et Android prend en charge la création et la propagation automatiques du contexte de trace via les clients HTTP.
import io.opentelemetry.api.trace.Span
import io.opentelemetry.api.trace.Tracer
import io.opentelemetry.context.Context
class TracingInterceptor : Interceptor {
private val tracer: Tracer = OpenTelemetry.getTracer("mobile-app")
override fun intercept(chain: Interceptor.Chain): Response {
val span = tracer.spanBuilder("HTTP POST /api/login")
.setParent(Context.current())
.startSpan()
return chain.proceed(chain.request())
.also { span.end() }
}
}
L'intercepteur Kotlin présenté crée un span pour chaque requête HTTP vers le serveur. Le contexte parent est propagé depuis le code appelant via Context.current(), permettant de lier le tracing côté client au tracing côté serveur.
OpenTelemetry est le standard de facto pour la collecte de données de trace. Il fournit une API unifiée pour générer des spans, l'instrumentation automatique des bibliothèques populaires et un mécanisme flexible pour exporter les données vers divers backends : Jaeger, Zipkin, Grafana Tempo, Datadog, New Relic.
OpenTelemetry prend en charge la création automatique de spans pour les frameworks populaires : Spring Boot, Ktor, Flask, Express, gRPC. Le développeur a seulement besoin d'ajouter une dépendance au projet, et la bibliothèque intercepte automatiquement les requêtes entrantes et sortantes. L'auto-instrumentation pour Java utilise un javaagent qui modifie le bytecode à la volée sans changer le code source.
Pour les plateformes mobiles, OpenTelemetry fournit Swift SDK et Kotlin SDK. Ils créent automatiquement des spans pour les requêtes réseau (URLSession, OkHttp), les opérations de base de données (CoreData, Room) et les tâches en arrière-plan. Le développeur peut ajouter des spans personnalisés pour la logique métier.
Les spans collectés sont envoyés à un collecteur via le protocole OTLP (OpenTelemetry Protocol). Le collecteur peut mettre en mémoire tampon, filtrer et rediriger les données vers un ou plusieurs systèmes de stockage. Selon la documentation d'OpenTelemetry, la latence typique entre la génération d'un span et son affichage dans un tableau de bord est de 2 à 5 secondes lors de l'utilisation de l'exportation gRPC.
import OpenTelemetryApi
import OpenTelemetrySdk
import URLSessionInstrumentation
let instrumentation = URLSessionInstrumentation()
instrumentation.enable()
let tracer = OpenTelemetry.instance.tracerFactory
.get("mobile-monitoring")
let span = tracer.spanBuilder("fetch-user-profile")
.setAttribute(key: "user.id", value: userId)
.startSpan()
span.end()
Le code Swift active l'instrumentation automatique de la couche réseau et crée un span personnalisé pour l'opération de récupération du profil utilisateur. L'attribut user.id permet de filtrer les traces par un utilisateur spécifique ultérieurement.
Dans les systèmes à forte charge, il est impossible de tracer chaque requête — cela crée une charge inacceptable sur le stockage et le réseau. L'échantillonnage résout ce problème en ne sauvegardant qu'un sous-ensemble de traces. Le choix de la stratégie affecte directement l'intégrité des données et le coût de l'infrastructure.
La décision de sauvegarder une trace est prise au moment de sa création — dans le span racine. L'approche la plus simple et la plus courante : un pourcentage fixe de requêtes (par exemple 5 %) est sauvegardé, le reste est ignoré. L'inconvénient est qu'on ne peut pas garantir que les erreurs rares seront capturées. Le Probability sampler dans OpenTelemetry prend en charge le réglage de la probabilité de 0,0 à 1,0.
La décision est reportée jusqu'à ce que tous les spans de la trace soient terminés. Un analyseur évalue si la trace contient des erreurs, des dépassements de temps ou des attributs intéressants, et seulement alors la sauvegarde. Cette approche nécessite la mise en mémoire tampon de tous les spans dans le collecteur, ce qui augmente la consommation mémoire. Selon Grafana Labs, l'échantillonnage tail-based est 40 à 60 % plus efficace en termes de « coût par donnée utile » dans les systèmes avec des erreurs rares mais critiques.
| Stratégie | Avantages | Inconvénients |
|---|---|---|
| Probabilité fixe | Simplicité, charge prévisible | Ignore les événements rares |
| Limitation de débit | Volume de données garanti | Couverture inégale |
| Tail-based | Capture toutes les erreurs | Consommation mémoire élevée |
| Adaptatif | Équilibre coût-couverture | Configuration complexe |
La journalisation (logging) enregistre des événements individuels avec des niveaux de gravité (info, warn, error) mais ne les lie pas dans le contexte d'une seule requête. Le tracing, en revanche, crée un arbre structuré d'opérations appartenant à une requête de bout en bout. Dans la pratique, ces deux approches ne sont pas mutuellement exclusives mais se complètent.
Les journaux sont efficaces pour l'analyse détaillée d'une erreur spécifique : un développeur voit le message exact, la trace de pile et les valeurs des variables. Le tracing répond à la question « pourquoi la requête prend-elle 5 secondes » — il montre quel microservice ou appel a pris le plus de temps. Selon Honeycomb (2024), les équipes qui utilisent le tracing avec la journalisation trouvent la cause racine des incidents 2,3 fois plus rapidement.
L'approche moderne — l'observabilité — combine le tracing, les métriques et les journaux en un seul système. OpenTelemetry prend en charge la corrélation entre ces trois signaux : chaque span peut contenir des liens vers les journaux associés, et les métriques peuvent être marquées avec trace_id pour approfondir des traces spécifiques.
Questions fréquentes
La surveillance montre des métriques agrégées du système — temps de réponse moyen, nombre d'erreurs par minute, charge CPU. Le tracing montre le chemin d'une seule requête spécifique à travers tous les composants. La surveillance répond « que se passe-t-il », le tracing répond « pourquoi cela se produit ».
Pour les systèmes de production, 1 à 5 % des requêtes suffisent avec un échantillonnage head-based. Si le système produit rarement des erreurs, un échantillonnage tail-based axé sur la capture de toutes les traces d'erreur est recommandé. Pour les environnements de staging, il est acceptable de tracer 100 % des requêtes sans limitations.
Les principaux outils incluent : Jaeger (solution d'Uber, open source), Grafana Tempo (stockage de traces évolutif), Datadog APM, New Relic Distributed Tracing, AWS X-Ray et Honeycomb. Tous prennent en charge le standard OpenTelemetry pour l'ingestion de données.
Oui, le tracing local fonctionne au sein d'un seul processus. Le SDK OpenTelemetry pour iOS et Android crée des spans pour les opérations locales : lecture de la base de données, traitement d'images, requêtes réseau. Ces traces ne sont pas distribuées mais sont utiles pour diagnostiquer les performances côté client.
Les bibliothèques de tracing modernes ajoutent moins de 1 % de surcharge avec un échantillonnage head-based. OpenTelemetry utilise une exportation asynchrone des données qui ne bloque pas le thread principal. Pour les appareils mobiles, il est recommandé de limiter la fréquence de création des spans et d'utiliser une stratégie d'échantillonnage adaptatif.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi