我正在用C ++实现一个日志处理程序,并且它运行良好,但是有一件事我觉得可以使用,这就是记录器从中获取输出的地方。
我想这不是一个大问题,但我偶然发现__func__
标识符,它基本上会保留当前函数的函数名。
所以我在我的Log类中有一个名为Write
的静态函数,它需要一个日志级别和一个变化列表。所以我会这样称呼它:
Log::Write(LOG_DEBUG, "this is an integer: %d", 10);
它会打印出来:
2013-01-02 => 10:12:01.366 [DEBUG]: this is an integer: 10
但是我认为在消息中也有调用者可能会有用这样的东西:
2013... => 10:12:... (functionName) [DEBUG]: blah
所以我可以做的(当然)是将__func__
作为参数添加到Log::Write
,但这意味着每当我调用Log::Write
时我都需要发送__func__
总是相同的,我觉得应该可以在没有明确说明的情况下这样做。
所以我想要的是提供的功能:
Log::Write(LOG_DEBUG, __func__, "message");
无需每次都明确输入 func 。
我不知道这是否真的可行,我得到的最好的选择是有一些方法可以取消引用函数Write
内部的调用者,我似乎不太可能只是“推断”这样的参数。但至少值得一提,也许我可以看看有哪些选择。
感谢。
答案 0 :(得分:7)
通常使用宏以及文件名__FILE__
和行号__LINE__
来完成。
void Log::Write(Level l,
char const* function,
char const* file,
int line,
char const* format,
...);
被包装成一个宏:
#define LOG(Level_, Format_, ...) \
Log::Write(Level_, __func__, __FILE__, __LINE__, Format_, __VA_ARGS__);
请注意,您可能希望通过检查是否在该级别登录来“保存”某些计算:
// suppose availability of "bool Log::Enabled(Level l)"
#define LOG(Level_, Format_, ...) \
while (Log::Enabled(Level_)) { \
Log::Write(Level_, __func__, __FILE__, __LINE__, Format_, __VA_ARGS__); \
break; \
}
使用while
代替if
是为了避免悬挂其他问题。
注意:您可能希望调查使用流进行日志记录。 printf
样式的问题是它不可组合。使用流,您可以为任何std::ostream& operator<<(std::ostream&, X const&)
重载X
,然后只编写一次方法,将其内容转储到日志中。
答案 1 :(得分:3)
#define WRITE_LOG(X,...) Log::Write(LOG_DEBUG, __func__, (X),__VA_ARGS__);
使用此宏来编写日志而不是函数,它会自动添加 func 参数。 Mat提到,这是典型的方式,在这种情况下,我无法想到任何避免宏的方法。