I trying to incorporate a simple error logging into my existing app, at the moment it reports errors just using cout
so I was hoping to keep a similar interface using the <<
operator. However I want it to log the line and function the error occurred, but I don't want to have to type __LINE__, __FUNCTION__
every time I need to log. Does anyone know a trick I can use to allow the __LINE__
macro to be used inside another function, reporting the calling line instead? Hope that makes sense.
我试图将一个简单的错误记录到我现有的应用程序中,目前它仅使用cout报告错误,所以我希望使用< <运算符保持类似的界面。但是我希望它记录行和函数发生的错误,但我不想每次需要登录时都要输入__line __,__ function__。有没有人知道我可以用来允许__line__宏在另一个函数中使用的技巧,而是报告调用行?希望有道理。< p>
class myLogClass {
uint8_t level;
public:
bool operator<<( const char * input );
};
bool myLogClass::operator<<( const char * input ) {
logItInSQL( input );
return true;
}
Instead of this every time
而不是每次都这样
myLogClass << "Line No: " << __LINE__
<< " Function: " << __FUNCTION__
<< " Error: " << "This is my error to be logged";
I would like to just be able to do:
我想能够做到:
myLogClass << "This is my error to be logged";
bool myLogClass::operator<<( const char * input ) {
logItInSQL( " Line No: __LINE__" );
logItInSQL( " Function: __FUNCTION__" );
logItInSQL( " Error: " + input );
return true;
}
5 个解决方案
#1
myLogClass << "Line No: " << __LINE__ ...
With your operator <<
chaining will not work since it returns a bool
.
使用您的运算符< <链接将无法工作,因为它返回一个bool。< p>
bool myLogClass::operator << (const char * input)
It is customary to define stream insertion as follows:
通常按如下方式定义流插入:
std::ostream& myLogClass::operator << (std::ostream& o, const char * input) {
// do something
return o;
}
Do this:
#define log(o, s) o << "Line No: " << __LINE__ << \
" Function: " << __FUNCTION__ << \
" Error: " << s // note I leave ; out
Additionally, you can wrap the macro in a do-while
loop:
此外,您可以在do-while循环中包装宏:
#define log(o, s) do { o << "Line No: " << __LINE__ << \
" Function: " << __FUNCTION__ << \
" Error: " << s; \
} while(0) // here, I leave ; out
Then you can happily write:
然后你可以高兴地写:
myLogClass myLogger; // do this
// use it
log(myLogger, "This is my error to be logged"); // note the ;
#2
In ANSI C (which should also work in C++ I assume), you can do that using variadic functions and preprocessor macros. See example below:
在ANSI C中(我也应该在C ++中工作),您可以使用可变参数函数和预处理器宏来实现。见下面的例子:
#include <stdio.h>
#include <stdarg.h>
#define MAXMSIZE 256
#define MyDebug(...) MyInternalDebug(__FILE__,__FUNCTION__,__LINE__,__VA_ARGS__)
void MyInternalDebug( char *file, char *function, const int line, const char *format, ... )
{
char message[MAXMSIZE];
// Variable argument list (VA)
va_list ap;
// Initialize VA
// args : Name of the last named parameter in the function definition.
// The arguments extracted by subsequent calls to va_arg are those after 'args'.
va_start(ap, format);
// Composes a string with the same text that would be printed if 'format' was used on printf,
// but using the elements in the variable argument list identified by 'ap' instead of
// additional function arguments and storing the resulting content as a C string in the buffer pointed by 'message'.
// * The state of arg is likely to be altered by the call.
vsprintf(message, format, ap);
// Custom print function
printf("%s\t%s\t%d\t%s\n",file, function, line, message);
// Finzalize use of VA
va_end(ap);
}
int main ()
{
MyInternalDebug(__FILE__, __FUNCTION__, __LINE__, "An error occured with message = '%s'", "Stack Overflow");
MyDebug("Another error occured with code = %d", 666);
return 0;
}
#3
No, this is why logging is done with macros. __LINE__
needs to be expanded by the preprocessor on the line in question, not in a common logging function.
不,这就是使用宏完成日志记录的原因。 __LINE__需要由相关行上的预处理器进行扩展,而不是在常见的日志记录功能中进行扩展。
#4
As Adam Mitz mentioned you need to use __LINE__ in the place of call.
I recommend to you to add an extra parameter like "additionalInfo" and create a macro that will generate this "additionalInfo" using __LINE__ and __FUNCTION__.
正如Adam Mitz所说,你需要在呼叫中使用__LINE__。我建议你添加一个额外的参数,如“additionalInfo”,并创建一个宏,使用__LINE__和__FUNCTION__生成这个“additionalInfo”。
#5
I could not get the code in the first answer to compile. I use this simple macro which accomplishes the task well:
我无法在编译的第一个答案中获得代码。我使用这个简单的宏来完成任务:
#define qlog(s) std::cerr << __FUNCTION__ << "::" << __LINE__ << "\t" << s << endl
#define qlog(s)std :: cerr << __FUNCTION__ <<“::”<< __LINE__ <<“\ t”<< s << << endl
#1
myLogClass << "Line No: " << __LINE__ ...
With your operator <<
chaining will not work since it returns a bool
.
使用您的运算符< <链接将无法工作,因为它返回一个bool。< p>
bool myLogClass::operator << (const char * input)
It is customary to define stream insertion as follows:
通常按如下方式定义流插入:
std::ostream& myLogClass::operator << (std::ostream& o, const char * input) {
// do something
return o;
}
Do this:
#define log(o, s) o << "Line No: " << __LINE__ << \
" Function: " << __FUNCTION__ << \
" Error: " << s // note I leave ; out
Additionally, you can wrap the macro in a do-while
loop:
此外,您可以在do-while循环中包装宏:
#define log(o, s) do { o << "Line No: " << __LINE__ << \
" Function: " << __FUNCTION__ << \
" Error: " << s; \
} while(0) // here, I leave ; out
Then you can happily write:
然后你可以高兴地写:
myLogClass myLogger; // do this
// use it
log(myLogger, "This is my error to be logged"); // note the ;
#2
In ANSI C (which should also work in C++ I assume), you can do that using variadic functions and preprocessor macros. See example below:
在ANSI C中(我也应该在C ++中工作),您可以使用可变参数函数和预处理器宏来实现。见下面的例子:
#include <stdio.h>
#include <stdarg.h>
#define MAXMSIZE 256
#define MyDebug(...) MyInternalDebug(__FILE__,__FUNCTION__,__LINE__,__VA_ARGS__)
void MyInternalDebug( char *file, char *function, const int line, const char *format, ... )
{
char message[MAXMSIZE];
// Variable argument list (VA)
va_list ap;
// Initialize VA
// args : Name of the last named parameter in the function definition.
// The arguments extracted by subsequent calls to va_arg are those after 'args'.
va_start(ap, format);
// Composes a string with the same text that would be printed if 'format' was used on printf,
// but using the elements in the variable argument list identified by 'ap' instead of
// additional function arguments and storing the resulting content as a C string in the buffer pointed by 'message'.
// * The state of arg is likely to be altered by the call.
vsprintf(message, format, ap);
// Custom print function
printf("%s\t%s\t%d\t%s\n",file, function, line, message);
// Finzalize use of VA
va_end(ap);
}
int main ()
{
MyInternalDebug(__FILE__, __FUNCTION__, __LINE__, "An error occured with message = '%s'", "Stack Overflow");
MyDebug("Another error occured with code = %d", 666);
return 0;
}
#3
No, this is why logging is done with macros. __LINE__
needs to be expanded by the preprocessor on the line in question, not in a common logging function.
不,这就是使用宏完成日志记录的原因。 __LINE__需要由相关行上的预处理器进行扩展,而不是在常见的日志记录功能中进行扩展。
#4
As Adam Mitz mentioned you need to use __LINE__ in the place of call.
I recommend to you to add an extra parameter like "additionalInfo" and create a macro that will generate this "additionalInfo" using __LINE__ and __FUNCTION__.
正如Adam Mitz所说,你需要在呼叫中使用__LINE__。我建议你添加一个额外的参数,如“additionalInfo”,并创建一个宏,使用__LINE__和__FUNCTION__生成这个“additionalInfo”。
#5
I could not get the code in the first answer to compile. I use this simple macro which accomplishes the task well:
我无法在编译的第一个答案中获得代码。我使用这个简单的宏来完成任务:
#define qlog(s) std::cerr << __FUNCTION__ << "::" << __LINE__ << "\t" << s << endl
#define qlog(s)std :: cerr << __FUNCTION__ <<“::”<< __LINE__ <<“\ t”<< s << << endl