日誌
理想情況是應用程式中的 Python 與 Rust 部分都使用相同設定,並將日誌輸出到同一位置。
本節簡要說明如何連結兩種語言的日誌生態系。對於 Python 擴充模組,建議的方式是使用 pyo3-log 軟體箱設定 Rust 的 logger,將日誌訊息送到 Python。若你想反向將 Python 日誌送到 Rust,請見本指南最後的說明。
使用 pyo3-log 將 Rust 日誌訊息送到 Python
pyo3-log 軟體箱允許將 Rust 端訊息傳送到 Python 的 logging 系統。這主要適用於為 Python 程式撰寫原生擴充。
使用 pyo3_log::init 以預設設定安裝 logger。也可以調整其設定(多半用於效能調校)。
#[pyo3::pymodule]
mod my_module {
use log::info;
use pyo3::prelude::*;
#[pyfunction]
fn log_something() {
// 這會使用安裝在 `my_module` 的 logger,將 `info`
// 訊息送到 Python 的 logging 系統。
info!("Something!");
}
#[pymodule_init]
fn init(m: &Bound<'_, PyModule>) -> PyResult<()> {
// 安裝 Rust -> Python logger 的好位置。
pyo3_log::init();
}
}
接著由 Python 端負責將訊息實際輸出到某處。
import logging
import my_module
FORMAT = '%(levelname)s %(name)s %(asctime)-15s %(filename)s:%(lineno)d %(message)s'
logging.basicConfig(format=FORMAT)
logging.getLogger().setLevel(logging.INFO)
my_module.log_something()
在呼叫任何可能產生日誌的 Rust 函式之前,務必先初始化 Python 的 logger。若無法滿足此限制,仍可用替代方式處理,請閱讀快取相關文件。
Python 到 Rust 的方向
若要讓 Rust 處理 Python 日誌,只需註冊一個 Rust 函式來處理由 Python 核心 logging 模組送出的日誌。
這已由 pyo3-pylogger 軟體箱實作。
use log::{info, warn};
use pyo3::prelude::*;
fn main() -> PyResult<()> {
// 在 python logger 中註冊主機端處理器,並提供 logger target
// 這裡的名稱請設定為適合你的應用程式
pyo3_pylogger::register("example_application_py_logger");
// 初始化 logger
env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("trace")).init();
// 從 Rust 紀錄一些訊息。
info!("Just some normal information!");
warn!("Something spooky happened!");
// 從 Python 紀錄一些訊息
Python::attach(|py| {
py.run(
"
import logging
logging.error('Something bad happened')
",
None,
None,
)
})
}