This file is an example of how to use the current module name to select the Log4cxx configuration file.
#include "config.h"
#ifdef WIN32
#include <Windows.h>
#elif __APPLE__
#include <mach-o/dyld.h>
#else
#include <unistd.h>
#endif
namespace {
auto DefaultConfigurationFileNames(std::string& altPrefix) -> std::vector<std::string> {
std::vector<std::string> result;
static const int bufSize = 4096;
char buf[bufSize+1] = {0}, pathSepar = '/';
uint32_t bufCount = 0;
#if defined(WIN32)
GetModuleFileName(NULL, buf, bufSize);
pathSepar = '\\';
#elif defined(__APPLE__)
_NSGetExecutablePath(buf, &bufCount);
#else
std::ostringstream exeLink;
exeLink << "/proc/" << getpid() << "/exe";
bufCount = readlink(exeLink.str().c_str(), buf, bufSize);
if (0 < bufCount)
buf[bufCount] = 0;
#endif
std::string programFileName(buf);
auto slashIndex = programFileName.rfind(pathSepar);
if (std::string::npos != slashIndex) {
altPrefix = programFileName.substr(0, slashIndex + 1);
#if defined(_DEBUG)
LogString msg1 = LOG4CXX_STR(
"Alternate prefix [");
helpers::Transcoder::decode(altPrefix, msg1);
msg1 += LOG4CXX_STR("]");
helpers::LogLog::debug(msg1);
#endif
result.push_back(programFileName.substr(slashIndex + 1));
#if defined(_DEBUG)
LogString msg2(LOG4CXX_STR(
"Alternate configuration file name ["));
helpers::Transcoder::decode(result.back(), msg2);
msg2 += LOG4CXX_STR("]");
helpers::LogLog::debug(msg2);
#endif
auto dotIndex = result.back().rfind('.');
if (std::string::npos != dotIndex) {
result.push_back(result.back());
result.back().erase(dotIndex);
#if defined(_DEBUG)
LogString msg3(LOG4CXX_STR(
"Alternate configuration file name ["));
helpers::Transcoder::decode(result.back(), msg3);
msg3 += LOG4CXX_STR("]");
helpers::LogLog::debug(msg3);
#endif
}
}
else if (!programFileName.empty()) {
auto dotIndex = result.back().rfind('.');
if (std::string::npos != dotIndex) {
programFileName.erase(dotIndex);
result.push_back(programFileName);
#if defined(_DEBUG)
LogString msg(LOG4CXX_STR(
"Alternate configuration file name ["));
helpers::Transcoder::decode(result.back(), msg);
msg += LOG4CXX_STR("]");
helpers::LogLog::debug(msg);
#endif
}
}
result.push_back("log4cxx");
result.push_back("log4j");
return result;
}
void SelectConfigurationFile() {
#if defined(_DEBUG)
helpers::LogLog::setInternalDebugging(true);
#endif
const char* extension[] = { ".xml", ".properties", 0 };
std::string altPrefix;
for (auto baseName : DefaultConfigurationFileNames(altPrefix)) {
int i = 0;
for (; extension[i]; ++i) {
File current_working_dir_candidate(baseName + extension[i]);
if (current_working_dir_candidate.
exists(pool)) {
DefaultConfigurator::setConfigurationFileName(current_working_dir_candidate.
getPath());
DefaultConfigurator::setConfigurationWatchSeconds(5);
break;
}
if (!altPrefix.empty()) {
File alt_dir_candidate(altPrefix + baseName + extension[i]);
if (alt_dir_candidate.
exists(pool)) {
DefaultConfigurator::setConfigurationFileName(alt_dir_candidate.
getPath());
DefaultConfigurator::setConfigurationWatchSeconds(5);
break;
}
}
}
if (extension[i])
break;
}
}
}
namespace com { namespace foo {
auto getLogger(
const std::string& name) ->
LoggerPtr {
static struct log4cxx_initializer {
log4cxx_initializer() {
SelectConfigurationFile();
}
~log4cxx_initializer() {
}
} initialiser;
return name.empty()
}
} }
An abstract representation of file and directory path names.
Definition: file.h:41
bool exists(log4cxx::helpers::Pool &p) const
Determines if file exists.
LogString getPath() const
Get file path.
Use the LogManager class to retreive Logger instances or to operate on the current LoggerRepository.
Definition: logmanager.h:45
static LoggerPtr getRootLogger()
Retrieve the root logger from the LoggerRepository.
static void shutdown()
Safely close and remove all appenders in all loggers including the root logger.
Definition: configuration.h:25
std::basic_string< logchar > LogString
Definition: logstring.h:60
std::shared_ptr< Logger > LoggerPtr
Definition: defaultloggerfactory.h:27