iT邦幫忙

2025 iThome 鐵人賽

DAY 23
0
DevOps

Vibe Coding 後的挑戰:Locust x Loki 負載及監控系列 第 23

Day23 - 將 Log 與 Trace 串起來:Grafana Agent 的初步介紹

  • 分享至 

  • xImage
  •  

經過前幾天對 Loki 的深入探討,我們已經掌握了如何有效地收集、查詢及警告日誌。然而,在現代複雜的微服務架構中,單純的日誌有時難以完整呈現一個請求的全貌。當一個請求在多個服務之間穿梭時,我們需要一種方法來追蹤它的完整生命週期,這就是「分散式追蹤 (Distributed Tracing)」要解決的問題。

在進入 Day 24 的主題 Grafana Tempo 之前,今天我們將扮演一個承先啟後的角色:探討如何將日誌 (Logs) 與追蹤 (Traces) 關聯起來,讓可觀測性 (Observability) 的三大支柱(Logs, Traces, Metrics)能夠協同工作。

為何需要關聯 Logs 與 Traces?

想像一個場景:

  1. 使用者回報在 App 中點擊某個按鈕後,出現了非預期的錯誤。
  2. 你從錯誤監控系統(或 Loki 的告警)中,找到了一條錯誤日誌,上面寫著 database connection timeout
  3. 你怎麼知道是哪個使用者的操作觸發了這個錯誤?這個請求在到達資料庫之前,經過了哪些服務?每個服務花費了多少時間?

如果你的日誌中包含一個獨一無二的 Trace ID,你就可以:

  • 快速定位:使用這個 Trace ID 在 Loki 中篩選出與該請求相關的所有日誌。
  • 完整視圖:使用同一個 Trace ID 在追蹤系統(如 Tempo 或 Jaeger)中,查看該請求的完整火焰圖 (Flame Graph),清晰地看到請求的調用鏈、每個環節的耗時與依賴關係。
  • 根本原因分析:結合日誌的細節與追蹤的宏觀視圖,快速找到問題的根本原因。例如,你可能會發現是某個上游服務的延遲,導致了下游服務的資料庫連接超時。

如何實現關聯:Trace ID Injection

要將日誌與追蹤關聯,關鍵在於在日誌中注入追蹤的上下文 (Trace Context),其中最重要的就是 Trace ID

當一個請求進入系統的第一個服務時,追蹤中介軟體 (Tracing Middleware) 會為它產生一個獨一無二的 Trace ID。這個 Trace ID 會隨著請求在服務之間傳遞。當每個服務在處理這個請求並產生相關日誌時,都需要將這個 Trace ID 一併記錄下來。

// 一般日誌
{
  "timestamp": "2025-09-09T10:00:00Z",
  "level": "info",
  "message": "User checkout process started"
}

// 注入 Trace ID 的日誌
{
  "timestamp": "2025-09-09T10:00:00Z",
  "level": "info",
  "message": "User checkout process started",
  "trace_id": "a1b2c3d4e5f6a7b8" // <-- 關鍵!
}

介紹 Grafana Agent

那麼,我們該如何有效地從應用程式中收集日誌和追蹤,並分別發送到 Loki 和 Tempo 呢?Grafana Agent 就是為此而生的利器。

Grafana Agent 是一個輕量級的可觀測性數據收集器,它可以:

  • 抓取 Metrics:相容 Prometheus 的指標格式。
  • 收集 Logs:相容 Promtail 的日誌收集功能。
  • 發送 Traces:支援 OpenTelemetry、Jaeger、Zipkin 等多種追蹤格式。

透過在你的應用程式環境中部署 Grafana Agent,你可以用一個統一的代理來處理所有可觀測性數據的收集與轉發,簡化了部署架構。

設定範例 (概念)

為了讓概念更具體,以下是一個簡化的 grafana-agent.yaml 設定檔範例。它展示了如何設定 Agent 同時處理日誌與追蹤。

# grafana-agent.yaml

# --- Metrics: Prometheus 指標設定 ---
metrics:
  wal_directory: /tmp/grafana-agent/wal
  global:
    scrape_interval: 60s
  configs:
    - name: integrations
      scrape_configs:
        - job_name: 'integrations/node_exporter'
          static_configs:
            - targets: ['localhost:9100']

# --- Logs: Loki 日誌設定 ---
logs:
  configs:
    - name: default
      positions:
        filename: /tmp/positions.yaml
      scrape_configs:
        # 類似 Promtail 的設定,從檔案中抓取日誌
        - job_name: 'app-logs'
          static_configs:
            - targets: [localhost]
              labels:
                job: fastapi-app
                __path__: /var/log/app.log
      # 將收集到的日誌發送到 Loki
      clients:
        - url: http://loki:3100/loki/api/v1/push

# --- Traces: Tempo 追蹤設定 ---
traces:
  configs:
    - name: default
      # 接收器 (Receivers):設定 Agent 監聽的端口,以接收追蹤數據
      receivers:
        otlp: # 接收 OpenTelemetry 格式的追蹤
          protocols:
            grpc:
              endpoint: "0.0.0.0:4317"
            http:
              endpoint: "0.0.0.0:4318"
      # 遠端寫入 (Remote Write):將接收到的追蹤數據發送到 Tempo
      remote_write:
        - endpoint: tempo:4317
          insecure: true

在這個範例中,我們可以看到 Grafana Agent 在一個設定檔中就整合了三種不同可觀測性訊號的處理邏輯,充分展現了其強大的整合能力。

下一步

今天我們理解了串連 Logs 與 Traces 的重要性,並初步認識了 Grafana Agent 這個工具。這為我們明天深入學習 Grafana Tempo 分散式追蹤系統打下了堅實的基礎。準備好進入追蹤的世界了嗎?


上一篇
Day22 - Loki 進階功能:Ruler 告警、儲存策略與多租戶
下一篇
Day24 - Grafana Tempo 分散式追蹤入門
系列文
Vibe Coding 後的挑戰:Locust x Loki 負載及監控27
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言