Phần 3 — Grafana Alloy: Collector duy nhất cho metrics, logs, traces
Ý kiến
0
Chưa có ý kiến nào. Hãy là người đầu tiên chia sẻ!
Chưa có ý kiến nào. Hãy là người đầu tiên chia sẻ!
Tổng quan series: Grafana LGTM (Loki, Tempo, Mimir) + Alloy collector + SeaweedFS object storage + Pyroscope/Beyla. Kiến trúc, hardware, thứ tự deploy.
Vì sao SeaweedFS phù hợp cho Loki/Mimir/Tempo hơn MinIO/Ceph. Kiến trúc 4 thành phần, cài đặt single-node và multi-node, replication, best practices.
Cấu hình monolithic của Loki, Mimir, Tempo cùng dùng SeaweedFS làm object storage. Retention strategy, multi-tenancy, mẹo cardinality.
Series Observability với Grafana Stack — 6 phần:
Phần 1 — Tổng quan: Observability với Grafana LGTM, Alloy và SeaweedFS
Phần 2 — SeaweedFS: Object storage gọn nhẹ cho Loki, Mimir, Tempo
Phần 3 — Grafana Alloy: Collector duy nhất cho metrics, logs, traces ← bạn đang đọc
Phần 5 — Grafana, Pyroscope, Beyla: UI, profiling và auto-instrumentation
Phần 6 — Production checklist: Backup, alerting, troubleshooting
Grafana Alloy là collector OpenTelemetry-distribution chính thức của Grafana Labs. Nó thay thế:
| Trước | Sau |
|---|---|
| Promtail (logs) | Alloy |
| Node Exporter (metrics OS) | Alloy |
| OTEL Collector (traces, OTLP) | Alloy |
| Vector / Fluent Bit (log shipping) | Alloy |
Một binary, một config, ba luồng dữ liệu: metrics, logs, traces.
Trong stack mới, Alloy đứng đầu chuỗi. Quy tắc: collector phải sống và sẵn sàng nhận data trước khi storage được khởi chạy. Nếu Loki/Mimir/Tempo lên trước mà Alloy chưa có config đúng, bạn sẽ mất logs và metrics của giai đoạn boot.
May mắn là Alloy có buffer + retry sẵn — nó vẫn nhận data từ apps trong khi chờ storage lên.
Alloy phải chạy mode: global để mỗi node trong cluster có đúng một Alloy thu thập logs/metrics của chính node đó. File alloy-compose.yml:
services:
alloy:
image: grafana/alloy:v1.15.1
environment:
- HOSTNAME={{.Node.Hostname}}
volumes:
- ./config/config.alloy:/etc/alloy/config.alloy:ro
- /var/lib/docker/containers:/var/lib/docker/containers:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- /:/host/root:ro,rslave
- /sys:/host/sys:ro
- /proc:/host/proc:ro
command:
- run
- --server.http.listen-addr=0.0.0.0:12345
- --storage.path=/var/lib/alloy/data
- /etc/alloy/config.alloy
ports:
- "4317:4317" # OTLP gRPC
- "4318:4318" # OTLP HTTP
- "12345:12345" # Alloy UI
networks: [observability-net]
deploy:
mode: global
resources:
limits: { memory: 512M }
update_config:
parallelism: 1
delay: 10s
order: stop-first
networks:
observability-net:
external: true
config.alloy đầy đủFile config/config.alloy — gửi data đến Mimir, Loki, Tempo:
// =====================================================
// 1. DESTINATIONS
// =====================================================
// Metrics → Mimir
prometheus.remote_write "mimir" {
endpoint {
url = "http://mimir:8080/api/v1/push"
headers = { "X-Scope-OrgID" = "primary_cluster" }
}
}
// Logs → Loki
loki.write "loki" {
endpoint { url = "http://loki:3100/loki/api/v1/push" }
external_labels = { cluster = "primary_cluster" }
}
// Traces → Tempo
otelcol.exporter.otlp "tempo" {
client {
endpoint = "tempo:4317"
tls { insecure = true }
}
}
// =====================================================
// 2. METRICS — node + cAdvisor (containers)
// =====================================================
prometheus.exporter.unix "node" {
rootfs_path = "/host/root"
sysfs_path = "/host/sys"
procfs_path = "/host/proc"
}
prometheus.scrape "node_exporter" {
targets = prometheus.exporter.unix.node.targets
forward_to = [prometheus.remote_write.mimir.receiver]
scrape_interval = "30s"
}
prometheus.exporter.cadvisor "containers" {
docker_host = "unix:///var/run/docker.sock"
}
prometheus.scrape "cadvisor" {
targets = prometheus.exporter.cadvisor.containers.targets
forward_to = [prometheus.remote_write.mimir.receiver]
scrape_interval = "30s"
}
// =====================================================
// 3. LOGS — Docker container logs
// =====================================================
discovery.docker "containers" {
host = "unix:///var/run/docker.sock"
}
loki.source.docker "logs" {
host = "unix:///var/run/docker.sock"
targets = discovery.docker.containers.targets
forward_to = [loki.process.relabel.receiver]
}
loki.process "relabel" {
forward_to = [loki.write.loki.receiver]
stage.docker { }
stage.labels {
values = {
stack = "__meta_docker_swarm_service_label_com_docker_stack_namespace",
service = "__meta_docker_swarm_service_name",
node = "__meta_docker_host",
}
}
}
// =====================================================
// 4. OTLP RECEIVER — apps push trực tiếp
// =====================================================
otelcol.receiver.otlp "app" {
grpc { endpoint = "0.0.0.0:4317" }
http { endpoint = "0.0.0.0:4318" }
output {
metrics = [otelcol.processor.batch.default.input]
traces = [otelcol.processor.batch.default.input]
logs = [otelcol.processor.batch.default.input]
}
}
otelcol.processor.batch "default" {
output {
metrics = [otelcol.exporter.prometheus.mimir_bridge.input]
traces = [otelcol.exporter.otlp.tempo.input]
logs = [otelcol.exporter.loki.loki_bridge.input]
}
}
otelcol.exporter.prometheus "mimir_bridge" {
forward_to = [prometheus.remote_write.mimir.receiver]
}
otelcol.exporter.loki "loki_bridge" {
forward_to = [loki.write.loki.receiver]
}
docker network create -d overlay observability-net
docker stack deploy -c alloy-compose.yml obs
Mở UI Alloy: http://<node-ip>:12345/graph — xem topology của các component.
X-Scope-OrgID: luôn đặt header này khi push tới Mimir. Sau này muốn tách Dev/Staging/Prod chỉ cần đổi giá trị, không phải dựng Mimir mới.
Lỗi HTTP đỏ trên UI: nếu node prometheus.remote_write báo lỗi, đó chỉ là vì Mimir chưa lên. Alloy có buffer/retry — không mất data.
scrape_interval: 30s là sweet spot cho metrics OS. App custom metrics có thể 15s.
Memory limit 512M — đủ cho ~50 container/node. Tăng nếu logs nhiều.
Legacy node_exporter: nếu vẫn còn server bare-metal chạy node_exporter:9100, scrape thẳng:
prometheus.scrape "external_nodes" {
targets = [
{"__address__" = "10.0.0.50:9100", "instance" = "old-db"},
]
forward_to = [prometheus.remote_write.mimir.receiver]
}
← Phần 2: SeaweedFS: Object storage gọn nhẹ cho Loki, Mimir, Tempo