Hướng dẫn cài đặt và cấu hình Grafana Beyla: Tự động giám sát ứng dụng không cần sửa mã nguồn bằng eBPF cho Go, Python và Node.js

Monitoring tutorial - IT technology blog
Monitoring tutorial - IT technology blog

Cơn đau đầu khi phải instrument từng ứng dụng một

Hệ thống monitoring của mình gồm Prometheus + Grafana đang theo dõi 15 server, và setup đó đã giúp phát hiện sự cố trước khi user báo nhiều lần rồi. Nhưng có một điểm mù mà mình mãi không giải quyết được: giám sát bên trong từng ứng dụng — latency theo từng endpoint, error rate, số request đang xử lý.

Mỗi lần team thêm một service mới, quy trình cũ là: mở code ra, cài thư viện prometheus_client hoặc OpenTelemetry SDK, viết middleware để đo latency, expose /metrics, rồi cấu hình Prometheus scrape. Service Go thì một kiểu, Python thì khác, Node.js lại khác nữa. Với team nhỏ, việc này ngốn 2-3 giờ mỗi service — và thường bị gác lại khi deadline gấp.

Sau 3 tháng chạy như vậy, mình nhận ra có đến 40% số service không có metrics gì cả — toàn là những service được viết nhanh và không ai có thời gian quay lại instrument.

Tại sao cách truyền thống lại khó duy trì

Công cụ không thiếu. OpenTelemetry rất capable, Prometheus client library đầy đủ tính năng. Nhưng instrumentation thủ công tạo ra technical debt theo kiểu rất khó thấy:

  • Developer phải học API của từng SDK cho từng ngôn ngữ
  • Code bị pha trộn giữa business logic và monitoring logic
  • Service mới không tự nhiên có metrics — ai đó phải nhớ thêm vào
  • Khi refactor, metrics cũ có thể không còn chính xác nhưng vẫn chạy, gây nhầm lẫn

APM thương mại như Datadog hay New Relic có auto-instrumentation agent khá tốt. Nhưng với 15 host, Datadog Pro tính ra khoảng $300-400/tháng — chưa kể custom metrics. Không phù hợp với ngân sách team nhỏ.

Các hướng giải quyết đã thử

Hướng 1: Instrumentation tập trung tại API Gateway

Cài Nginx hoặc Envoy làm gateway, đo latency và request count tại đó. Cách này nhanh nhưng chỉ thấy được tầng ngoài cùng — không biết service nào bên trong đang chậm, không có trace xuyên suốt qua nhiều service.

Hướng 2: OpenTelemetry Collector + auto-instrumentation agent

Java có -javaagent rất trưởng thành. Python có opentelemetry-instrument. Node.js có @opentelemetry/auto-instrumentations-node. Nhưng Go thì không — Go compile ra binary tĩnh, không có cơ chế inject agent lúc runtime theo kiểu JVM.

Mình đã dùng cách này cho Python và Node.js, nhưng vẫn phải sửa entrypoint của từng service, và Go vẫn bị bỏ trống.

Hướng 3 — cách mình đang dùng: Grafana Beyla với eBPF

Beyla là open-source tool của Grafana Labs, dùng eBPF (extended Berkeley Packet Filter) để hook vào kernel Linux. Nó tự động quan sát các ứng dụng đang chạy — không cần chỉnh sửa một dòng code nào. Beyla hoạt động ở tầng kernel, intercept các syscall liên quan đến HTTP/gRPC, rồi tổng hợp thành metrics RED (Rate, Errors, Duration) và traces.

Sau 6 tháng chạy trên production, đây là cách mình thấy hiệu quả nhất cho môi trường mixed-language.

Cài đặt Grafana Beyla từng bước

Yêu cầu

  • Linux kernel 5.8 trở lên (kiểm tra: uname -r)
  • Quyền root hoặc CAP_BPF, CAP_PERFMON, CAP_SYS_PTRACE
  • Prometheus đang chạy để nhận metrics (hoặc dùng Grafana Cloud)

Cài Beyla bằng Docker

Cách nhanh nhất để thử là chạy Beyla như một container song song với ứng dụng cần giám sát:

# Giám sát ứng dụng đang chạy trên host port 8080
docker run --rm \
  --pid=host \
  --privileged \
  -e BEYLA_OPEN_PORT=8080 \
  -e BEYLA_PROMETHEUS_PORT=9400 \
  -p 9400:9400 \
  grafana/beyla:latest

Truy cập http://localhost:9400/metrics — metric http_server_request_duration_seconds sẽ xuất hiện ngay, không cần sửa gì trong ứng dụng.

Cài Beyla bằng binary trực tiếp

# Tải binary mới nhất (kiểm tra trang releases để lấy version mới nhất)
wget https://github.com/grafana/beyla/releases/download/v1.8.0/beyla-linux-amd64
chmod +x beyla-linux-amd64
sudo mv beyla-linux-amd64 /usr/local/bin/beyla

# Chạy và tự tìm process đang lắng nghe port 8080
sudo BEYLA_OPEN_PORT=8080 BEYLA_PROMETHEUS_PORT=9400 beyla

Cấu hình file YAML cho production

Biến môi trường chỉ hợp lý khi thử nghiệm. Trên production, file cấu hình YAML dễ quản lý hơn nhiều:

# /etc/beyla/config.yaml
open_port: 8080          # Port ứng dụng đang lắng nghe
service_name: my-api     # Tên hiển thị trong Grafana

prometheus_export:
  port: 9400
  path: /metrics

# Tùy chọn: export traces sang Grafana Tempo
otel_traces_export:
  endpoint: http://tempo:4317

# Lọc path không cần theo dõi (health check, static files)
filters:
  application:
    - path_pattern: '/health'
      method: GET
# Chạy với file config
sudo beyla --config /etc/beyla/config.yaml

Tích hợp với Prometheus

Thêm job vào prometheus.yml:

scrape_configs:
  - job_name: 'beyla-my-api'
    static_configs:
      - targets: ['localhost:9400']
    relabel_configs:
      - source_labels: [__address__]
        target_label: instance

Chạy Beyla như systemd service

Để Beyla tự khởi động cùng server:

# /etc/systemd/system/beyla.service
[Unit]
Description=Grafana Beyla eBPF Auto-instrumentation
After=network.target

[Service]
ExecStart=/usr/local/bin/beyla --config /etc/beyla/config.yaml
Restart=on-failure
User=root

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now beyla
sudo systemctl status beyla

Beyla hoạt động thế nào với từng ngôn ngữ

Cơ chế bên dưới khác nhau tùy ngôn ngữ, nhưng đầu ra metrics thì đồng nhất:

  • Go: Beyla dùng uprobes để hook vào các hàm net/http và gRPC trong binary đã compile. Đây là thứ mà không có agent nào khác làm được với Go.
  • Python: Hook vào WSGI/ASGI middleware layer (Django, Flask, FastAPI đều được).
  • Node.js: Hook vào V8 runtime và http/https module.

Metrics sinh ra đều theo chuẩn OpenTelemetry semantic conventions, nên dashboard Grafana dùng được ngay mà không cần tùy chỉnh.

Kết quả sau 6 tháng dùng thực tế

Thứ làm mình bất ngờ không phải là Beyla chạy được — mà là nó chạy tốt ngay cả trên những service cũ không ai dám đụng tới. Mình có một service Go viết từ 2021, không có unit test, không ai trong team hiểu rõ hoàn toàn — giờ nó đã có đầy đủ latency histogram, error rate, và request throughput mà không cần chạm vào một dòng code nào.

Coverage metrics trong team tăng từ 60% lên 100% trong vòng một buổi chiều, đơn giản là deploy Beyla lên từng host.

Về overhead: mình đo được khoảng 1-2% CPU và ~50MB RAM cho một host đang xử lý ~500 req/s. Chấp nhận được hoàn toàn.

Một điểm cần lưu ý: Beyla cần kernel 5.8+ và quyền privileged. Nếu bạn chạy trong môi trường containerized với security policies nghiêm ngặt (như GKE Autopilot), cần kiểm tra khả năng tương thích trước.

Dashboard Grafana cho Beyla

Grafana Labs cung cấp sẵn dashboard tại Grafana.com với ID 19419 (RED Metrics) và 19420 (Service Map). Import vào Grafana:

  1. Vào Grafana → Dashboards → Import
  2. Nhập ID 19419 → Load
  3. Chọn Prometheus datasource → Import

Sau khi import xong, Service Map hiện ra ngay — tất cả service, traffic giữa chúng, và request flow đều hiển thị mà không cần config thêm gì. Request Rate, Error Rate, P99 latency theo từng endpoint đều có sẵn. Không cần viết một dòng PromQL nào.

Share: