Console: improve console logging facility
This commit is contained in:
@@ -40,6 +40,7 @@
|
||||
#include "Exception.h"
|
||||
#include "PyObjectBase.h"
|
||||
#include <QCoreApplication>
|
||||
#include <frameobject.h>
|
||||
|
||||
using namespace Base;
|
||||
|
||||
@@ -251,18 +252,24 @@ void ConsoleSingleton::SetConnectionMode(ConnectionMode mode)
|
||||
*/
|
||||
void ConsoleSingleton::Message( const char *pMsg, ... )
|
||||
{
|
||||
char format[BufferSize];
|
||||
const unsigned int format_len = BufferSize;
|
||||
#define FC_CONSOLE_FMT(_type,_type2) \
|
||||
char format[BufferSize];\
|
||||
format[sizeof(format)-4] = '.';\
|
||||
format[sizeof(format)-3] = '.';\
|
||||
format[sizeof(format)-2] = '\n';\
|
||||
format[sizeof(format)-1] = 0;\
|
||||
const unsigned int format_len = sizeof(format)-4;\
|
||||
va_list namelessVars;\
|
||||
va_start(namelessVars, pMsg);\
|
||||
vsnprintf(format, format_len, pMsg, namelessVars);\
|
||||
format[sizeof(format)-5] = '.';\
|
||||
va_end(namelessVars);\
|
||||
if (connectionMode == Direct)\
|
||||
Notify##_type(format);\
|
||||
else\
|
||||
QCoreApplication::postEvent(ConsoleOutput::getInstance(), new ConsoleEvent(MsgType_##_type2, format));
|
||||
|
||||
va_list namelessVars;
|
||||
va_start(namelessVars, pMsg); // Get the "..." vars
|
||||
vsnprintf(format, format_len, pMsg, namelessVars);
|
||||
va_end(namelessVars);
|
||||
|
||||
if (connectionMode == Direct)
|
||||
NotifyMessage(format);
|
||||
else
|
||||
QCoreApplication::postEvent(ConsoleOutput::getInstance(), new ConsoleEvent(MsgType_Txt, format));
|
||||
FC_CONSOLE_FMT(Message,Txt);
|
||||
}
|
||||
|
||||
/** Prints a Message
|
||||
@@ -282,18 +289,7 @@ void ConsoleSingleton::Message( const char *pMsg, ... )
|
||||
*/
|
||||
void ConsoleSingleton::Warning( const char *pMsg, ... )
|
||||
{
|
||||
char format[BufferSize];
|
||||
const unsigned int format_len = BufferSize;
|
||||
|
||||
va_list namelessVars;
|
||||
va_start(namelessVars, pMsg); // Get the "..." vars
|
||||
vsnprintf(format, format_len, pMsg, namelessVars);
|
||||
va_end(namelessVars);
|
||||
|
||||
if (connectionMode == Direct)
|
||||
NotifyWarning(format);
|
||||
else
|
||||
QCoreApplication::postEvent(ConsoleOutput::getInstance(), new ConsoleEvent(MsgType_Wrn, format));
|
||||
FC_CONSOLE_FMT(Warning,Wrn);
|
||||
}
|
||||
|
||||
/** Prints a Message
|
||||
@@ -313,18 +309,7 @@ void ConsoleSingleton::Warning( const char *pMsg, ... )
|
||||
*/
|
||||
void ConsoleSingleton::Error( const char *pMsg, ... )
|
||||
{
|
||||
char format[BufferSize];
|
||||
const unsigned int format_len = BufferSize;
|
||||
|
||||
va_list namelessVars;
|
||||
va_start(namelessVars, pMsg); // Get the "..." vars
|
||||
vsnprintf(format, format_len, pMsg, namelessVars);
|
||||
va_end(namelessVars);
|
||||
|
||||
if (connectionMode == Direct)
|
||||
NotifyError(format);
|
||||
else
|
||||
QCoreApplication::postEvent(ConsoleOutput::getInstance(), new ConsoleEvent(MsgType_Err, format));
|
||||
FC_CONSOLE_FMT(Error,Err);
|
||||
}
|
||||
|
||||
|
||||
@@ -346,24 +331,12 @@ void ConsoleSingleton::Error( const char *pMsg, ... )
|
||||
|
||||
void ConsoleSingleton::Log( const char *pMsg, ... )
|
||||
{
|
||||
char format[BufferSize];
|
||||
const unsigned int format_len = BufferSize;
|
||||
|
||||
if (_bVerbose)
|
||||
if (!_bVerbose)
|
||||
{
|
||||
va_list namelessVars;
|
||||
va_start(namelessVars, pMsg); // Get the "..." vars
|
||||
vsnprintf(format, format_len, pMsg, namelessVars);
|
||||
va_end(namelessVars);
|
||||
|
||||
if (connectionMode == Direct)
|
||||
NotifyLog(format);
|
||||
else
|
||||
QCoreApplication::postEvent(ConsoleOutput::getInstance(), new ConsoleEvent(MsgType_Log, format));
|
||||
FC_CONSOLE_FMT(Log,Log);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Delivers the time/date
|
||||
* This method gives you a string with the actual time/date. You can
|
||||
* use that for Log() calls to make timestamps.
|
||||
@@ -464,7 +437,7 @@ int *ConsoleSingleton::GetLogLevel(const char *tag, bool create) {
|
||||
|
||||
void ConsoleSingleton::Refresh() {
|
||||
if(_bCanRefresh)
|
||||
QCoreApplication::sendPostedEvents();
|
||||
qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
|
||||
}
|
||||
|
||||
void ConsoleSingleton::EnableRefresh(bool enable) {
|
||||
@@ -552,7 +525,7 @@ PyObject *ConsoleSingleton::sPyMessage(PyObject * /*self*/, PyObject *args)
|
||||
|
||||
PY_TRY {
|
||||
if (string)
|
||||
Instance().Message("%s",string); // process message
|
||||
Instance().NotifyMessage(string); // process message
|
||||
} PY_CATCH;
|
||||
|
||||
Py_XDECREF(unicode);
|
||||
@@ -598,7 +571,7 @@ PyObject *ConsoleSingleton::sPyWarning(PyObject * /*self*/, PyObject *args)
|
||||
|
||||
PY_TRY {
|
||||
if (string)
|
||||
Instance().Warning("%s",string); // process message
|
||||
Instance().NotifyWarning(string); // process message
|
||||
} PY_CATCH;
|
||||
|
||||
Py_XDECREF(unicode);
|
||||
@@ -644,7 +617,7 @@ PyObject *ConsoleSingleton::sPyError(PyObject * /*self*/, PyObject *args)
|
||||
|
||||
PY_TRY {
|
||||
if (string)
|
||||
Instance().Error("%s",string); // process message
|
||||
Instance().NotifyError(string); // process message
|
||||
} PY_CATCH;
|
||||
|
||||
Py_XDECREF(unicode);
|
||||
@@ -690,7 +663,7 @@ PyObject *ConsoleSingleton::sPyLog(PyObject * /*self*/, PyObject *args)
|
||||
|
||||
PY_TRY {
|
||||
if (string)
|
||||
Instance().Log("%s",string); // process message
|
||||
Instance().NotifyLog(string); // process message
|
||||
} PY_CATCH;
|
||||
|
||||
Py_XDECREF(unicode);
|
||||
@@ -968,8 +941,23 @@ std::stringstream &LogLevel::prefix(std::stringstream &str, const char *src, int
|
||||
str << d.count() << ' ';
|
||||
}
|
||||
if(print_tag) str << '<' << tag << "> ";
|
||||
if(print_src) {
|
||||
if(print_src==2) {
|
||||
PyFrameObject* frame = PyEval_GetFrame();
|
||||
if(frame) {
|
||||
line = PyFrame_GetLineNumber(frame);
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
src = PyUnicode_AsUTF8(frame->f_code->co_filename);
|
||||
#else
|
||||
src = PyString_AsString(frame->f_code->co_filename);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if(print_src && src && src[0]) {
|
||||
#ifdef FC_OS_WIN32
|
||||
const char *_f = std::strrchr(src, '\\');
|
||||
#else
|
||||
const char *_f = std::strrchr(src, '/');
|
||||
#endif
|
||||
str << (_f?_f+1:src)<<"("<<line<<"): ";
|
||||
}
|
||||
return str;
|
||||
|
||||
@@ -123,7 +123,7 @@
|
||||
* shown blew along with their default values.
|
||||
*
|
||||
* \code{.c}
|
||||
* FC_LOG_LEVEL_INIT(tag, print_tag=true, print_src=false,
|
||||
* FC_LOG_LEVEL_INIT(tag, print_tag=true, print_src=0,
|
||||
* print_time=false, add_eol=true, refresh=false)
|
||||
* \endcode
|
||||
*
|
||||
@@ -133,7 +133,11 @@
|
||||
*
|
||||
* \code{.c}
|
||||
* FC_LOG_INSTANCE.refresh = true; // print time for each log, default false.
|
||||
* FC_LOG_INSTANCE.print_src = true; // print file and line number, default false.
|
||||
*
|
||||
* // print file and line number, default 0, if set to 2 then print python
|
||||
* // source from current call frame.
|
||||
* FC_LOG_INSTANCE.print_src = 1;
|
||||
*
|
||||
* FC_LOG_INSTANCE.print_tag = false; // do not print tag, default true
|
||||
* FC_LOG_INSTANCE.add_eol = false; // do not add eol
|
||||
* FC_LOG_INSTANCE.refresh = true; // refresh GUI after each log
|
||||
@@ -349,24 +353,34 @@
|
||||
#define FC_LOG_LEVEL_INIT(_tag,...) \
|
||||
_FC_LOG_LEVEL_INIT(FC_LOG_INSTANCE, _tag, ## __VA_ARGS__)
|
||||
|
||||
#define _FC_PRINT(_instance,_l,_func,_msg) do{\
|
||||
#define __FC_PRINT(_instance,_l,_func,_msg,_file,_line) do{\
|
||||
if(_instance.isEnabled(_l)) {\
|
||||
std::stringstream str;\
|
||||
_instance.prefix(str,__FILE__,__LINE__) << _msg;\
|
||||
std::stringstream _str;\
|
||||
_instance.prefix(_str,_file,_line) << _msg;\
|
||||
if(_instance.add_eol) \
|
||||
str<<std::endl;\
|
||||
Base::Console()._func("%s",str.str().c_str());\
|
||||
_str<<std::endl;\
|
||||
Base::Console()._func(_str.str().c_str());\
|
||||
if(_instance.refresh) Base::Console().Refresh();\
|
||||
}\
|
||||
}while(0)
|
||||
|
||||
#define FC_MSG(_msg) _FC_PRINT(FC_LOG_INSTANCE,FC_LOGLEVEL_MSG,Message,_msg)
|
||||
#define FC_WARN(_msg) _FC_PRINT(FC_LOG_INSTANCE,FC_LOGLEVEL_WARN,Warning,_msg)
|
||||
#define FC_ERR(_msg) _FC_PRINT(FC_LOG_INSTANCE,FC_LOGLEVEL_ERR,Error,_msg)
|
||||
#define FC_LOG(_msg) _FC_PRINT(FC_LOG_INSTANCE,FC_LOGLEVEL_LOG,Log,_msg)
|
||||
#define FC_TRACE(_msg) _FC_PRINT(FC_LOG_INSTANCE,FC_LOGLEVEL_TRACE,Log,_msg)
|
||||
#define _FC_PRINT(_instance,_l,_func,_msg) __FC_PRINT(_instance,_l,_func,_msg,__FILE__,__LINE__)
|
||||
|
||||
#define FC_MSG(_msg) _FC_PRINT(FC_LOG_INSTANCE,FC_LOGLEVEL_MSG,NotifyMessage,_msg)
|
||||
#define FC_WARN(_msg) _FC_PRINT(FC_LOG_INSTANCE,FC_LOGLEVEL_WARN,NotifyWarning,_msg)
|
||||
#define FC_ERR(_msg) _FC_PRINT(FC_LOG_INSTANCE,FC_LOGLEVEL_ERR,NotifyError,_msg)
|
||||
#define FC_LOG(_msg) _FC_PRINT(FC_LOG_INSTANCE,FC_LOGLEVEL_LOG,NotifyLog,_msg)
|
||||
#define FC_TRACE(_msg) _FC_PRINT(FC_LOG_INSTANCE,FC_LOGLEVEL_TRACE,NotifyLog,_msg)
|
||||
|
||||
#define _FC_MSG(_file,_line,_msg) __FC_PRINT(FC_LOG_INSTANCE,FC_LOGLEVEL_MSG,NotifyMessage,_msg,_file,_line)
|
||||
#define _FC_WARN(_file,_line,_msg) __FC_PRINT(FC_LOG_INSTANCE,FC_LOGLEVEL_WARN,NotifyWarning,_msg,_file,_line)
|
||||
#define _FC_ERR(_file,_line,_msg) __FC_PRINT(FC_LOG_INSTANCE,FC_LOGLEVEL_ERR,NotifyError,_msg,_file,_line)
|
||||
#define _FC_LOG(_file,_line,_msg) __FC_PRINT(FC_LOG_INSTANCE,FC_LOGLEVEL_LOG,NotifyLog,_msg,_file,_line)
|
||||
#define _FC_TRACE(_file,_line,_msg) __FC_PRINT(FC_LOG_INSTANCE,FC_LOGLEVEL_TRACE,NotifyLog,_msg,_file,_line)
|
||||
|
||||
#define FC_XYZ(_pt) '('<<(_pt).X()<<", " << (_pt).Y()<<", " << (_pt).Z()<<')'
|
||||
#define FC_XY(_pt) '('<<(_pt).x<<", " << (_pt).y<<')'
|
||||
#define FC_xy(_pt) '('<<(_pt).x<<", " << (_pt).y<<')'
|
||||
#define FC_xyz(_pt) '('<<(_pt).x<<", " << (_pt).y<<", " << (_pt).z<<')'
|
||||
|
||||
#ifndef FC_LOG_NO_TIMING
|
||||
# define FC_TIME_CLOCK high_resolution_clock
|
||||
@@ -506,7 +520,13 @@ public:
|
||||
/// Prints a log Message
|
||||
virtual void Log ( const char * pMsg, ... ) ;
|
||||
|
||||
/// Delivers a time/date string
|
||||
// observer processing
|
||||
void NotifyMessage(const char *sMsg);
|
||||
void NotifyWarning(const char *sMsg);
|
||||
void NotifyError (const char *sMsg);
|
||||
void NotifyLog (const char *sMsg);
|
||||
|
||||
/// Delivers a time/date string
|
||||
const char* Time(void);
|
||||
/// Attaches an Observer to FCConsole
|
||||
void AttachObserver(ConsoleObserver *pcObserver);
|
||||
@@ -582,12 +602,6 @@ private:
|
||||
static void Destruct(void);
|
||||
static ConsoleSingleton *_pcSingleton;
|
||||
|
||||
// observer processing
|
||||
void NotifyMessage(const char *sMsg);
|
||||
void NotifyWarning(const char *sMsg);
|
||||
void NotifyError (const char *sMsg);
|
||||
void NotifyLog (const char *sMsg);
|
||||
|
||||
// observer list
|
||||
std::set<ConsoleObserver * > _aclObservers;
|
||||
|
||||
@@ -623,12 +637,12 @@ public:
|
||||
std::string tag;
|
||||
int &lvl;
|
||||
bool print_tag;
|
||||
bool print_src;
|
||||
int print_src;
|
||||
bool print_time;
|
||||
bool add_eol;
|
||||
bool refresh;
|
||||
|
||||
LogLevel(const char *tag, bool print_tag=true, bool print_src=false,
|
||||
LogLevel(const char *tag, bool print_tag=true, int print_src=0,
|
||||
bool print_time=false, bool add_eol=true, bool refresh=false)
|
||||
:tag(tag),lvl(*Console().GetLogLevel(tag))
|
||||
,print_tag(print_tag),print_src(print_src),print_time(print_time)
|
||||
|
||||
Reference in New Issue
Block a user