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.
| Famille | Exemples | Qui la lit ? |
|---|---|---|
| Variables natives d’Alloy | GOMEMLIMIT, GOGC, HTTP_PROXY | Alloy, automatiquement |
| Vos propres variables | TEMPO_ENDPOINT, CLUSTER_NAME | Alloy, seulement via sys.env() |
| Variables OpenTelemetry | OTEL_SERVICE_NAME, OTEL_EXPORTER_OTLP_ENDPOINT | Le SDK de l’application |
| L’exception | OTEL_RESOURCE_ATTRIBUTES | Alloy, 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.
| Variable | Rôle | Défaut |
|---|---|---|
GOMEMLIMIT | Limite mémoire souple du ramasse-miettes (900MiB, 1GiB…) | Calculée (voir ci-dessous) |
AUTOMEMLIMIT | Part de la limite du conteneur utilisée pour calculer GOMEMLIMIT (0 à 1) | 0,9 |
AUTOMEMLIMIT_EXPERIMENT | system : se baser sur la mémoire totale du système | – |
GOGC | Pourcentage cible du ramasse-miettes ; off le désactive | 100 |
GOMAXPROCS | Nombre de threads exécutant du code Go simultanément | Non précisé |
GOTRACEBACK | Détail des traces lors d’un panic | Non précisé |
GODEBUG | Options de débogage : x509usefallbackroots, netdns | – |
PPROF_MUTEX_PROFILING_PERCENT | Part des mutex échantillonnés | 0,1 % |
PPROF_BLOCK_PROFILING_RATE | Fréquence de suivi des blocages de goroutines | 10000 |
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 #
| Variable | Rôle |
|---|---|
HTTP_PROXY | Proxy des requêtes HTTP |
HTTPS_PROXY | Proxy des requêtes HTTPS |
NO_PROXY | Exceptions 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.
| Variable | Rôle |
|---|---|
CONFIG_FILE | Fichier de configuration du moteur par défaut |
CUSTOM_ARGS | Options supplémentaires, par exemple --server.http.listen-addr=0.0.0.0:12345 |
ALLOY_OTEL_MODE | Active 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. Avecendpoint = sys.env("ABSENTE")surotelcol.exporter.otlphttp,alloy runs'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.
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.
overridevauttruepar défaut : un attribut déjà présent est remplacé. Si la variable contientservice.name, toutes les applications qui passent par cet Alloy prennent ce nom. Vos services fusionnent alors dans Tempo.OTEL_SERVICE_NAMEest ignorée par ce détecteur, contrairement à un SDK où elle a priorité.
Bonne pratique : sur un Alloy qui reçoit plusieurs applications, utilisezoverride = falseet limitez la variable aux attributs du site :deployment.environment.name,k8s.cluster.name,cloud.region. Ne mettez jamaisservice.name.
5. Les variables OTEL_* côté application #
Pointer un SDK vers Alloy avec les variables standard.
Variables générales du SDK #
| Variable | Rôle | Défaut (spécification) |
|---|---|---|
OTEL_SERVICE_NAME | Nom du service ; prioritaire sur le service.name de OTEL_RESOURCE_ATTRIBUTES | – |
OTEL_RESOURCE_ATTRIBUTES | Attributs de ressource : cle=valeur,cle2=valeur2 | – |
OTEL_SDK_DISABLED | Désactive le SDK | false |
OTEL_LOG_LEVEL | Niveau de journalisation du SDK | info |
OTEL_PROPAGATORS | Propagation du contexte | tracecontext,baggage |
OTEL_TRACES_SAMPLER | Échantillonneur | parentbased_always_on |
OTEL_TRACES_SAMPLER_ARG | Argument de l’échantillonneur (ex. 0.1) | – |
OTEL_TRACES_EXPORTER, OTEL_METRICS_EXPORTER, OTEL_LOGS_EXPORTER | Exportateur de chaque signal | otlp |
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.
| Variable | Rôle | Défaut |
|---|---|---|
OTEL_EXPORTER_OTLP_ENDPOINT | URL de destination | gRPC http://localhost:4317, HTTP http://localhost:4318 |
OTEL_EXPORTER_OTLP_PROTOCOL | grpc, http/protobuf ou http/json | http/protobuf |
OTEL_EXPORTER_OTLP_HEADERS | En-têtes : cle=valeur,cle2=valeur2 | – |
OTEL_EXPORTER_OTLP_TIMEOUT | Délai maximal d’un envoi, nouvelles tentatives comprises | 10s |
OTEL_EXPORTER_OTLP_COMPRESSION | gzip ou none | Choix du SDK |
OTEL_EXPORTER_OTLP_CERTIFICATE | Certificat de confiance TLS | – |
Le piège du chemin : avecOTEL_EXPORTER_OTLP_ENDPOINT=http://alloy:4318, le SDK ajoute/v1/traces. Avec la variable par signalOTEL_EXPORTER_OTLP_TRACES_ENDPOINT, l'URL est utilisée telle quelle : indiquez alorshttp://alloy:4318/v1/traces. Autre erreur fréquente : envoyer duhttp/protobuf(protocole par défaut) sur le port gRPC4317.
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.otlphttpattend une URL (http://tempo:4318) etotelcol.exporter.otlp, en gRPC, unhost:port(tempo:4317). Sansendpoint, ce dernier est refusé au chargement (« missing required attribute endpoint »), même siOTEL_EXPORTER_OTLP_ENDPOINTest 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: 1GiCas 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, saufOTEL_RESOURCE_ATTRIBUTESavecresourcedetection. - Lisez vos valeurs avec
sys.env(), et prévoyez une valeur par défaut aveccoalesce(). - Utilisez
override = falsesur un Alloy partagé, et jamaisservice.namedans sa variable. - Réservez
OTEL_SERVICE_NAMEetOTEL_EXPORTER_OTLP_*aux applications. - Fixez
GOMEMLIMITsous 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.yamlSources officielles #
Mon suivi
Connectez-vous pour suivre votre progression et prendre des notes. Se connecter
Glossaire de la formation
Observabilité
La capacité à connaître l'état interne d'un système à partir des données qu'il émet.Ces données sont classées en 3 piliers : logsmétriquestracesprofil...
Traces distribuées
Technique (issue du pilier des Traces) permettant de suivre le cheminement complet d'une requête à travers de multiples micro-services pour identifier...
Métriques
Mesures numériques collectées à intervalles réguliers (ex: CPU, RAM, temps de réponse) utilisées pour évaluer l'état de santé global d'un système au f...
Profilage en continu (Continuous Profiling)
Analyse constante de l'exécution du code en production pour identifier avec précision quelles lignes de code ou fonctions consomment le plus de ressou...
Access Log
Fichier de journalisation enregistrant les requêtes traitées par un serveur web (Apache, Nginx, Lighttpd, etc.). Il permet de tracer l'activité du ser...
Client IP
L'adresse IP de l'utilisateur effectuant la requête vers le serveur web. Lorsqu'un utilisateur passe par un Load Balancer ou un proxy (ex: Cloudflare)...
Timestamp
La date et l'heure exactes auxquelles la requête a été reçue par le serveur.Configuration : %t dans Apache, $time_local ou $time_iso8601 dans Nginx.
Request
La ligne de requête initiale du client. Elle comprend généralement la méthode HTTP (ex: GET), l'URL demandée et la version du protocole HTTP.Configura...
Status Code
Le code de statut HTTP final renvoyé par le serveur au client (ex : 200 pour un succès, 404 pour ressource non trouvée).Configuration : %>s dans Apach...
Size
Le volume des données renvoyées au client, mesuré en octets (généralement sans les en-têtes HTTP).Configuration : %b ou %O dans Apache, $body_bytes_se...
Referrer
L'URL de la page web depuis laquelle le client a cliqué ou suivi un lien pour accéder à la ressource actuelle.Configuration : %{Referer}i dans Apache,...
User-Agent
Les informations d'identification fournies par le client concernant son navigateur, son système d'exploitation et son appareil. Sa structure standard ...
Response Time
La durée totale prise par le serveur pour traiter la requête et renvoyer la réponse au client.Configuration : %D (microsecondes) ou %T (secondes) dans...
Grafana Alloy
Collecteur de télémétrie open source et flexible, successeur de Grafana Agent. Il est conçu pour collecter, transformer et exporter des logs, métrique...
River
Langage de configuration déclaratif utilisé par Grafana Alloy, inspiré de HCL (Terraform). Il permet de définir des pipelines de télémétrie complexes ...
Grafana Loki
Système de journalisation (logs) multi-tenant, hautement disponible et inspiré de Prometheus. Il est conçu pour être très économe en ressources en n'i...
Articles recommandés
OpenTelemetry Collector, Grafana Alloy et Bindplane : comparer trois approches des pipelines de télémétrie
Comparatif détaillé de trois façons de gérer des pipelines de télémétrie : l'OpenTelemetry Collec...
Référence des Composants Grafana Alloy
Un guide de référence complet sur tous les composants disponibles dans Grafana Alloy, organisé pa...
Les concepts fondamentaux d'OpenTelemetry : signaux, ressources, contexte et maturité
Le vocabulaire indispensable d'OpenTelemetry : les quatre signaux, API et SDK, ressource et instr...
Grafana Alloy et Prometheus : collecter et envoyer des métriques
Apprenez à configurer Grafana Alloy pour collecter, transformer et envoyer des métriques en utili...
OTLP expliqué : comprendre le protocole OpenTelemetry
Découvrez le protocole OTLP expliqué simplement. Comprendre les différences entre gRPC et HTTP po...
Grafana Alloy : Déploiement Avancé et Clustering
Maîtrisez le déploiement avancé de Grafana Alloy en mode clustering. Comprenez ses avantages pour...
Grafana Alloy : L'importance de l'auto-supervision (Self-Monitoring)
Découvrez pourquoi et comment configurer Grafana Alloy pour qu'il se supervise lui-même, en colle...
Grafana Alloy vs Grafana Agent vs Promtail : Lequel choisir ?
Découvrez l'évolution des collecteurs de télémétrie de l'écosystème Grafana. Comparatif détaillé ...
Collecter des logs vers Loki : Alloy, Promtail, Docker et OpenTelemetry
Envoyer des logs vers Loki : Grafana Alloy, Promtail, driver Docker, OTLP, bons labels, parsing e...