Observabilité en Go : tracing, métriques et logs pour les pros

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Votre application fonctionne, mais êtes-vous sûr de savoir ce qui se passe à l'intérieur ?

\n\n

Imaginez : vous avez déployé un microservice en Go en production. Il ne plante pas, ne génère pas d'erreurs 500, mais les utilisateurs se plaignent que la page charge « lentement ». Vous consultez la surveillance — CPU 30%, mémoire normale. Que faire ? Sans observabilité en Go, vous êtes un capitaine de navire sans carte ni boussole.

\n\n

L'observabilité n'est pas simplement des « logs ». Ce sont trois piliers : le tracing, les métriques et les logs. Ensemble, ils vous donnent un super-pouvoir : comprendre ce qui se passe dans le système, même si vous ne vous attendiez pas à un problème. Dans cet article, nous allons décortiquer chacun de ces aspects avec des exemples de code en Go. Vous ne lirez pas simplement de la théorie — vous obtiendrez des recettes prêtes à l'emploi que vous pouvez mettre en œuvre dès aujourd'hui.

\n\n

Pourquoi Go est-il le langage idéal pour l'observabilité ?

\n\n

Go a été créé pour les systèmes backend où la performance et la fiabilité sont essentielles. La bibliothèque standard (net/http, database/sql) sait déjà fournir des métriques et prendre en charge les contextes pour le tracing. Et l'écosystème OpenTelemetry Go et Prometheus Go rend l'implémentation de l'observabilité simple et élégante.

\n\n

Mais le principal avantage est qu'il n'y a pas de « magie » en Go. Vous écrivez du code qui peut être mesuré, tracé et journalisé sans douleur. Voyons comment cela se fait.

\n\n

Tracing en Go : OpenTelemetry en action

\n\n

Le tracing (traçage) est l'histoire d'une requête, de son entrée dans le système jusqu'à sa sortie. Il montre combien de temps chaque étape a pris : requête à la base de données, appel à une API externe, traitement des données. En Go, le tracing est basé sur les contextes (context.Context).

\n\n

Configuration du SDK OpenTelemetry

\n\n

Installons les paquets :

\n
go get go.opentelemetry.io/otel \\\n  go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp \\\n  go.opentelemetry.io/otel/sdk/trace
\n\n

Maintenant, initialisons le traceur :

\n\n
package main\n\nimport (\n    "context"\n    "log"\n    "go.opentelemetry.io/otel"\n    "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"\n    "go.opentelemetry.io/otel/sdk/trace"\n)\n\nfunc initTracer() {\n    exporter, err := otlptracehttp.New(context.Background())\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    tp := trace.NewTracerProvider(\n        trace.WithBatcher(exporter),\n        trace.WithSampler(trace.AlwaysSample()),\n    )\n    otel.SetTracerProvider(tp)\n}
\n\n

Création d'une span dans un gestionnaire HTTP

\n\n

Voici à quoi ressemble le tracing dans du code réel :

\n\n
func userHandler(w http.ResponseWriter, r *http.Request) {\n    tracer := otel.Tracer("user-service")\n    ctx, span := tracer.Start(r.Context(), "getUser")\n    defer span.End()\n\n    // Simulation d'une requête à la base de données\n    user, err := getUserFromDB(ctx, r.URL.Query().Get("id"))\n    if err != nil {\n        span.RecordError(err)\n        span.SetStatus(codes.Error, err.Error())\n        http.Error(w, err.Error(), 500)\n        return\n    }\n\n    span.SetAttributes(\n        attribute.String("user.id", user.ID),\n        attribute.Int64("user.age", int64(user.Age)),\n    )\n\n    // Span enfant pour un appel externe\n    _, childSpan := tracer.Start(ctx, "callAnalyticsAPI")\n    defer childSpan.End()\n\n    callAnalyticsAPI(user)\n    \n    w.Write([]byte("OK"))\n}
\n\n

Chaque span contient un nom, une heure de début et de fin, des attributs et un statut. Dans Jaeger ou Grafana Tempo, vous verrez une carte complète de la requête.

\n\n

Conseil pratique

\n

N'oubliez pas de transmettre le contexte dans toute l'application. En Go, cela se fait automatiquement si vous utilisez context.Context dans les signatures de fonctions. OpenTelemetry Go récupérera lui-même le contexte de la requête HTTP si vous utilisez un middleware.

\n\n

Métriques : Prometheus et export en Go

\n\n

Les métriques sont des chiffres qui indiquent l'état du système : RPS, latence, nombre d'erreurs, uti

Blogs

Book Recommendations