Apache Log4cxx  Version 1.1.0
com/foo/config3.cpp

This file is an example of how to use the current module name to select the Log4cxx configuration file.

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "config.h"
#include <log4cxx/file.h>
#ifdef WIN32
#include <Windows.h>
#elif __APPLE__
#include <mach-o/dyld.h>
#else
#include <unistd.h> /* getpid */
#endif
// Local functions
namespace {
using namespace log4cxx;
// Get a list of file base names that may contain configuration data
// and put an alternate path into \c altPrefix
auto DefaultConfigurationFileNames(std::string& altPrefix) -> std::vector<std::string> {
std::vector<std::string> result;
// Find the executable file name
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) {
// Extract the path
altPrefix = programFileName.substr(0, slashIndex + 1);
#if defined(_DEBUG)
LogString msg1 = LOG4CXX_STR("Alternate prefix [");
helpers::Transcoder::decode(altPrefix, msg1);
msg1 += LOG4CXX_STR("]");
#endif
// Add a local directory relative name
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("]");
#endif
// Add a local directory relative name without any extension
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("]");
#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("]");
#endif
}
}
result.push_back("log4cxx");
result.push_back("log4j");
return result;
}
// Provide the name of the configuration file to [DefaultConfigurator](@ref log4cxx.DefaultConfigurator).
// Set up a background thread that will check for changes every 5 seconds and reload the configuration
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)) {
DefaultConfigurator::setConfigurationFileName(current_working_dir_candidate.getPath());
break;
}
if (!altPrefix.empty()) {
File alt_dir_candidate(altPrefix + baseName + extension[i]);
if (alt_dir_candidate.exists(pool)) {
DefaultConfigurator::setConfigurationFileName(alt_dir_candidate.getPath());
break;
}
}
}
if (extension[i]) // Found a configuration file?
break;
}
}
} // namespace
namespace com { namespace foo {
// Retrieve the \c name logger pointer.
// Configure Log4cxx on the first call.
auto getLogger(const std::string& name) -> LoggerPtr {
static struct log4cxx_initializer {
log4cxx_initializer() {
SelectConfigurationFile();
}
~log4cxx_initializer() {
}
} initialiser;
return name.empty()
: log4cxx::LogManager::getLogger(name);
}
} } // namespace com::foo
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