RousselTMLEARNING

Artículo · Alloy: del descubrimiento a la maestría

Variables de entorno y OpenTelemetry

Este artículo está disponible en francés.

1. L'essentiel : Alloy n'est pas un SDK #

Qui lit quelle variable, et pourquoi la confusion est fréquente.

Trois familles de variables à ne pas confondre #

Une idée reçue revient souvent : « Alloy est compatible OpenTelemetry, donc il suffit de définir les variables OTEL_* ». C'est faux. Ces variables sont définies par la spécification pour les SDK, c'est-à-dire les bibliothèques intégrées à vos applications. Alloy est un collecteur : il reçoit de l'OTLP, mais sa configuration passe par ses composants.

Qui lit quelle variable d'environnement entre l'application, Alloy et le backend

FamilleExemplesQui la lit ?
Variables natives d’AlloyGOMEMLIMIT, GOGC, HTTP_PROXYAlloy, automatiquement
Vos propres variablesTEMPO_ENDPOINT, CLUSTER_NAMEAlloy, seulement via sys.env()
Variables OpenTelemetryOTEL_SERVICE_NAME, OTEL_EXPORTER_OTLP_ENDPOINTLe SDK de l’application
L’exceptionOTEL_RESOURCE_ATTRIBUTESAlloy, via otelcol.processor.resourcedetection
Comment ces résultats ont été vérifiés : les comportements de cet article ont été testés le 4 novembre 2026 avec Grafana Alloy v1.21.3, en envoyant de vraies traces OTLP. La liste des variables évolue : consultez la documentation de votre version.

2. Les variables lues nativement par Alloy #

Mémoire, runtime Go, proxy et paquets Linux.

Mémoire et runtime Go #

Alloy étant écrit en Go, il respecte les variables du runtime. Ce sont les seules, avec celles du proxy, que la documentation d'Alloy liste comme lues automatiquement.

VariableRôleDéfaut
GOMEMLIMITLimite mémoire souple du ramasse-miettes (900MiB, 1GiB…)Calculée (voir ci-dessous)
AUTOMEMLIMITPart de la limite du conteneur utilisée pour calculer GOMEMLIMIT (0 à 1)0,9
AUTOMEMLIMIT_EXPERIMENTsystem : se baser sur la mémoire totale du système–
GOGCPourcentage cible du ramasse-miettes ; off le désactive100
GOMAXPROCSNombre de threads exécutant du code Go simultanémentNon précisé
GOTRACEBACKDétail des traces lors d’un panicNon précisé
GODEBUGOptions de débogage : x509usefallbackroots, netdns–
PPROF_MUTEX_PROFILING_PERCENTPart des mutex échantillonnés0,1 %
PPROF_BLOCK_PROFILING_RATEFréquence de suivi des blocages de goroutines10000
GOMEMLIMIT n'est pas une limite stricte : la documentation le rappelle explicitement. Gardez une marge sous la limite de votre conteneur, sinon le processus peut quand même être tué (OOM).

Proxy sortant #

VariableRôle
HTTP_PROXYProxy des requêtes HTTP
HTTPS_PROXYProxy des requêtes HTTPS
NO_PROXYExceptions séparées par des virgules : adresses IP, blocs CIDR, domaines ou *

Paquets Linux (systemd) #

Avec les paquets deb et rpm, le service lit ses réglages dans /etc/default/alloy (Debian, Ubuntu) ou /etc/sysconfig/alloy (RHEL, Fedora, SUSE). Après modification : sudo systemctl restart alloy.

VariableRôle
CONFIG_FILEFichier de configuration du moteur par défaut
CUSTOM_ARGSOptions supplémentaires, par exemple --server.http.listen-addr=0.0.0.0:12345
ALLOY_OTEL_MODEActive le moteur OpenTelemetry au lieu du moteur par défaut
OTEL_CONFIG_FILE, OTEL_CUSTOM_ARGSÉquivalents pour le moteur OpenTelemetry

3. Vos variables : sys.env() #

Lecture explicite, valeurs par défaut et pièges.

Lire une variable dans la configuration #

Toute autre variable doit être lue explicitement avec sys.env(). Si elle n'existe pas, la fonction renvoie une chaîne vide, sans erreur : c'est pourquoi on l'associe à coalesce() pour prévoir une valeur par défaut.

otelcol.exporter.otlp "tempo" {
  client {
    // host:port pour cet exportateur gRPC ; valeur par défaut si la variable est absente
    endpoint = coalesce(sys.env("TEMPO_ENDPOINT"), "tempo:4317")
    headers  = { "X-Scope-OrgID" = coalesce(sys.env("TEMPO_TENANT"), "anonymous") }
    tls {
      insecure = true
    }
  }
}
Piège : sans valeur par défaut, l'échec survient plus loin. Avec endpoint = sys.env("ABSENTE") sur otelcol.exporter.otlphttp, alloy run s'arrête sur « at least one endpoint must be specified ». Le message ne cite pas la variable : pensez à elle en premier.

Une variable d'environnement n'est lue qu'au démarrage du processus : la changer impose de redémarrer Alloy. Pour une valeur qui doit pouvoir changer à chaud, utilisez local.file ou remote.http. Les secrets sont traités dans la leçon Gestion des secrets.

4. OTEL_RESOURCE_ATTRIBUTES : la variable que l'on peut lire #

Le détecteur env, l'option override et son piège.

Le composant resourcedetection #

Le composant otelcol.processor.resourcedetection possède un détecteur env, activé par défaut (detectors = ["env"]). Il lit OTEL_RESOURCE_ATTRIBUTES au format cle1=valeur1,cle2=valeur2 et ajoute ces attributs à toutes les données qui le traversent. C'est le moyen d'indiquer l'environnement ou le cluster une seule fois, au niveau du collecteur.

Effet mesuré de OTEL_RESOURCE_ATTRIBUTES selon la configuration d'Alloy

Le piège d'override #

Ces quatre résultats ont été mesurés avec une même trace envoyée par une application nommée from-app. Trois enseignements :

  • Sans le composant, la variable n'a aucun effet. La définir pour Alloy ne suffit pas.
  • override vaut true par défaut : un attribut déjà présent est remplacé. Si la variable contient service.name, toutes les applications qui passent par cet Alloy prennent ce nom. Vos services fusionnent alors dans Tempo.
  • OTEL_SERVICE_NAME est ignorée par ce détecteur, contrairement à un SDK où elle a priorité.
Bonne pratique : sur un Alloy qui reçoit plusieurs applications, utilisez override = false et limitez la variable aux attributs du site : deployment.environment.name, k8s.cluster.name, cloud.region. Ne mettez jamais service.name.

5. Les variables OTEL_* côté application #

Pointer un SDK vers Alloy avec les variables standard.

Variables générales du SDK #

VariableRôleDéfaut (spécification)
OTEL_SERVICE_NAMENom du service ; prioritaire sur le service.name de OTEL_RESOURCE_ATTRIBUTES–
OTEL_RESOURCE_ATTRIBUTESAttributs de ressource : cle=valeur,cle2=valeur2–
OTEL_SDK_DISABLEDDésactive le SDKfalse
OTEL_LOG_LEVELNiveau de journalisation du SDKinfo
OTEL_PROPAGATORSPropagation du contextetracecontext,baggage
OTEL_TRACES_SAMPLERÉchantillonneurparentbased_always_on
OTEL_TRACES_SAMPLER_ARGArgument de l’échantillonneur (ex. 0.1)–
OTEL_TRACES_EXPORTER, OTEL_METRICS_EXPORTER, OTEL_LOGS_EXPORTERExportateur de chaque signalotlp

Variables de l'exportateur OTLP #

Chacune existe aussi par signal, par exemple OTEL_EXPORTER_OTLP_TRACES_ENDPOINT, qui l'emporte alors sur la variable générale.

VariableRôleDéfaut
OTEL_EXPORTER_OTLP_ENDPOINTURL de destinationgRPC http://localhost:4317, HTTP http://localhost:4318
OTEL_EXPORTER_OTLP_PROTOCOLgrpc, http/protobuf ou http/jsonhttp/protobuf
OTEL_EXPORTER_OTLP_HEADERSEn-têtes : cle=valeur,cle2=valeur2–
OTEL_EXPORTER_OTLP_TIMEOUTDélai maximal d’un envoi, nouvelles tentatives comprises10s
OTEL_EXPORTER_OTLP_COMPRESSIONgzip ou noneChoix du SDK
OTEL_EXPORTER_OTLP_CERTIFICATECertificat de confiance TLS–
Le piège du chemin : avec OTEL_EXPORTER_OTLP_ENDPOINT=http://alloy:4318, le SDK ajoute /v1/traces. Avec la variable par signal OTEL_EXPORTER_OTLP_TRACES_ENDPOINT, l'URL est utilisée telle quelle : indiquez alors http://alloy:4318/v1/traces. Autre erreur fréquente : envoyer du http/protobuf (protocole par défaut) sur le port gRPC 4317.

Exemple complet : une application et Alloy #

L'application reçoit ses variables standard ; Alloy reçoit celles qui concernent le site. Sa configuration, validée avec alloy validate et testée de bout en bout, reprend explicitement la destination :

otelcol.receiver.otlp "default" {
  grpc {
    endpoint = "0.0.0.0:4317"
  }
  http {
    endpoint = "0.0.0.0:4318"
  }
  output {
    traces  = [otelcol.processor.resourcedetection.env.input]
    metrics = [otelcol.processor.resourcedetection.env.input]
    logs    = [otelcol.processor.resourcedetection.env.input]
  }
}

// Ajoute les attributs de OTEL_RESOURCE_ATTRIBUTES sans écraser ceux des applications
otelcol.processor.resourcedetection "env" {
  detectors = ["env"]
  override  = false
  output {
    traces  = [otelcol.processor.batch.default.input]
    metrics = [otelcol.processor.batch.default.input]
    logs    = [otelcol.processor.batch.default.input]
  }
}

otelcol.processor.batch "default" {
  output {
    traces  = [otelcol.exporter.otlphttp.backend.input]
    metrics = [otelcol.exporter.otlphttp.backend.input]
    logs    = [otelcol.exporter.otlphttp.backend.input]
  }
}

// Reprend explicitement la variable standard : sans sys.env, elle ne serait pas lue
otelcol.exporter.otlphttp "backend" {
  client {
    endpoint = sys.env("OTEL_EXPORTER_OTLP_ENDPOINT")
    headers  = { "X-Scope-OrgID" = coalesce(sys.env("BACKEND_TENANT"), "anonymous") }
  }
}
services:
  alloy:
    image: grafana/alloy:latest
    command: run /etc/alloy/config.alloy --server.http.listen-addr=0.0.0.0:12345 --storage.path=/var/lib/alloy/data
    volumes:
      - ./config.alloy:/etc/alloy/config.alloy:ro
    environment:
      OTEL_EXPORTER_OTLP_ENDPOINT: http://tempo:4318
      OTEL_RESOURCE_ATTRIBUTES: deployment.environment.name=prod,k8s.cluster.name=eu-west
      GOMEMLIMIT: 900MiB
    deploy:
      resources:
        limits:
          memory: 1G

  app:
    image: mon-registre/commandes:1.4.0
    environment:
      OTEL_SERVICE_NAME: commandes
      OTEL_RESOURCE_ATTRIBUTES: service.version=1.4.0,team=paiements
      OTEL_EXPORTER_OTLP_ENDPOINT: http://alloy:4318
      OTEL_EXPORTER_OTLP_PROTOCOL: http/protobuf
      OTEL_TRACES_SAMPLER: parentbased_traceidratio
      OTEL_TRACES_SAMPLER_ARG: "0.1"

À l'essai, la trace arrive bien sur /v1/traces du backend : otelcol.exporter.otlphttp ajoute le chemin de chaque signal, comme un SDK avec la variable générale.

Correspondance : otelcol.exporter.otlphttp attend une URL (http://tempo:4318) et otelcol.exporter.otlp, en gRPC, un host:port (tempo:4317). Sans endpoint, ce dernier est refusé au chargement (« missing required attribute endpoint »), même si OTEL_EXPORTER_OTLP_ENDPOINT est définie.

6. Le moteur OpenTelemetry : alloy otel #

La syntaxe ${env:VAR} du Collector, en préversion publique.

Une configuration YAML du Collector #

Le binaire d'Alloy embarque aussi un moteur OpenTelemetry, lancé avec alloy otel --config=otel.yaml. Il lit un fichier YAML au format du Collector : on y retrouve la syntaxe ${env:VARIABLE}, au lieu de sys.env(). Nous avons vérifié cette substitution et le détecteur env sur Alloy v1.21.3.

receivers:
  otlp:
    protocols:
      http:
        endpoint: ${env:RECEIVER_ENDPOINT}
processors:
  resourcedetection:
    detectors: [env]
exporters:
  otlphttp:
    endpoint: ${env:OTEL_EXPORTER_OTLP_ENDPOINT}
service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [resourcedetection]
      exporters: [otlphttp]
Ce moteur est en préversion publique : la documentation prévient que des changements incompatibles sont possibles. Pour la production, le moteur par défaut (alloy run) reste le choix stable.

7. Kubernetes et bonnes pratiques #

Helm, Beyla, erreurs courantes et commandes.

Sur Kubernetes #

# values.yaml du chart Helm grafana/alloy
alloy:
  extraEnv:
    - name: OTEL_RESOURCE_ATTRIBUTES
      value: "deployment.environment.name=prod,k8s.cluster.name=eu-west"
    - name: GOMEMLIMIT
      value: "900MiB"
  resources:
    limits:
      memory: 1Gi

Cas particulier de Beyla : le composant beyla.ebpf peut reprendre, via extra_resource_labels, des attributs fournis par la variable OTEL_RESOURCE_ATTRIBUTES du service observé. C'est la variable de l'application qui compte, pas celle d'Alloy.

À retenir #

  • Définir OTEL_* pour Alloy ne configure pas Alloy, sauf OTEL_RESOURCE_ATTRIBUTES avec resourcedetection.
  • Lisez vos valeurs avec sys.env(), et prévoyez une valeur par défaut avec coalesce().
  • Utilisez override = false sur un Alloy partagé, et jamais service.name dans sa variable.
  • Réservez OTEL_SERVICE_NAME et OTEL_EXPORTER_OTLP_* aux applications.
  • Fixez GOMEMLIMIT sous la limite mémoire du conteneur.

Commandes à connaître #

# Vérifier la configuration avec les variables de l'environnement courant
TEMPO_ENDPOINT=tempo:4317 alloy validate config.alloy

# Valider un fichier sans le lancer, puis le démarrer
alloy fmt config.alloy
alloy run config.alloy --server.http.listen-addr=127.0.0.1:12345

# Voir les variables réellement reçues par le processus
docker compose exec alloy env | grep -E 'OTEL_|GOMEM'

# Tester le pipeline avec une trace minimale (OTLP/HTTP)
curl -X POST -H 'Content-Type: application/json' -d @trace.json http://localhost:4318/v1/traces

# Moteur OpenTelemetry (préversion publique)
alloy otel --config=otel.yaml

Sources officielles #

📄 Variables d'environnement de Grafana Alloy : GOMEMLIMIT, sys.env et OTEL_RESOURCE_ATTRIBUTES →

Mi seguimiento

  • ⏱ Duración estimada : ≈ 23 min

Inicia sesión para seguir tu progreso y tomar notas. Iniciar sesión

💬 Hacer una pregunta

Glossaire de la formation

Observabilidad

La capacidad de conocer el estado interno de un sistema a partir de los datos que emite.Estos datos se clasifican en 3 pilares: logs (registros)métric...

Trazas distribuidas

Técnica (proveniente del pilar de Trazas) que permite seguir el recorrido completo de una solicitud a través de múltiples microservicios para identifi...

Métricas

Medidas numéricas recopiladas a intervalos regulares (ej: CPU, RAM, tiempo de respuesta) utilizadas para evaluar el estado de salud general de un sist...

Perfilado continuo (Continuous Profiling)

Análisis constante de la ejecución de código en producción para identificar con precisión qué líneas de código o funciones consumen más recursos (CPU,...

Access Log (Registro de acceso)

Archivo de registro que guarda las solicitudes procesadas por un servidor web (Apache, Nginx, Lighttpd, etc.). Permite rastrear la actividad del servi...

Client IP (IP del Cliente)

La dirección IP del usuario que realiza la solicitud hacia el servidor web. Cuando un usuario pasa por un Load Balancer o un proxy (ej: Cloudflare), l...

Timestamp (Marca de tiempo)

La fecha y la hora exactas en las que el servidor recibió la solicitud.Configuración: %t en Apache, $time_local o $time_iso8601 en Nginx.

Request (Solicitud)

La línea de solicitud inicial del cliente. Generalmente incluye el método HTTP (ej: GET), la URL solicitada y la versión del protocolo HTTP.Configurac...

Status Code (Código de estado)

El código de estado HTTP final devuelto por el servidor al cliente (ej: 200 para un éxito, 404 para recurso no encontrado).Configuración: %>s en Apach...

Size (Tamaño)

El volumen de datos devuelto al cliente, medido en bytes (generalmente sin los encabezados HTTP).Configuración: %b u %O en Apache, $body_bytes_sent en...

Referrer (Referente)

La URL de la página web desde la que el cliente hizo clic o siguió un enlace para acceder al recurso actual.Configuración: %{Referer}i en Apache, $htt...

User-Agent

La información de identificación proporcionada por el cliente sobre su navegador, su sistema operativo y su dispositivo. Su estructura estándar a menu...

Response Time (Tiempo de respuesta)

El tiempo total que tarda el servidor en procesar la solicitud y devolver la respuesta al cliente.Configuración: %D (microsegundos) o %T (segundos) en...

Artículos recomendados

Envoyer des traces vers Tempo : instrumentation OpenTelemetry et Alloy

Produire et acheminer des traces vers Tempo : auto-instrumentation Python/Java/Node, SDK manuel, ...

Configuration de Grafana Alloy : syntaxe, ports et premiers composants

Dans le cadre d'une formation Grafana ou formation observabilité, maîtrisez la syntaxe déclarativ...

OpenTelemetry : Instrumentation Automatique vs Manuelle

Comprenez les différences entre l'instrumentation automatique et manuelle avec OpenTelemetry, leu...

Instrumenter ses applications pour Jaeger avec OpenTelemetry

Envoyer des traces à Jaeger avec OpenTelemetry : auto-instrumentation (Java, Python, Node.js), SD...

Bonnes Pratiques Grafana Alloy : Optimiser sa Collecte de Télémétrie

Découvrez les règles d'or pour configurer Grafana Alloy de manière robuste : modularité, gestion ...

Grafana Alloy et les traces : OTLP, Jaeger et Zipkin vers Tempo

Plongez dans le traitement des traces distribuées. Apprenez à ingérer des traces OTLP, Jaeger ou ...

Grafana Alloy vs OpenTelemetry Collector : Lequel choisir ?

Comparaison détaillée entre Grafana Alloy et l'OpenTelemetry Collector. Découvrez les avantages, ...

Grafana Alloy : Collecter les métriques système et les logs locaux

Découvrez comment configurer Grafana Alloy pour superviser le serveur sur lequel il s'exécute, av...

Référence des Composants Grafana Alloy

Un guide de référence complet sur tous les composants disponibles dans Grafana Alloy, organisé pa...

Apoyar

♥ APOYAR

Apoya RousselTM Learning

Los cursos, artículos, prácticas y certificados siguen siendo gratuitos y sin publicidad intrusiva. Una contribución libre, por el importe que elijas, financia el alojamiento, los entornos de prácticas y nuevos contenidos.

Contribuir con PayPal Importe libre · tarjeta o cuenta PayPalMás información
QR code PayPal
O escanea este código QR con tu teléfono

¡Gracias, cada contribución cuenta!