I have different parts of my application calling a logger function to log details.
Logger class
std::string filename = "blahblah"; // variable to store the location of the properties file
log4cpp::PropertyConfigurator::configure(filename);
void Logger::logging(const std::string& msg)
{
Log4cpp::Category& myLogger = log4cpp::Category::getRoot();
myLogger.log(log4cpp::Priority::INFO, msg);//only takes in string as input
}
Calling class
Logger logMe;
int a = 5;
double b = 6;
logMe.logging("log this msg" + a + "," + b);
I realised that the above will give me error, as a
and b
are of different types. One way to solve it is to use std::to_string
logMe.logging("log this msg" + std::to_string(a) + "," + std::to_string(b));
However, I have hundreds of calls to the logging function, and it will be time consuming to edit each and every call to std::to_string
. Is/are there any easier way(s) to do it?
Oh and to clarify, the code works before as the previous way was by defining a #define function.
#Define logging(FLAG, X)\
do {\
...
clog << x; \
}while(0)
logging(LogFlag::Warning, "log this msg" << a << "," << b << endl);
But i am now rewriting parts of the code to comply to static testing.
Thanks in advance.
You can add an overload of logging
that takes a parameter pack and joins it up into a string, using std::stringstream
In c++17, we can use a fold expression, e.g.
template <typename Args ...>
void Logger::logging(Args ... args)
{
std::stringstream ss;
(ss << ... << args);
Log4cpp::Category& myLogger = log4cpp::Category::getRoot();
myLogger.log(log4cpp::Priority::INFO, ss.str());
}
In c++11 or 14, we have to be slightly more tricky
template <typename ... Args >
void Logger::logging(Args ... args)
{
std::stringstream ss;
std::initializer_list<int> unused{ (ss << args, 0)... };
Log4cpp::Category& myLogger = log4cpp::Category::getRoot();
myLogger.log(log4cpp::Priority::INFO, ss.str());
}
Then you call either as e.g.
logMe.logging("log this msg", a, ",", b);