Hi,
I'm wondering if a "Scope Tracer" or a "General Scope Function" can be easily implemented with existing boost libraries now.
One example use case is to log variable or parameter values or any program state when entering or leaving a scope, but it can do more than just logging, it can, for example, lock/unlock mutex, or prepare/teardown test cases, etc.
For logging requirement, to give you an idea, the expected log message looks like this:
>04/10/09 05:29:12:210257 entering func foo with parameter a=10, b=1.5, d.x=10, d.y=[string], global d=2, filename:test.cpp
>04/10/09 05:29:12:210257 entering while() a=10, b=1.5, d.x=10
>04/10/09 05:29:12:210257 leaving while() a=9, b=1.5, d.x=9
>04/10/09 05:29:12:210257 entering while() a=9, b=1.5, d.x=9
>04/10/09 05:29:12:210257 leaving while() a=8, b=1.5, d.x=8
>...
>04/10/09 05:29:12:210257 entering while() a=2, b=1.5, d.x=2
>04/10/09 05:29:12:210257 leaving while() a=1, b=1.5, d.x=1
>04/10/09 05:29:12:210257 entering while() a=1, b=1.5, d.x=1
>04/10/09 05:29:12:210257 leaving while() a=0, b=1.5, d.x=0
>04/10/09 05:29:12:210257 leaving function foo with parameter a=0, b=1.5, d.x=0, d.y=[string], global d=2, filename:test.cpp
It does not have to be logging, it can do any general processing when entering/leaving a scope.
I implemented a small library to do so in 2008 mainly for tracing, it worked fine for me and I never revisited it again until recently. Wondering if boost has libraries to support such a requirment.
My implementation has a template class logger_class which can manage the log-level at runtime and send the log message to standard-output or other places. Application code use a macro to invoke the library, the macro can be disabled at compile time, or weakened to only log scope without variables.
Example of the macro definition:
#ifdef ENABLE_ONLY_SCOPE_TRACER
#define SCOPE_TRACER(logger_class, logger, args, level, scope) \
scope_tracer<logger_class> tracer_obj(logger, __FUNCTION__, __FILE__, __LINE__); \
if (logger.get_level() >= level){ \
tracer_obj.init(level, scope).noMore(); \
}
#else
#ifdef DISABLE_SCOPE_VAR_TRACER
#define SCOPE_TRACER(logger_class, logger, args, level, scope)
#else
#define SCOPE_TRACER(logger_class, logger, args, level, scope) \
scope_tracer<loggerClass> tracer_obj(logger, __FUNCTION__, __FILE__, __LINE__); \
if (logger.get_level() >= level){ \
tracer_obj.init(level, scope) << args; \
tracer_obj.noMore(); \
}
#endif
#endif
Application code example:
int globalVar;
void MyClass::func1( A a, B&b, C* c, int d, std::string & s){
SCOPE_TRACER(MyLogger, test_logger, a<<b<<c<<d<<s<<globalVar, LOG_LEVEL_TRACE, "func1");
...
int localVar;
while(x){
SCOPE_TRACER(MyLogger, test_logger, x<<a<<b<<c<<d<<s<<globalVar<<localVar, LOG_LEVEL_TRACE, "while(x)");
...
}
...
}
As you see, "<<" operator is being used. But it does not have to be only "<<" operator. Basically any C++ operator can be supported between the logger class and logged type. And the logger_class is not limited to just do tracing, it can virtuall do anything.
I can attach the code if needed. The code was compiled with GCC on linux and VisualStudio on Windows.
If the above functionality can be easily achieved using existing boot library, please advise how. Otherwise is it worth to request such a feature in boost?
Thanks,
Anlin