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 [");
msg1 += LOG4CXX_STR("]");
#endif
result.push_back(programFileName.substr(slashIndex + 1));
#if defined(_DEBUG)
LogString msg2(LOG4CXX_STR(
"Alternate configuration file name ["));
msg2 += LOG4CXX_STR("]");
#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 ["));
msg3 += LOG4CXX_STR("]");
#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 ["));
msg += LOG4CXX_STR("]");
#endif
}
}
result.push_back("log4cxx");
result.push_back("log4j");
return result;
}
void SelectConfigurationFile() {
#if defined(_DEBUG)
#endif
const char* extension[] = { ".xml", ".properties", 0 };
std::string altPrefix;
helpers::Pool pool;
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)) {
break;
}
if (!altPrefix.empty()) {
File alt_dir_candidate(altPrefix + baseName + extension[i]);
if (alt_dir_candidate.exists(pool)) {
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()
:
log4cxx::LogManager::getLogger(name);
}
} }
static void setConfigurationFileName(const LogString &path)
Make path the configuration file used by configure().
static void setConfigurationWatchSeconds(int seconds)
Make seconds the time a background thread will delay before checking for a change to the configuratio...
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.
static void setInternalDebugging(bool enabled)
Use the value of enabled as the new internal debug logging state.
static void debug(const LogString &msg)
Output msg to SystemErrWriter if internal debug logging is enabled.
static unsigned int decode(const std::string &in, std::string::const_iterator &iter)
Decodes next character from a UTF-8 string.
Definition: appender.h:27
std::basic_string< logchar > LogString
Definition: logstring.h:60
std::shared_ptr< Logger > LoggerPtr
Definition: defaultloggerfactory.h:26