Day 4:tracing——日誌與追蹤

學習目標

  • 了解 tracing 的核心概念
  • 用 tracing 的巨集記錄日誌
  • 用 #[instrument] 做 span 追蹤

今日重點

安裝

[dependencies]
tracing = "0.1"
tracing-subscriber = "0.3"

設定 subscriber 並使用巨集

fn main() {
    tracing_subscriber::fmt().init();   // 啟動日誌訂閱

    tracing::info!("application started");
    tracing::warn!("something suspicious");
    tracing::debug!("only shown at debug level");
    tracing::error!("something failed");
}

Zen 概念:event 與 span

  • event:單一瞬間的記錄(info!、warn! 等)
  • span:一段時間的範圍(用 #[instrument] 自動產生),可巢狀、可顯示花費時間

#[instrument]

use tracing::info;

#[tracing::instrument]
fn process_order(order_id: u32) -> Result<String, String> {
    info!("Processing order {}", order_id);
    // ...處理
    info!("Order {} processed successfully", order_id);
    Ok(format!("Order {} completed", order_id))
}

#[instrument] 自動建立一個 span,名稱=函式名,並記錄參數,方便追蹤一段作業的開始/結束與耗時。

練習

use tracing::{info, error, instrument};

#[instrument]
fn fetch_user(id: u32) -> Result<String, String> {
    if id == 0 {
        error!("invalid id {}", id);
        return Err("bad id".to_string());
    }
    Ok(format!("user-{}", id))
}

fn main() {
    tracing_subscriber::fmt().init();
    match fetch_user(7) {
        Ok(u) => info!("got {}", u),
        Err(e) => error!("failed: {}", e),
    }
}

執行後觀察自動產生的 span 與花費時間輸出。

自我檢查

  • 知道 event vs span 的差別
  • 會用 tracing 巨集 + subscriber
  • 會用 #[instrument]
  • 理解 tracing 與 println! 的差異(結構化、可查詢)

深入連結

  • tracing crate 文件(docs.rs/tracing)