Hi,
Am using log4cplus 1.2.0(liblog4cplus.so on Linux and Unicode version on Windows - log4cplusU.dll on Windows Server 2008).
When you intialize log4cplus:
log4cplus::PropertyConfigurator::doConfigure(log4cplusConfig.c_str());
Is there an option to pass a callback to above api so caller can specify his own log file name instead of being forced to read it from log4cplus.properties...?
For ex. caller could have a callback function a() which he could pass to an overloaded version of above which would allow him to define his own FileAppender name in his callback a() for ex:
log4cplus::PropertyConfigurator::doConfigure(log4cplusConfig.c_str(), a);
where callback func a() could be:
void a(char * msg) { //Specify my own log file name and path std::string g_sDataLogPath = "abc/xyz/HiStorHdim.log"; FILE *pFile = ::fopen(pszFile, "ab"); if(pFile) { //Write log message to file fprintf(pFile, "FmtMsg[%s]\n", msg); ::fclose(pFile); } }
If this feature is not available now then can it be put in...? In my case log4cplus is wrapped in my library and caller of my library wants to specify log file name local in his own app(not having to pass that info to my library). Need this urgently for work project...!
You can parametrize the configuration file with environment variables which you can set in your application before you do the configuration.
Diff:
Yes but my caller is running his app as a service and does not have much freedom to set environment vars, so setting log file name is completely contained in his app(cannot get that info into my code space that's why was looking for callback like option).
Windows services can be started with command line parameters and I do not doubt you can start Linux services with command line parameter, too. Use (you or your client) this parameter to pass the path into the process itself and then, internally, set up some environment variable.
Another alternative is to construct the
PropertyConfigurator
out of your own providedstd::stringstream
orhelpers::Properties
where the path will be set to your desired value.Moreover, you can provide your own Appender instance derived either from Appender or existing appenders instead of using the stock ones.
Using an ad hoc callback to write the messages is not the way.
Are there any examples for how to construct helpers::Properties from std::stringstream...? IN other words how do I populate log4cplus::tistream input in:
Properties(log4cplus::tistream& input);
It seems there's issue in setProperty on the property object when trying to set any property in Visual Studio 2012 with Unicode enabled(I even tried to turn off UNICODE but didn't work). setProperty works in Linux though(since Unicode is off there).
Sample below:
log4cplus::helpers::Properties prop(strtowstr(log4cplusConfig).c_str());
//#ifdef _UNICODE
//#undef _UNICODE
//#undef UNICODE
log4cplus::tstring logFileKey = LOG4CPLUS_TEXT("log4cplus.appender.LOG.File");
log4cplus::tstring logLevelKey = LOG4CPLUS_TEXT("log4cplus.rootLogger");
//set first property below
prop.setProperty(logFileKey, strtowstr(m_strxyzLogPath).c_str()); //throws run-time erorr here
//set another property below
prop.setProperty(logLevelKey, strtowstr(sslogLevel.str()).c_str());
//#define _UNICODE
//#define UNICODE
//#endif
log4cplus::PropertyConfigurator propConfig(prop);
propConfig.configure();
}
It throws a run-time error like:
log4cplus:ERROR PropertyConfigurator::configureLogger()- Invalid appender: LOG
when I try to set(override) the "log4cplus.appender.LOG.File" property above.
These are thhe two properties am trying to override(in log4cplus.properties):
log4cplus.rootLogger=INFO,LOG
log4cplus.appender.LOG.File=${xyz_log_path}/xyz.log
Can let me know why setProperty is failing in Unicode...?