Apache Log4cxx  Version 1.5.0
Loading...
Searching...
No Matches
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>
#elif (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 500) || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L)
#include <unistd.h> // getpid
#else
#include <cstring> // strncpy
#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);
#elif (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 500) || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L)
std::ostringstream exeLink;
exeLink << "/proc/" << getpid() << "/exe";
bufCount = readlink(exeLink.str().c_str(), buf, bufSize);
if (0 < bufCount)
buf[bufCount] = 0;
#else
strncpy(buf, "auto-configured", bufSize);
#endif
std::string programFileName(buf);
auto slashIndex = programFileName.rfind(pathSepar);
if (std::string::npos != slashIndex) {
// Extract the path
altPrefix = programFileName.substr(0, slashIndex + 1);
{
LogString msg = LOG4CXX_STR("Alternate prefix [");
helpers::Transcoder::decode(altPrefix, msg);
msg += LOG4CXX_STR("]");
}
// Add a local directory relative name
result.push_back(programFileName.substr(slashIndex + 1));
{
LogString msg(LOG4CXX_STR("Alternate configuration file name ["));
helpers::Transcoder::decode(result.back(), msg);
msg += LOG4CXX_STR("]");
}
// 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);
{
LogString msg(LOG4CXX_STR("Alternate configuration file name ["));
helpers::Transcoder::decode(result.back(), msg);
msg += LOG4CXX_STR("]");
}
}
}
else if (!programFileName.empty()) {
auto dotIndex = result.back().rfind('.');
if (std::string::npos != dotIndex) {
programFileName.erase(dotIndex);
result.push_back(programFileName);
{
LogString msg(LOG4CXX_STR("Alternate configuration file name ["));
helpers::Transcoder::decode(result.back(), msg);
msg += LOG4CXX_STR("]");
}
}
}
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;
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)) {
break;
}
}
}
if (extension[i]) // Found a configuration file?
return;
}
// Configuration file not found - send events to the console
}
} // namespace
namespace com { namespace foo {
// Retrieve the \c name logger pointer.
// Configure Log4cxx on the first call.
auto getLogger(const std::string& name) -> LoggerPtr {
using namespace log4cxx;
static struct log4cxx_initializer {
log4cxx_initializer() {
SelectConfigurationFile();
}
~log4cxx_initializer() {
LogManager::shutdown();
}
} initialiser;
return name.empty()
? LogManager::getRootLogger()
: LogManager::getLogger(name);
}
} } // namespace com::foo
static void configure(const LayoutPtr &layout=LayoutPtr())
Add a ConsoleAppender to the root logger that formats output using layout.
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...
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.
static void setInternalDebugging(bool enabled)
Use the value of enabled as the new internal debug logging state.
static bool isDebugEnabled()
Is internal debugging enabled?
static void debug(const LogString &msg)
Output msg to SystemErrWriter if internal debug logging is enabled.
Definition pool.h:33
static unsigned int decode(const std::string &in, std::string::const_iterator &iter)
Decodes next character from a UTF-8 string.
Definition configuration.h:25
std::basic_string< logchar > LogString
Definition logstring.h:60
std::shared_ptr< Logger > LoggerPtr
Definition defaultloggerfactory.h:27