追蹤
為了效能而撰寫擴充模組的 Python 專案,可能會想使用 Rust 的 tracing 生態系 來了解擴充模組的效能表現。
本節介紹幾個提供此能力的軟體箱。它們建立在 tracing_subscriber 之上,並需要同時修改 Python 與 Rust 程式碼來整合。請注意每個擴充模組都必須設定自己的 tracing 整合;一個擴充模組無法看到另一個模組的 tracing 資料。
pyo3-tracing-subscriber(文件)
pyo3-tracing-subscriber 提供 Python 專案設定 tracing_subscriber 的方式,並暴露幾個 tracing_subscriber layer:
tracing_subscriber::fmt:輸出易讀格式到檔案或 stdoutopentelemetry-stdout:輸出 OTLP 到檔案或 stdoutopentelemetry-otlp:輸出 OTLP 到 OTLP 端點
擴充模組必須呼叫 pyo3_tracing_subscriber::add_submodule 來導出設定與初始化 tracing 所需的 Python 類別。
在 Python 端,使用 Tracing 內容管理器來初始化 tracing,並在其區塊內執行 Rust 程式碼。Tracing 需要一個描述使用哪些 layer 的 GlobalTracingConfig 實例。
範例程式碼請見 crates.io 的 README。
pyo3-python-tracing-subscriber(文件)
名稱相近的 pyo3-python-tracing-subscriber 在 Rust 中實作一個 shim,將 tracing 資料轉送到由 Python 定義並傳入的 Layer 實作。
擴充模組可用多種方式整合 pyo3-python-tracing-subscriber,其中一個簡單做法可能如下:
#[tracing::instrument]
#[pyfunction]
fn fibonacci(index: usize, use_memoized: bool) -> PyResult<usize> {
// ...
}
#[pyfunction]
pub fn initialize_tracing(py_impl: Bound<'_, PyAny>) {
tracing_subscriber::registry()
.with(pyo3_python_tracing_subscriber::PythonCallbackLayerBridge::new(py_impl))
.init();
}
擴充模組必須提供某種方式,讓 Python 傳入一個或多個實作了 Layer 介面 的 Python 物件。接著應使用這些物件建立 pyo3_python_tracing_subscriber::PythonCallbackLayerBridge 實例,並如上所示初始化 tracing_subscriber。
Python 物件實作的是改良版的 Layer 介面:
on_new_span()可回傳狀態,該狀態會儲存在 Rust span 中- 其他回呼會以額外的位置參數取得該狀態
一個假的 Layer 實作可能如下:
import rust_extension
class MyPythonLayer:
def __init__(self):
pass
# `on_new_span` 可以回傳某些狀態
def on_new_span(self, span_attrs: str, span_id: str) -> int:
print(f"[on_new_span]: {span_attrs} | {span_id}")
return random.randint(1, 1000)
# 來自 `on_new_span` 的狀態會傳回其他特徵方法
def on_event(self, event: str, state: int):
print(f"[on_event]: {event} | {state}")
def on_close(self, span_id: str, state: int):
print(f"[on_close]: {span_id} | {state}")
def on_record(self, span_id: str, values: str, state: int):
print(f"[on_record]: {span_id} | {values} | {state}")
def main():
rust_extension.initialize_tracing(MyPythonLayer())
print("10th fibonacci number: ", rust_extension.fibonacci(10, True))
pyo3-python-tracing-subscriber 提供可運作的範例,展示 Rust 與 Python 端的整合方式。