Commandes Grafana Alloy
Grafana Alloy est une distribution OpenTelemetry flexible et neutre vis-à-vis des fournisseurs pour collecter, traiter et exporter des données de télémétrie (métriques, journaux, traces). Successeur de Grafana Agent, il utilise un langage de configuration basé sur les composants.
Installation
Référentiels de paquets Linux
Debian/Ubuntu
sudo mkdir -p /etc/apt/keyrings/
wget -qO - https://apt.grafana.com/gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/grafana.gpg
echo "deb [signed-by=/etc/apt/keyrings/grafana.gpg] https://apt.grafana.com stable main" | sudo tee /etc/apt/sources.list.d/grafana.list
sudo apt-get update
sudo apt-get install alloy
RHEL/CentOS/Fedora
sudo tee /etc/yum.repos.d/grafana.repo << EOF
[grafana]
name=grafana
baseurl=https://rpm.grafana.com
repo_gpgcheck=1
enabled=1
gpgcheck=1
gpgkey=https://rpm.grafana.com/gpg.key
EOF
sudo dnf install alloy
macOS
brew install grafana/grafana/alloy
alloy --version
Téléchargement binaire
# Télécharger la dernière version
wget https://github.com/grafana/alloy/releases/download/v1.14.0/alloy-v1.14.0-linux-amd64.zip
unzip alloy-v1.14.0-linux-amd64.zip
sudo mv alloy /usr/local/bin/
alloy --version
Docker
docker pull grafana/alloy:latest
docker run -v /path/to/config.alloy:/etc/alloy/config.alloy \
grafana/alloy:latest run /etc/alloy/config.alloy --server.http.listen-addr=0.0.0.0:12345
Graphique Helm
helm repo add grafana https://grafana.github.io/helm-charts
helm repo update
helm install alloy grafana/alloy --namespace monitoring --create-namespace \
-f values.yaml
Commandes de base
| Commande | Description |
|---|---|
alloy run config.alloy | Exécuter Alloy avec le fichier de configuration spécifié |
alloy run config.alloy --server.http.listen-addr=0.0.0.0:12345 | Exécuter avec une adresse de serveur HTTP personnalisée |
alloy fmt config.alloy | Formater et valider le fichier de configuration (mode essai) |
alloy fmt -w config.alloy | Formater le fichier de configuration en place |
alloy tools parse config.alloy | Analyser et valider la syntaxe de la configuration |
alloy tools lint config.alloy | Linter la configuration pour les problèmes |
alloy --version | Afficher la version d’Alloy |
alloy --help | Afficher l’aide |
alloy run --help | Afficher les options de la commande run |
Concepts de base de configuration
Extension de fichier et syntaxe
Alloy utilise l’extension de fichier .alloy avec un langage de configuration basé sur les composants (similaire à HCL).
Structure de base
// Les commentaires utilisent //
// Instanciation de composant : <component_type>.<unique_name> { ... }
prometheus.scrape "example" {
targets = [{"__address__" = "localhost:9090"}]
forward_to = [prometheus.remote_write.grafana.receiver]
}
// Exporter les données d'un composant à un autre
prometheus.remote_write "grafana" {
endpoint {
url = "https://prometheus.grafana.net/api/prom/push"
headers = {
"Authorization" = "Bearer ${GRAFANA_TOKEN}"
}
}
}
Variables et secrets
// Variables d'environnement
GRAFANA_TOKEN = env("GRAFANA_TOKEN")
PROMETHEUS_URL = env("PROMETHEUS_URL")
// Variables locales
local "my_targets" {
value = [
{"__address__" = "localhost:9090"},
{"__address__" = "localhost:9100"},
]
}
// Références de variables
prometheus.scrape "nodes" {
targets = local.my_targets.value
}
Blocs d’arguments et d’exportation
// La plupart des composants acceptent des arguments
prometheus.scrape "example" {
targets = [{"__address__" = "localhost:9090"}]
scrape_interval = "30s"
scrape_timeout = "10s"
forward_to = [prometheus.remote_write.grafana.receiver]
}
// Les composants exportent des données (visibles dans l'interface utilisateur sous Exports)
// Exemple : prometheus.scrape exporte scraped_targets et targets
Composants - Sources
Scrape Prometheus
prometheus.scrape "kubernetes" {
targets = discovery.kubernetes.nodes.targets
scrape_interval = "30s"
scrape_timeout = "10s"
metrics_path = "/metrics"
scheme = "http"
forward_to = [prometheus.relabel.drop_internal.receiver]
}
Source de fichier Loki
loki.source.file "app_logs" {
targets = [
{
__path__ = "/var/log/app/*.log",
job = "app",
env = "production",
}
]
forward_to = [loki.relabel.add_labels.receiver]
}
Récepteur OpenTelemetry (OTLP)
otelcol.receiver.otlp "default" {
grpc {
endpoint = "0.0.0.0:4317"
}
http {
endpoint = "0.0.0.0:4318"
}
output {
traces = [otelcol.processor.batch.default.input]
metrics = [otelcol.processor.batch.default.input]
logs = [otelcol.processor.batch.default.input]
}
}
Récepteur Prometheus Remote Write
prometheus.receive_http "example" {
http {
address = "0.0.0.0:9009"
}
forward_to = [prometheus.relabel.example.receiver]
}
Serveur API Loki
loki.relabel "add_labels" {
forward_to = [loki.write.grafana.receiver]
rule {
source_labels = ["__path__"]
target_label = "job"
replacement = "app-logs"
}
}
Composants - Processeurs
Processeur batch
otelcol.processor.batch "default" {
send_batch_size = 1000
timeout = "10s"
send_batch_max_size = 2000
output {
traces = [otelcol.exporter.otlp.grafana.input]
metrics = [otelcol.exporter.prometheus.grafana.input]
logs = [otelcol.exporter.loki.grafana.input]
}
}
Processeur de filtre
otelcol.processor.filter "drop_internal" {
metrics {
exclude {
match_type = "regexp"
regexp = "internal_.*"
}
}
output {
metrics = [otelcol.exporter.prometheus.grafana.input]
}
}
Processeur de détection de ressources
otelcol.processor.resourcedetection "default" {
detectors = ["env", "system", "gcp", "aws", "azure", "docker", "kubernetes"]
output {
traces = [otelcol.processor.batch.default.input]
metrics = [otelcol.processor.batch.default.input]
logs = [otelcol.processor.batch.default.input]
}
}
Processeur d’attributs
otelcol.processor.attributes "add_env" {
action {
key = "environment"
value = "production"
action = "insert"
}
action {
key = "pod_name"
from_attribute = "k8s.pod.name"
action = "insert"
}
output {
traces = [otelcol.processor.batch.default.input]
metrics = [otelcol.processor.batch.default.input]
logs = [otelcol.processor.batch.default.input]
}
}
Processeur de limiteur de mémoire
otelcol.processor.memory_limiter "default" {
check_interval = "5s"
limit_mib = 512
spike_limit_mib = 256
output {
traces = [otelcol.processor.batch.default.input]
metrics = [otelcol.processor.batch.default.input]
logs = [otelcol.processor.batch.default.input]
}
}
Processeur d’étendue (traces)
otelcol.processor.span "extract_attributes" {
name {
to_attributes {
rules = ["^/api/(?P<version>v\\d)/(?P<resource>\\w+)"]
}
}
output {
traces = [otelcol.processor.batch.default.input]
}
}
Composants - Exportateurs
Prometheus Remote Write
prometheus.remote_write "grafana" {
endpoint {
url = "https://prometheus.grafana.net/api/prom/push"
basic_auth {
username = "GRAFANA_USER_ID"
password = "${GRAFANA_TOKEN}"
}
headers = {
"X-Custom-Header" = "value"
}
tls_config {
insecure_skip_verify = false
}
}
wal {
enabled = true
directory = "/var/lib/alloy/wal"
}
queue_settings {
capacity = 10000
}
}
Écriture Loki
loki.write "grafana" {
endpoint {
url = "https://logs.grafana.net/loki/api/v1/push"
basic_auth {
username = "GRAFANA_USER_ID"
password = "${GRAFANA_TOKEN}"
}
}
tenant_id = "production"
}
Exportateur OpenTelemetry (OTLP)
otelcol.exporter.otlp "grafana_cloud" {
client {
endpoint = "tempo.grafana.net:4317"
auth = otelcol.auth.basic "grafana" {}
tls {
insecure = false
}
}
retry_on_failure {
enabled = true
initial_interval = "5s"
max_interval = "30s"
max_elapsed_time = "5m"
}
}
Authentification OTLP
otelcol.auth.basic "grafana" {
username = "GRAFANA_USER_ID"
password = "${GRAFANA_TOKEN}"
}
// OTLP avec authentification de base
otelcol.exporter.otlp "example" {
client {
endpoint = "tempo.grafana.net:4317"
auth = otelcol.auth.basic.grafana.handler
}
}
Exportateur Prometheus (style Node Exporter)
prometheus.exporter.unix "local_system" {
disabled_collectors = ["netdev", "netstat"]
}
prometheus.scrape "local_system" {
targets = prometheus.exporter.unix.local_system.targets
forward_to = [prometheus.remote_write.grafana.receiver]
}
Composants - Découverte
Découverte Kubernetes
discovery.kubernetes "cluster" {
role = "pod"
namespaces {
names = ["default", "monitoring", "production"]
}
}
prometheus.scrape "kubernetes" {
targets = discovery.kubernetes.cluster.targets
forward_to = [prometheus.remote_write.grafana.receiver]
relabel_configurations {
source_labels = ["__meta_kubernetes_pod_annotation_prometheus_io_scrape"]
regex = "true"
action = "keep"
}
}
Découverte Docker
discovery.docker "local" {
host = "unix:///var/run/docker.sock"
}
prometheus.scrape "docker" {
targets = discovery.docker.local.targets
forward_to = [prometheus.remote_write.grafana.receiver]
}
Découverte Consul
discovery.consul "example" {
server = "localhost:8500"
datacenter = "dc1"
services = ["prometheus", "app"]
}
prometheus.scrape "consul" {
targets = discovery.consul.example.targets
forward_to = [prometheus.remote_write.grafana.receiver]
}
Découverte basée sur fichier
discovery.file "dynamic_targets" {
files = ["/etc/alloy/targets.json"]
refresh_interval = "30s"
}
prometheus.scrape "file_targets" {
targets = discovery.file.dynamic_targets.targets
forward_to = [prometheus.remote_write.grafana.receiver]
}
Collecte de métriques
Scrape Prometheus avec relabeling
prometheus.scrape "prometheus" {
targets = [
{
__address__ = "prometheus.example.com:9090",
job = "prometheus",
},
{
__address__ = "alertmanager.example.com:9093",
job = "alertmanager",
},
]
metrics_path = "/metrics"
scrape_interval = "30s"
scrape_timeout = "10s"
relabel_configurations {
source_labels = ["__address__"]
target_label = "instance"
regex = "([^:]+)(?::\\d+)?"
replacement = "${1}"
}
metric_relabel_configurations {
source_labels = ["__name__"]
regex = "up|job|instance"
action = "keep"
}
forward_to = [prometheus.relabel.drop_internal.receiver]
}
Intégration Node Exporter
prometheus.exporter.unix "node_metrics" {
collectors = ["cpu", "diskstats", "filesystem", "loadavg", "meminfo", "netdev", "netstat"]
disabled_collectors = ["netdev"]
set_collectors = ["textfile"]
textfile_directory = "/var/lib/node_exporter/textfile_collector"
}
prometheus.scrape "node_exporter" {
targets = prometheus.exporter.unix.node_metrics.targets
forward_to = [prometheus.remote_write.grafana.receiver]
}
Point de terminaison de métriques personnalisé
prometheus.scrape "custom_app" {
targets = [
{
__address__ = "app.example.com:8080",
__metrics_path__ = "/api/metrics",
job = "custom-app",
env = "production",
},
]
scrape_interval = "15s"
forward_to = [prometheus.remote_write.grafana.receiver]
}
Collecte de journaux
Suivi de fichiers avec Loki
loki.source.file "application" {
targets = [
{
__path__ = "/var/log/app/app.log",
job = "app",
service = "web",
env = "production",
},
{
__path__ = "/var/log/app/error.log",
job = "app",
level = "error",
},
]
forward_to = [loki.relabel.add_labels.receiver]
}
Journaux Journal (systemd)
loki.source.journal "systemd" {
path = "/var/log/journal"
labels = {
job = "systemd",
}
forward_to = [loki.relabel.add_labels.receiver]
}
Analyse des journaux JSON
loki.relabel "parse_json" {
forward_to = [loki.process.extract_json.receiver]
rule {
source_labels = ["__path__"]
target_label = "filename"
}
}
loki.process "extract_json" {
forward_to = [loki.write.grafana.receiver]
stage {
json {
expressions = {
timestamp = "ts",
message = "msg",
level = "level",
service = "service",
}
}
}
stage {
labels {
values = {
level = "level",
service = "service",
}
}
}
stage {
timestamp {
source = "timestamp"
format = "Unix"
}
}
}
Journaux multilignes (traces de pile)
loki.process "multiline" {
forward_to = [loki.write.grafana.receiver]
stage {
multiline {
line_start_pattern = "^\\d{4}-\\d{2}-\\d{2}"
}
}
stage {
regex {
expression = "^(?P<timestamp>\\d{4}-\\d{2}-\\d{2}) (?P<level>\\w+) (?P<message>.*)"
}
}
stage {
labels {
values = {
level = "level",
}
}
}
}
Collecte de traces
Pipeline de traces OpenTelemetry
otelcol.receiver.otlp "app" {
grpc {
endpoint = "0.0.0.0:4317"
}
http {
endpoint = "0.0.0.0:4318"
}
output {
traces = [otelcol.processor.memory_limiter.default.input]
}
}
otelcol.processor.memory_limiter "default" {
check_interval = "5s"
limit_mib = 512
spike_limit_mib = 256
output {
traces = [otelcol.processor.batch.default.input]
}
}
otelcol.processor.batch "default" {
send_batch_size = 100
timeout = "10s"
output {
traces = [otelcol.exporter.otlp.grafana.input]
}
}
otelcol.exporter.otlp "grafana" {
client {
endpoint = "tempo.grafana.net:4317"
auth = otelcol.auth.basic.grafana.handler
}
}
otelcol.auth.basic "grafana" {
username = "GRAFANA_USER_ID"
password = "${GRAFANA_TOKEN}"
}
Récepteur Jaeger
otelcol.receiver.jaeger "default" {
protocols {
grpc {
endpoint = "0.0.0.0:14250"
}
thrift_http {
endpoint = "0.0.0.0:14268"
}
}
output {
traces = [otelcol.processor.batch.default.input]
}
}
Récepteur Zipkin
otelcol.receiver.zipkin "default" {
endpoint = "0.0.0.0:9411"
output {
traces = [otelcol.processor.batch.default.input]
}
}
Déploiement Kubernetes
Valeurs Helm (values.yaml)
config: |
otelcol.receiver.otlp "default" {
grpc {
endpoint = "0.0.0.0:4317"
}
http {
endpoint = "0.0.0.0:4318"
}
output {
traces = [otelcol.processor.batch.default.input]
}
}
otelcol.processor.batch "default" {
send_batch_size = 100
output {
traces = [otelcol.exporter.otlp.grafana.input]
}
}
otelcol.exporter.otlp "grafana" {
client {
endpoint = "tempo.grafana.net:4317"
auth = otelcol.auth.basic.grafana.handler
}
}
otelcol.auth.basic "grafana" {
username = "GRAFANA_USER_ID"
password = "${GRAFANA_TOKEN}"
}
alloy:
remoteConfigUrl: ""
serviceAccount:
create: true
rbac:
create: true
daemonset:
enabled: true
deployment:
enabled: true
replicas: 1
configMap:
content: ""
livenessProbe:
enabled: true
readinessProbe:
enabled: true
Installation Helm
# Installer avec des valeurs personnalisées
helm install alloy grafana/alloy \
--namespace monitoring \
--create-namespace \
-f values.yaml
# Mettre à jour l'installation existante
helm upgrade alloy grafana/alloy \
--namespace monitoring \
-f values.yaml
# Désinstaller
helm uninstall alloy --namespace monitoring
Exemple DaemonSet
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: alloy
namespace: monitoring
spec:
selector:
matchLabels:
app: alloy
template:
metadata:
labels:
app: alloy
spec:
serviceAccountName: alloy
containers:
- name: alloy
image: grafana/alloy:latest
args:
- run
- /etc/alloy/config.alloy
- --server.http.listen-addr=0.0.0.0:12345
ports:
- name: http
containerPort: 12345
- name: otlp-grpc
containerPort: 4317
- name: otlp-http
containerPort: 4318
volumeMounts:
- name: config
mountPath: /etc/alloy
- name: varlog
mountPath: /var/log
readOnly: true
volumes:
- name: config
configMap:
name: alloy-config
- name: varlog
hostPath:
path: /var/log
---
apiVersion: v1
kind: ConfigMap
metadata:
name: alloy-config
namespace: monitoring
data:
config.alloy: |
prometheus.scrape "kubernetes" {
targets = discovery.kubernetes.nodes.targets
forward_to = [prometheus.remote_write.grafana.receiver]
}
discovery.kubernetes "nodes" {
role = "node"
}
prometheus.remote_write "grafana" {
endpoint {
url = "https://prometheus.grafana.net/api/prom/push"
basic_auth {
username = "GRAFANA_USER_ID"
password = "${GRAFANA_TOKEN}"
}
}
}
Exemple ServiceMonitor
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: app-metrics
namespace: production
spec:
selector:
matchLabels:
app: myapp
endpoints:
- port: metrics
interval: 30s
path: /metrics
Configuration Docker
Fichier Compose
version: '3.8'
services:
alloy:
image: grafana/alloy:latest
container_name: alloy
command:
- run
- /etc/alloy/config.alloy
- --server.http.listen-addr=0.0.0.0:12345
ports:
- "12345:12345"
- "4317:4317"
- "4318:4318"
volumes:
- ./alloy-config.alloy:/etc/alloy/config.alloy
- /var/run/docker.sock:/var/run/docker.sock
- /var/log:/var/log:ro
environment:
- GRAFANA_TOKEN=${GRAFANA_TOKEN}
networks:
- monitoring
prometheus:
image: prom/prometheus:latest
container_name: prometheus
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
networks:
- monitoring
networks:
monitoring:
driver: bridge
Exécuter un conteneur
# Exécuter avec le fichier de configuration
docker run -d \
--name alloy \
-v /path/to/config.alloy:/etc/alloy/config.alloy \
-p 12345:12345 \
-p 4317:4317 \
-p 4318:4318 \
-e GRAFANA_TOKEN=$GRAFANA_TOKEN \
grafana/alloy:latest run /etc/alloy/config.alloy \
--server.http.listen-addr=0.0.0.0:12345
# Afficher les journaux
docker logs -f alloy
# Arrêter le conteneur
docker stop alloy
docker rm alloy
Débogage
Accès à l’interface web
# Accéder à l'interface utilisateur d'Alloy (port par défaut 12345)
# Affiche l'état des composants, les exportations, les métriques
curl http://localhost:12345
# Navigateur : http://localhost:12345/graph
Niveaux de journalisation
# Exécuter avec journalisation de débogage
alloy run config.alloy --log.level=debug
# Exécuter avec journalisation d'info (par défaut)
alloy run config.alloy --log.level=info
# Exécuter avec journalisation d'avertissement
alloy run config.alloy --log.level=warn
Valider la configuration
# Analyser la configuration sans l'exécuter
alloy tools parse config.alloy
# Vérifier les erreurs de syntaxe
alloy fmt config.alloy
# Linter et valider
alloy tools lint config.alloy
Inspecter les composants
# Afficher tous les types de composants
alloy tools component list
# Obtenir la documentation des composants
alloy tools component doc prometheus.scrape
# Afficher le schéma des composants
alloy tools component schema prometheus.scrape
Profilage Pprof
# Activer le serveur pprof (par défaut : http://localhost:6060/debug/pprof)
alloy run config.alloy --pprof.enabled=true --pprof.address=0.0.0.0:6060
# Afficher le profil de tas
curl http://localhost:6060/debug/pprof/heap > heap.prof
go tool pprof heap.prof
# Afficher le profil de goroutine
curl http://localhost:6060/debug/pprof/goroutine
Inspection des traces
# Activer le traçage distribué
alloy run config.alloy --traces.enabled=true
# Accéder à l'interface de trace (si exposée)
curl http://localhost:12345/traces
Variables d’environnement
| Variable | Description |
|---|---|
ALLOY_CONFIG_FILE | Chemin d’accès au fichier de configuration |
GRAFANA_TOKEN | Jeton d’authentification pour Grafana Cloud |
PROMETHEUS_URL | Point de terminaison du serveur Prometheus |
LOKI_URL | Point de terminaison de l’API Loki |
TEMPO_URL | Point de terminaison de l’API Tempo |
OTEL_EXPORTER_OTLP_ENDPOINT | Point de terminaison de l’exportateur OpenTelemetry OTLP |
OTEL_EXPORTER_OTLP_HEADERS | En-têtes de l’exportateur OTLP |
OTEL_SDK_DISABLED | Désactiver le SDK OpenTelemetry |
LOG_LEVEL | Niveau de journalisation : debug, info, warn, error |
ALLOY_REMOTE_CONFIG_URL | URL de configuration à distance |
NODE_NAME | Identificateur de nœud (nom de nœud k8s) |
POD_NAME | Nom du pod (pour k8s) |
NAMESPACE | Espace de noms Kubernetes |
Utilisation des variables d’environnement
# Exporter des variables
export GRAFANA_TOKEN="glc_xxx"
export PROMETHEUS_URL="https://prometheus.grafana.net"
# Exécuter Alloy
alloy run config.alloy
# Dans config.alloy, référencer avec ${ }
prometheus.remote_write "grafana" {
endpoint {
url = "${PROMETHEUS_URL}/api/prom/push"
basic_auth {
password = "${GRAFANA_TOKEN}"
}
}
}
Ressources
- Documentation officielle : https://grafana.com/docs/alloy/latest/
- Référence de configuration : https://grafana.com/docs/alloy/latest/reference/
- Catalogue des composants : https://grafana.com/docs/alloy/latest/reference/components/
- Référentiel GitHub : https://github.com/grafana/alloy
- Notes de version : https://github.com/grafana/alloy/releases
- Intégration Grafana Cloud : https://grafana.com/products/cloud/
- Spécification OpenTelemetry : https://opentelemetry.io/docs/
- Discussions communautaires : https://community.grafana.com/
- Tutoriels et exemples : https://grafana.com/docs/alloy/latest/tutorials/
- Graphique Helm : https://github.com/grafana/helm-charts/tree/main/charts/alloy
- Images Docker : https://hub.docker.com/r/grafana/alloy
- Commentaires et problèmes : https://github.com/grafana/alloy/issues