TL; DR版本:你在Python項目中用於C++位內可配置(並且最好是捕獲)的日誌記錄?詳情如下。在Python擴展中管理日誌/警告
假設你有一些編譯好的.so
模塊,可能需要做一些錯誤檢查並警告用戶(部分)不正確的數據。目前我正在使用Python代碼的logging
框架和來自C/C++的log4cxx
庫。 log4cxx
日誌級別在文件(log4cxx.properties
)中定義,目前已修復,我正在考慮如何使其更加靈活。我看到的幾個選擇:
控制它的一種方法是進行模塊範圍的配置調用。
# foo/__init__.py import sys from _foo import import bar, baz, configure_log configure_log(sys.stdout, WARNING) # tests/test_foo.py def test_foo(): # Maybe a custom context to change the logfile for # the module and restore it at the end. with CaptureLog(foo) as log: assert foo.bar() == 5 assert log.read() == "124.24 - foo - INFO - Bar returning 5"
讓每個執行日誌記錄的編譯函數都接受可選的日誌參數。
# foo.c int bar(PyObject* x, PyObject* logfile, PyObject* loglevel) { LoggerPtr logger = default_logger("foo"); if (logfile != Py_None) logger = file_logger(logfile, loglevel); ... } # tests/test_foo.py def test_foo(): with TemporaryFile() as logfile: assert foo.bar(logfile=logfile, loglevel=DEBUG) == 5 assert logfile.read() == "124.24 - foo - INFO - Bar returning 5"
還有其他的方法嗎?
第二個似乎有點乾淨,但它需要功能簽名改變(或使用kwargs和解析它們)。首先是...可能有些尷尬,但是一次性創建整個模塊並從每個單獨的函數中刪除邏輯。
你對此有何看法?我非常樂意接受其他解決方案。
感謝,
感謝您的建議。我還需要弄清楚的一件事是,如果記錄不是立即發生在C模塊內,它將如何工作。我想在這種情況下,我必須通過顯式參數傳遞記錄器。 – 2010-06-09 16:25:16
是的,您可以使簽名爲'log_it(char * logger_name,int level,char * msg)'。 – 2011-11-14 19:43:25