iT邦幫忙

2023 iThome 鐵人賽

DAY 16
0
Software Development

Rust Web API 從零開始系列 第 16

Day16 - 發佈之前,先加個Log吧(1)

  • 分享至 

  • xImage
  •  

目前為止第一支API已經可以紀錄基本的訂閱資料,這時候就可以先準備發布了。不過發布之前,我們要先幫系統加上紀錄log的功能,當產品發佈到雲平台後就不像在本機一樣容易偵錯,所以當問題發生時,我們希望有日誌的功能能夠幫助釐清問題。rust中有幾個紀錄log的套件,一般而言常使用log,但在多執行緒非同步的系統中,因為一個任務不一定是由同一個執行緒完成,就會造成難以追蹤,這時候log就不敷使用了。今天要介紹的是同為tokio生態系中的套件tracing

Span

這是tracing中的第一個基本概念。最簡的紀錄log的方式是用printf!(),這樣便會在日誌中紀錄一筆資料,這樣的log是單點的。Span與單純的印出log不同,它表示的是一段區間,像是一個HTTP Request的開始到結束。tracing提供了span!巨集來簡的的產生一個span

fn main() {
    // 建立span
    let span = span!(Level::TRACE, "這是一個span");

    // 開始進入span的區間
    let enter = span.enter();
    
    // do something
} 
// 離開main的作用域後,因為rust的特性會drop作用域內的東西
// 換句話說就是這個span的結束

span的設計符合rust的哲學,他的生命週期會在離開作用域後回收,也就是離開main()的作用範圍,在這個span的生命週期內可以記錄一些內容。

Event

那麼要如何紀錄自定義的log呢?tracing提供了event,event可以單獨存在,但需要在span的作用範圍內才會被span捕捉:

event!(Level::INFO, "不在span區間內");

let span = span!(Level::INFO, "my_span");
let _guard = span.enter();

event!(Level::DEBUG, "在span區間內");

上面的這段程式碼紀錄的結果如下:

某個時間  INFO 應用程式: 不在span區間內
某個時間 DEBUG my_span: 應用程式: 在span區間內
----------------^^^

另外tracing也提供了info!error!等巨集來簡單的建立event。

Subscribers

subscribers是一個很巧妙的設計,不同於前面兩者是結構體,Subscriber是一個trait,這個trait定義了一個Subscriber的行為。這個設計其實跟.Net中的ILoggerProvider很像,我們可以藉由ILogger通知紀錄log,並由ILoggerProvider決定要如何處理這些log。

Subscriber中定義了三個方法

  1. enter : 進入span時會呼叫
  2. event : 紀錄event時會呼叫
  3. exit : 離開span時會呼叫

既然Subscribers是一個trait,也就代表了可以有多種不同的實做,事實上一個系統中可以通時具有多個Subscriber,tracing本身不實做訂閱者,但官方提供了幾個實做:

  1. tracing-subscriber
  2. tracing-log
  3. tracing-appender
  4. tracing-futures

另外也有一些第三方的實做像是著名的tracing-opentelemetry,喜歡grafana的也可以用tracing-loki


上一篇
Day15 - 管理應用程式的組態
下一篇
Day17 - 發佈之前,先加個Log吧(2)
系列文
Rust Web API 從零開始30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言