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