Day 5:tracing 進階應用

學習目標

  • 用 tracing 的欄位與變數
  • 結構化日誌輸出
  • 結合 anyhow 顯示錯誤鏈

今日重點

帶欄位的結構化日誌

use tracing::info;

fn main() {
    tracing_subscriber::fmt().init();
    let order_id = 42;
    let total = 999.5;

    info!(order_id, total, "order received");
    // 輸出含 order_id=42 total=999.5
}

結構化欄位讓日誌可被監控系統(如 Loki、Datadog)撈取。

instrument 自訂欄位

use tracing::instrument;

#[instrument(skip(password))]
fn login(user: &str, password: &str) -> Result<(), String> {
    // skip 避免把敏感資料寫進日誌
    if user == "admin" { Ok(()) } else { Err("denied".to_string()) }
}

結合 anyhow 顯示錯誤鏈

use anyhow::{Result, Context};
use tracing::error;

fn do_work() -> Result<()> {
    std::fs::read_to_string("x.toml").context("read config")?;
    Ok(())
}

fn main() -> Result<()> {
    tracing_subscriber::fmt().init();
    if let Err(e) = do_work() {
        error!("{:?}", e);   // {:?} 顯示 anyhow 的完整錯誤鏈
    }
    Ok(())
}

練習

use tracing::{info, instrument};
use tracing_subscriber::fmt;

#[instrument]
fn add(a: i32, b: i32) -> i32 {
    info!(a, b, "adding");
    a + b
}

fn main() {
    fmt().init();
    let r = add(3, 4);
    info!(result = r, "done");
}

觀察 span 內如何攜帶 a、b 欄位。

自我檢查

  • 會寫帶欄位的日誌
  • 知道 skip 避免記錄敏感資料
  • 能結合 anyhow 印出錯誤鏈
  • 理解結構化日誌的價值

深入連結

  • tracing-subscriber crate + tracing 官方範例