أوامر Grafana Alloy
Grafana Alloy هو موزع OpenTelemetry مرن وغير متحيز لجمع ومعالجة وتصدير بيانات القياسات (المقاييس والسجلات والتتبعات). خليفة Grafana Agent، يستخدم لغة تكوين قائمة على المكونات.
التثبيت
مستودعات حزم 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
تحميل البرنامج الثنائي
# تحميل أحدث إصدار
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
Helm Chart
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
الأوامر الأساسية
| الأمر | الوصف |
|---|---|
alloy run config.alloy | تشغيل Alloy مع ملف التكوين المحدد |
alloy run config.alloy --server.http.listen-addr=0.0.0.0:12345 | التشغيل مع عنوان خادم HTTP مخصص لواجهة المستخدم |
alloy fmt config.alloy | تنسيق والتحقق من ملف التكوين (تشغيل جاف) |
alloy fmt -w config.alloy | تنسيق ملف التكوين في المكان |
alloy tools parse config.alloy | تحليل والتحقق من صيغة التكوين |
alloy tools lint config.alloy | بحث التكوين عن المشاكل |
alloy --version | عرض إصدار Alloy |
alloy --help | عرض معلومات المساعدة |
alloy run --help | عرض خيارات أمر التشغيل |
أساسيات التكوين
امتداد الملف والصيغة
يستخدم Alloy امتداد ملف .alloy مع لغة تكوين قائمة على المكونات (مشابهة لـ HCL).
الهيكل الأساسي
// التعليقات تستخدم //
// إنشاء instance مكون: <component_type>.<unique_name> { ... }
prometheus.scrape "example" {
targets = [{"__address__" = "localhost:9090"}]
forward_to = [prometheus.remote_write.grafana.receiver]
}
// تصدير البيانات من مكون إلى آخر
prometheus.remote_write "grafana" {
endpoint {
url = "https://prometheus.grafana.net/api/prom/push"
headers = {
"Authorization" = "Bearer ${GRAFANA_TOKEN}"
}
}
}
المتغيرات والأسرار
// متغيرات البيئة
GRAFANA_TOKEN = env("GRAFANA_TOKEN")
PROMETHEUS_URL = env("PROMETHEUS_URL")
// متغيرات محلية
local "my_targets" {
value = [
{"__address__" = "localhost:9090"},
{"__address__" = "localhost:9100"},
]
}
// المرجع المتغيرات
prometheus.scrape "nodes" {
targets = local.my_targets.value
}
كتل الحجج والتصديرات
// معظم المكونات تقبل الحجج
prometheus.scrape "example" {
targets = [{"__address__" = "localhost:9090"}]
scrape_interval = "30s"
scrape_timeout = "10s"
forward_to = [prometheus.remote_write.grafana.receiver]
}
// المكونات تصدر البيانات (مرئية في واجهة المستخدم ضمن التصديرات)
// مثال: prometheus.scrape يصدر scraped_targets و targets
المكونات - المصادر
Prometheus Scrape
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]
}
مصدر ملف Loki
loki.source.file "app_logs" {
targets = [
{
__path__ = "/var/log/app/*.log",
job = "app",
env = "production",
}
]
forward_to = [loki.relabel.add_labels.receiver]
}
OpenTelemetry Receiver (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]
}
}
جهاز استقبال Prometheus Remote Write
prometheus.receive_http "example" {
http {
address = "0.0.0.0:9009"
}
forward_to = [prometheus.relabel.example.receiver]
}
خادم Loki API
loki.relabel "add_labels" {
forward_to = [loki.write.grafana.receiver]
rule {
source_labels = ["__path__"]
target_label = "job"
replacement = "app-logs"
}
}
المكونات - المعالجات
معالج الدفع
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]
}
}
معالج الفلتر
otelcol.processor.filter "drop_internal" {
metrics {
exclude {
match_type = "regexp"
regexp = "internal_.*"
}
}
output {
metrics = [otelcol.exporter.prometheus.grafana.input]
}
}
معالج كشف المورد
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]
}
}
معالج الصفات
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]
}
}
معالج حد الذاكرة
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]
}
}
معالج Span (التتبعات)
otelcol.processor.span "extract_attributes" {
name {
to_attributes {
rules = ["^/api/(?P<version>v\\d)/(?P<resource>\\w+)"]
}
}
output {
traces = [otelcol.processor.batch.default.input]
}
}
المكونات - الصادرات
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
}
}
Loki Write
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"
}
مصدر 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"
}
}
مصادقة OTLP
otelcol.auth.basic "grafana" {
username = "GRAFANA_USER_ID"
password = "${GRAFANA_TOKEN}"
}
// OTLP مع مصادقة أساسية
otelcol.exporter.otlp "example" {
client {
endpoint = "tempo.grafana.net:4317"
auth = otelcol.auth.basic.grafana.handler
}
}
مصدّر Prometheus (على نمط 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]
}
المكونات - الاكتشاف
اكتشاف 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"
}
}
اكتشاف 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]
}
اكتشاف 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]
}
اكتشاف قائم على الملفات
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]
}
جمع المقاييس
Prometheus Scraping مع إعادة التسمية
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]
}
تكامل 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]
}
نقطة نهاية مقاييس مخصصة
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]
}
جمع السجلات
تتبع الملفات مع 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]
}
سجلات Journal (systemd)
loki.source.journal "systemd" {
path = "/var/log/journal"
labels = {
job = "systemd",
}
forward_to = [loki.relabel.add_labels.receiver]
}
تحليل سجلات 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"
}
}
}
السجلات متعددة الأسطر (Stack Traces)
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",
}
}
}
}
جمع التتبعات
أنبوب OpenTelemetry Traces
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}"
}
جهاز استقبال 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]
}
}
جهاز استقبال Zipkin
otelcol.receiver.zipkin "default" {
endpoint = "0.0.0.0:9411"
output {
traces = [otelcol.processor.batch.default.input]
}
}
نشر Kubernetes
قيم 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
تثبيت Helm
# تثبيت مع قيم مخصصة
helm install alloy grafana/alloy \
--namespace monitoring \
--create-namespace \
-f values.yaml
# ترقية التثبيت الموجود
helm upgrade alloy grafana/alloy \
--namespace monitoring \
-f values.yaml
# إلغاء التثبيت
helm uninstall alloy --namespace monitoring
مثال 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}"
}
}
}
مثال 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
تكوين Docker
ملف 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
تشغيل حاوية
# التشغيل مع ملف التكوين
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
# عرض السجلات
docker logs -f alloy
# إيقاف الحاوية
docker stop alloy
docker rm alloy
التصحيح
وصول واجهة الويب
# وصول واجهة Alloy (منفذ افتراضي 12345)
# يعرض حالة المكون والتصديرات والمقاييس
curl http://localhost:12345
# المتصفح: http://localhost:12345/graph
مستويات السجل
# التشغيل مع تسجيل التصحيح
alloy run config.alloy --log.level=debug
# التشغيل مع تسجيل المعلومات (افتراضي)
alloy run config.alloy --log.level=info
# التشغيل مع تسجيل التحذير
alloy run config.alloy --log.level=warn
التحقق من التكوين
# تحليل التكوين بدون تشغيل
alloy tools parse config.alloy
# التحقق من أخطاء الصيغة
alloy fmt config.alloy
# بحث والتحقق
alloy tools lint config.alloy
فحص المكونات
# عرض جميع أنواع المكونات
alloy tools component list
# الحصول على توثيق المكون
alloy tools component doc prometheus.scrape
# عرض مخطط المكون
alloy tools component schema prometheus.scrape
تحليل Pprof
# تفعيل خادم pprof (افتراضي: http://localhost:6060/debug/pprof)
alloy run config.alloy --pprof.enabled=true --pprof.address=0.0.0.0:6060
# عرض ملف heap
curl http://localhost:6060/debug/pprof/heap > heap.prof
go tool pprof heap.prof
# عرض ملف goroutine
curl http://localhost:6060/debug/pprof/goroutine
فحص التتبعات
# تفعيل التتبع الموزع
alloy run config.alloy --traces.enabled=true
# الوصول إلى واجهة المستخدم trace (إذا تم تعريضها)
curl http://localhost:12345/traces
متغيرات البيئة
| المتغير | الوصف |
|---|---|
ALLOY_CONFIG_FILE | مسار ملف التكوين |
GRAFANA_TOKEN | رمز المصادقة لـ Grafana Cloud |
PROMETHEUS_URL | نقطة نهاية خادم Prometheus |
LOKI_URL | نقطة نهاية Loki API |
TEMPO_URL | نقطة نهاية Tempo API |
OTEL_EXPORTER_OTLP_ENDPOINT | نقطة نهاية OTLP exporter لـ OpenTelemetry |
OTEL_EXPORTER_OTLP_HEADERS | رؤوس OTLP exporter |
OTEL_SDK_DISABLED | تعطيل OpenTelemetry SDK |
LOG_LEVEL | مستوى السجل: debug, info, warn, error |
ALLOY_REMOTE_CONFIG_URL | عنوان URL للتكوين البعيد |
NODE_NAME | معرّف العقدة (اسم عقدة k8s) |
POD_NAME | اسم Pod (للـ k8s) |
NAMESPACE | مساحة اسم Kubernetes |
استخدام متغيرات البيئة
# تصدير المتغيرات
export GRAFANA_TOKEN="glc_xxx"
export PROMETHEUS_URL="https://prometheus.grafana.net"
# تشغيل Alloy
alloy run config.alloy
# في config.alloy، المرجع مع ${ }
prometheus.remote_write "grafana" {
endpoint {
url = "${PROMETHEUS_URL}/api/prom/push"
basic_auth {
password = "${GRAFANA_TOKEN}"
}
}
}
الموارد
- الوثائق الرسمية: https://grafana.com/docs/alloy/latest/
- مرجع التكوين: https://grafana.com/docs/alloy/latest/reference/
- كتالوج المكونات: https://grafana.com/docs/alloy/latest/reference/components/
- مستودع GitHub: https://github.com/grafana/alloy
- ملاحظات الإصدار: https://github.com/grafana/alloy/releases
- تكامل Grafana Cloud: https://grafana.com/products/cloud/
- مواصفات OpenTelemetry: https://opentelemetry.io/docs/
- مناقشات المجتمع: https://community.grafana.com/
- البرامج التعليمية والأمثلة: https://grafana.com/docs/alloy/latest/tutorials/
- Helm Chart: https://github.com/grafana/helm-charts/tree/main/charts/alloy
- صور Docker: https://hub.docker.com/r/grafana/alloy
- التعليقات والمشاكل: https://github.com/grafana/alloy/issues