This is an automated email from the ASF dual-hosted git repository.
swebb2066 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/logging-log4cxx.git
The following commit(s) were added to refs/heads/master by this push:
new a4ebf8f8 Require the configuration file specify an appender to be
valid (#533)
a4ebf8f8 is described below
commit a4ebf8f81f294bb85020db1fb6f067d1a3abe24f
Author: Stephen Webb <[email protected]>
AuthorDate: Thu Sep 4 10:22:57 2025 +1000
Require the configuration file specify an appender to be valid (#533)
* Simplify DOMConfigurator
* Require that a properties file has an appender to be valid
* In the next ABI, require that a properties file adds an appender to be
valid
* Log a warning when the configuration file did not add an appender
* Upgrade sonarcube version to avoid Github action command injection
vulnerability
* Improve the layout of a logged XML syntax error
---
.github/workflows/sonarcloud.yml | 4 +-
src/main/cpp/charsetdecoder.cpp | 7 ++
src/main/cpp/defaultconfigurator.cpp | 1 -
src/main/cpp/domconfigurator.cpp | 137 +++++++++++----------
src/main/cpp/propertyconfigurator.cpp | 99 ++++++++++-----
src/main/include/log4cxx/helpers/charsetdecoder.h | 22 +++-
src/main/include/log4cxx/propertyconfigurator.h | 7 +-
src/test/cpp/asyncappendertestcase.cpp | 3 +-
src/test/cpp/customlogger/xloggertestcase.cpp | 3 +-
src/test/cpp/db/odbcappendertestcase.cpp | 3 +-
src/test/cpp/fmttest.cpp | 9 +-
src/test/cpp/helpers/messagebuffertest.cpp | 3 +-
src/test/cpp/hierarchythresholdtestcase.cpp | 24 ++--
src/test/cpp/l7dtestcase.cpp | 3 +-
src/test/cpp/locationdisabledtest.cpp | 3 +-
src/test/cpp/locationtest.cpp | 3 +-
src/test/cpp/ndctestcase.cpp | 3 +-
src/test/cpp/net/smtpappendertestcase.cpp | 6 +-
src/test/cpp/net/xmlsocketappendertestcase.cpp | 3 +-
src/test/cpp/patternlayouttest.cpp | 45 ++++---
src/test/cpp/propertyconfiguratortest.cpp | 9 +-
src/test/cpp/rolling/filterbasedrollingtest.cpp | 5 +-
src/test/cpp/varia/errorhandlertestcase.cpp | 6 +-
src/test/cpp/xml/customleveltestcase.cpp | 10 +-
src/test/cpp/xml/domtestcase.cpp | 51 ++++++--
src/test/resources/input/xml/DOMTestCase5_bad0.xml | 22 ++++
src/test/resources/input/xml/DOMTestCase5_bad1.xml | 33 +++++
src/test/resources/input/xml/DOMTestCase5_bad2.xml | 33 +++++
src/test/resources/input/xml/DOMTestCase5_bad3.xml | 22 ++++
src/test/resources/input/xml/DOMTestCase5_good.xml | 33 +++++
30 files changed, 449 insertions(+), 163 deletions(-)
diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml
index 526b6e41..85a304e6 100644
--- a/.github/workflows/sonarcloud.yml
+++ b/.github/workflows/sonarcloud.yml
@@ -55,7 +55,7 @@ jobs:
sudo apt-get install -y libapr1-dev libaprutil1-dev
- name: Install Build Wrapper
- uses: SonarSource/sonarqube-scan-action/[email protected]
+ uses: SonarSource/sonarqube-scan-action/[email protected]
env:
SONAR_HOST_URL: ${{ env.SONAR_SERVER_URL }}
@@ -84,7 +84,7 @@ jobs:
-o "$BaseDir/build/coverage.xml"
- name: SonarQube Scan
- uses: SonarSource/[email protected]
+ uses: SonarSource/[email protected]
env:
SONAR_TOKEN: ${{ secrets.SONARCLOUD_TOKEN }}
SONAR_HOST_URL: ${{ env.SONAR_SERVER_URL }}
diff --git a/src/main/cpp/charsetdecoder.cpp b/src/main/cpp/charsetdecoder.cpp
index b985f475..ed79d440 100644
--- a/src/main/cpp/charsetdecoder.cpp
+++ b/src/main/cpp/charsetdecoder.cpp
@@ -15,6 +15,7 @@
* limitations under the License.
*/
#define NOMINMAX /* tell windows not to define min/max macros */
+#include <log4cxx/private/string_c11.h>
#include <log4cxx/logstring.h>
#include <log4cxx/helpers/charsetdecoder.h>
#include <log4cxx/helpers/bytebuffer.h>
@@ -585,6 +586,12 @@ CharsetDecoderPtr CharsetDecoder::getDecoder(const
LogString& charset)
#endif
}
+log4cxx_status_t CharsetDecoder::decode(const char* in, size_t maxByteCount,
LogString& out)
+{
+ ByteBuffer buf((char*)in, strnlen_s(in, maxByteCount));
+ return decode(buf, out);
+}
+
diff --git a/src/main/cpp/defaultconfigurator.cpp
b/src/main/cpp/defaultconfigurator.cpp
index fe19df32..c34f3d64 100644
--- a/src/main/cpp/defaultconfigurator.cpp
+++ b/src/main/cpp/defaultconfigurator.cpp
@@ -214,7 +214,6 @@ DefaultConfigurator::configureFromFile(const
std::vector<LogString>& directories
std::get<0>(result) =
ConfigurationStatus::Configured;
return result;
}
- LogLog::warn(LOG4CXX_STR("Unable to load: ") +
candidate_str);
}
}
}
diff --git a/src/main/cpp/domconfigurator.cpp b/src/main/cpp/domconfigurator.cpp
index 6f78b3ac..7c940858 100644
--- a/src/main/cpp/domconfigurator.cpp
+++ b/src/main/cpp/domconfigurator.cpp
@@ -14,7 +14,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#include <log4cxx/private/string_c11.h>
#include <log4cxx/logstring.h>
#include <log4cxx/xml/domconfigurator.h>
#include <log4cxx/appender.h>
@@ -68,6 +67,7 @@ struct DOMConfigurator::DOMConfiguratorPrivate
helpers::Properties props = Configurator::properties();
spi::LoggerRepositoryPtr repository;
spi::LoggerFactoryPtr loggerFactory;
+ bool appenderAdded{ false };
};
namespace LOG4CXX_NS
@@ -190,9 +190,19 @@ AppenderPtr DOMConfigurator::findAppenderByReference(
apr_xml_doc* doc,
AppenderMap& appenders)
{
+ AppenderPtr appender;
LogString appenderName(subst(getAttribute(utf8Decoder, appenderRef,
REF_ATTR)));
+ if (appenderName.empty())
+ {
+ LogString msg(LOG4CXX_STR("["));
+ utf8Decoder->decode(appenderRef->name, MAX_ATTRIBUTE_NAME_LEN,
msg);
+ msg += LOG4CXX_STR("] attribute [");
+ utf8Decoder->decode(REF_ATTR, MAX_ATTRIBUTE_NAME_LEN, msg);
+ msg += LOG4CXX_STR("] not found");
+ LogLog::warn(msg);
+ return appender;
+ }
AppenderMap::const_iterator match = appenders.find(appenderName);
- AppenderPtr appender;
if (match != appenders.end())
{
@@ -311,27 +321,23 @@ AppenderPtr DOMConfigurator::parseAppender(Pool& p,
}
else if (tagName == APPENDER_REF_TAG)
{
- LogString refName =
subst(getAttribute(utf8Decoder, currentElement, REF_ATTR));
-
- if (!refName.empty() &&
appender->instanceof(AppenderAttachable::getStaticClass()))
+ if
(appender->instanceof(AppenderAttachable::getStaticClass()))
{
AppenderAttachablePtr aa =
LOG4CXX_NS::cast<AppenderAttachable>(appender);
- if (LogLog::isDebugEnabled())
+ if (auto delegateAppender =
findAppenderByReference(p, utf8Decoder, currentElement, doc, appenders))
{
-
LogLog::debug(LOG4CXX_STR("Attaching ") + Appender::getStaticClass().getName()
- + LOG4CXX_STR(" named
[") + refName + LOG4CXX_STR("] to ") + Appender::getStaticClass().getName()
- + LOG4CXX_STR(" named
[") + appender->getName() + LOG4CXX_STR("]"));
+ if (LogLog::isDebugEnabled())
+ {
+
LogLog::debug(LOG4CXX_STR("Attaching ") + Appender::getStaticClass().getName()
+ + LOG4CXX_STR("
named [") + delegateAppender->getName() + LOG4CXX_STR("] to ") +
Appender::getStaticClass().getName()
+ + LOG4CXX_STR("
named [") + appender->getName() + LOG4CXX_STR("]"));
+ }
+
aa->addAppender(delegateAppender);
}
-
aa->addAppender(findAppenderByReference(p, utf8Decoder, currentElement, doc,
appenders));
- }
- else if (refName.empty())
- {
- LogLog::error(LOG4CXX_STR("Can't add ")
+ Appender::getStaticClass().getName() + LOG4CXX_STR(" with empty ref
attribute"));
}
else
{
- LogLog::error(LOG4CXX_STR("Requesting
attachment of ") + Appender::getStaticClass().getName()
- + LOG4CXX_STR(" named [") +
refName + LOG4CXX_STR("] to ") + Appender::getStaticClass().getName()
+ LogLog::error(LOG4CXX_STR("Cannot
attach to ") + Appender::getStaticClass().getName()
+ LOG4CXX_STR(" named [") +
appender->getName() + LOG4CXX_STR("]")
+ LOG4CXX_STR(" which does not
implement ") + AppenderAttachable::getStaticClass().getName());
}
@@ -386,7 +392,8 @@ void DOMConfigurator::parseErrorHandler(Pool& p,
}
else if (tagName == APPENDER_REF_TAG)
{
-
eh->setBackupAppender(findAppenderByReference(p, utf8Decoder, currentElement,
doc, appenders));
+ if (auto appender = findAppenderByReference(p,
utf8Decoder, currentElement, doc, appenders))
+ eh->setBackupAppender(appender);
}
else if (tagName == LOGGER_REF)
{
@@ -461,7 +468,7 @@ void DOMConfigurator::parseLogger(
if (LogLog::isDebugEnabled())
{
- LogLog::debug(LOG4CXX_STR("Retreiving an instance of ") +
loggerName);
+ LogLog::debug(LOG4CXX_STR("Getting [") + loggerName +
LOG4CXX_STR("]"));
}
LoggerPtr logger = m_priv->repository->getLogger(loggerName,
m_priv->loggerFactory);
@@ -493,7 +500,12 @@ void DOMConfigurator::parseLoggerFactory(
if (className.empty())
{
- LogLog::error(LOG4CXX_STR("Logger Factory tag class attribute
not found."));
+ LogString msg(LOG4CXX_STR("["));
+ utf8Decoder->decode(factoryElement->name,
MAX_ATTRIBUTE_NAME_LEN, msg);
+ msg += LOG4CXX_STR("] attribute [");
+ utf8Decoder->decode(CLASS_ATTR, MAX_ATTRIBUTE_NAME_LEN, msg);
+ msg += LOG4CXX_STR("] not found");
+ LogLog::warn(msg);
}
else
{
@@ -558,25 +570,16 @@ void DOMConfigurator::parseChildrenOfLoggerElement(
if (tagName == APPENDER_REF_TAG)
{
- AppenderPtr appender = findAppenderByReference(p,
utf8Decoder, currentElement, doc, appenders);
- LogString refName = subst(getAttribute(utf8Decoder,
currentElement, REF_ATTR));
-
- if (appender)
+ if (auto appender = findAppenderByReference(p,
utf8Decoder, currentElement, doc, appenders))
{
if (LogLog::isDebugEnabled())
{
LogLog::debug(LOG4CXX_STR("Adding ") +
Appender::getStaticClass().getName()
- + LOG4CXX_STR(" named [") +
refName + LOG4CXX_STR("]")
+ + LOG4CXX_STR(" named [") +
appender->getName() + LOG4CXX_STR("]")
+ LOG4CXX_STR(" to logger [") +
logger->getName() + LOG4CXX_STR("]"));
}
newappenders.push_back(appender);
}
- else
- {
- LogLog::debug(LOG4CXX_STR("Appender named [") +
refName +
- LOG4CXX_STR("] not found."));
- }
-
}
else if (tagName == LEVEL_TAG)
{
@@ -594,8 +597,10 @@ void DOMConfigurator::parseChildrenOfLoggerElement(
if (newappenders.empty())
logger->removeAllAppenders();
else
+ {
logger->replaceAppenders(newappenders);
-
+ m_priv->appenderAdded = true;
+ }
propSetter.activate(p);
}
@@ -760,7 +765,7 @@ void DOMConfigurator::parseLevel(
LogString levelStr(subst(getAttribute(utf8Decoder, element,
VALUE_ATTR)));
if (LogLog::isDebugEnabled())
{
- LogLog::debug(LOG4CXX_STR("Level value for ") + loggerName +
LOG4CXX_STR(" is [") + levelStr + LOG4CXX_STR("]"));
+ LogLog::debug(LOG4CXX_STR("Setting [") + loggerName +
LOG4CXX_STR("] level to [") + levelStr + LOG4CXX_STR("]"));
}
if (StringHelper::equalsIgnoreCase(levelStr, LOG4CXX_STR("INHERITED"),
LOG4CXX_STR("inherited"))
@@ -815,7 +820,7 @@ void DOMConfigurator::parseLevel(
if (LogLog::isDebugEnabled())
{
- LogLog::debug(loggerName + LOG4CXX_STR(" level set to ") +
+ LogLog::debug(LOG4CXX_STR("[") + loggerName + LOG4CXX_STR("]
level is ") +
logger->getEffectiveLevel()->toString());
}
}
@@ -841,7 +846,6 @@ spi::ConfigurationStatus DOMConfigurator::doConfigure
)
{
m_priv->repository = repository ? repository :
LogManager::getLoggerRepository();
- m_priv->repository->setConfigured(true);
#if LOG4CXX_ABI_VERSION <= 15
m_priv->loggerFactory = std::make_shared<DefaultLoggerFactory>();
@@ -856,15 +860,9 @@ spi::ConfigurationStatus DOMConfigurator::doConfigure
if (rv != APR_SUCCESS)
{
- // There is not technically an exception thrown here, but this
behavior matches
- // what the PropertyConfigurator does
- IOException io(rv);
- LogString msg2(LOG4CXX_STR("Could not read configuration file
["));
- msg2.append(filename.getPath());
- msg2.append(LOG4CXX_STR("]. "));
- LOG4CXX_DECODE_CHAR(msg, io.what());
- msg2.append(msg);
- LogLog::error(msg2);
+ LogLog::error(LOG4CXX_STR("Could not open configuration file [")
+ + filename.getPath() + LOG4CXX_STR("]")
+ , IOException(rv));
return spi::ConfigurationStatus::NotConfigured;
}
else
@@ -874,32 +872,32 @@ spi::ConfigurationStatus DOMConfigurator::doConfigure
if (LogLog::isDebugEnabled())
{
- LogString debugMsg = LOG4CXX_STR("Loading configuration
file [")
- + filename.getPath() + LOG4CXX_STR("]");
- LogLog::debug(debugMsg);
+ LogLog::debug(LOG4CXX_STR("Loading configuration file
[")
+ + filename.getPath() +
LOG4CXX_STR("]"));
}
rv = apr_xml_parse_file(p.getAPRPool(), &parser, &doc, fd,
2000);
if (rv != APR_SUCCESS)
{
- char errbuf[2000];
- char errbufXML[2000];
- LogString msg2(LOG4CXX_STR("Error parsing file ["));
- msg2.append(filename.getPath());
- msg2.append(LOG4CXX_STR("], "));
- apr_strerror(rv, errbuf, sizeof(errbuf));
- LOG4CXX_DECODE_CHAR(lerrbuf, std::string(errbuf));
- msg2.append(lerrbuf);
-
+ LogString reason;
if (parser)
{
- apr_xml_parser_geterror(parser, errbufXML,
sizeof(errbufXML));
- LOG4CXX_DECODE_CHAR(lerrbufXML,
std::string(errbufXML));
- msg2.append(lerrbufXML);
+ char errbuf[2000];
+ apr_xml_parser_geterror(parser, errbuf,
sizeof(errbuf));
+ LOG4CXX_DECODE_CHAR(lsErrbuf,
std::string(errbuf));
+ reason.append(lsErrbuf);
}
-
- LogLog::error(msg2);
+ else
+ {
+ char errbuf[2000];
+ apr_strerror(rv, errbuf, sizeof(errbuf));
+ LOG4CXX_DECODE_CHAR(lsErrbuf,
std::string(errbuf));
+ reason.append(lsErrbuf);
+ }
+ LogLog::error(LOG4CXX_STR("Error parsing file [")
+ + filename.getPath() + LOG4CXX_STR("]")
+ , RuntimeException(reason));
return spi::ConfigurationStatus::NotConfigured;
}
else
@@ -910,6 +908,15 @@ spi::ConfigurationStatus DOMConfigurator::doConfigure
}
}
+ if (!m_priv->appenderAdded)
+ {
+ LogLog::warn(LOG4CXX_STR("[") + filename.getPath()
+ + LOG4CXX_STR("] did not add an ") +
Appender::getStaticClass().getName()
+ + LOG4CXX_STR(" to a logger"));
+ return spi::ConfigurationStatus::NotConfigured;
+ }
+
+ m_priv->repository->setConfigured(true);
return spi::ConfigurationStatus::Configured;
}
@@ -1042,7 +1049,12 @@ void DOMConfigurator::parse(
}
else
{
- LogLog::error(LOG4CXX_STR("DOM element is - not a
<configuration> element."));
+ LogString msg(LOG4CXX_STR("Root element ["));
+ utf8Decoder->decode(element->name,
MAX_ATTRIBUTE_NAME_LEN, msg);
+ msg += LOG4CXX_STR("] is not [");
+ utf8Decoder->decode(CONFIGURATION_TAG,
MAX_ATTRIBUTE_NAME_LEN, msg);
+ msg += LOG4CXX_STR("]");
+ LogLog::error(msg);
return;
}
}
@@ -1163,8 +1175,7 @@ LogString DOMConfigurator::getAttribute(
{
if (attrName == attr->name)
{
- ByteBuffer buf((char*) attr->value,
strnlen_s(attr->value, MAX_ATTRIBUTE_NAME_LEN));
- utf8Decoder->decode(buf, attrValue);
+ utf8Decoder->decode(attr->value,
MAX_ATTRIBUTE_NAME_LEN, attrValue);
}
}
diff --git a/src/main/cpp/propertyconfigurator.cpp
b/src/main/cpp/propertyconfigurator.cpp
index 6dd2036b..b1c1d939 100644
--- a/src/main/cpp/propertyconfigurator.cpp
+++ b/src/main/cpp/propertyconfigurator.cpp
@@ -86,19 +86,44 @@ class PropertyWatchdog : public FileWatchdog
IMPLEMENT_LOG4CXX_OBJECT(PropertyConfigurator)
+using RegistryType = std::map<LogString, AppenderPtr>;
+using RegistryPtr = std::unique_ptr<RegistryType>;
+
+#if 15 < LOG4CXX_ABI_VERSION
+struct PropertyConfigurator::PrivateData
+{
+
+ /**
+ Used internally to keep track of configured appenders.
+ */
+ RegistryPtr registry{ std::make_unique<RegistryType>() };
+
+ /**
+ Used to create new instances of logger
+ */
+ spi::LoggerFactoryPtr loggerFactory{ std::make_shared<LoggerFactory>()
};
+
+ /**
+ True if an appender was added to a logger
+ */
+ bool appenderAdded{ false };
+};
+PropertyConfigurator::PropertyConfigurator()
+ : m_priv{ std::make_unique<PrivateData>() }
+#else
+#define m_priv this
PropertyConfigurator::PropertyConfigurator()
: registry(new std::map<LogString, AppenderPtr>())
-#if LOG4CXX_ABI_VERSION <= 15
, loggerFactory(new DefaultLoggerFactory())
-#else
- , loggerFactory(new LoggerFactory())
#endif
{
}
PropertyConfigurator::~PropertyConfigurator()
{
+#if LOG4CXX_ABI_VERSION <= 15
delete registry;
+#endif
}
spi::ConfigurationStatus PropertyConfigurator::doConfigure
@@ -110,11 +135,13 @@ spi::ConfigurationStatus PropertyConfigurator::doConfigure
#endif
)
{
- auto hierarchy = repository ? repository :
LogManager::getLoggerRepository();
- hierarchy->setConfigured(true);
-
+ auto result = spi::ConfigurationStatus::NotConfigured;
+ if (LogLog::isDebugEnabled())
+ {
+ LogLog::debug(LOG4CXX_STR("Loading configuration file [")
+ + configFileName.getPath() + LOG4CXX_STR("]"));
+ }
Properties props = Configurator::properties();
-
try
{
InputStreamPtr inputStream = InputStreamPtr( new
FileInputStream(configFileName) );
@@ -122,29 +149,32 @@ spi::ConfigurationStatus PropertyConfigurator::doConfigure
}
catch (const IOException& ex)
{
- LOG4CXX_DECODE_CHAR(lsMsg, ex.what());
- LogLog::error(((LogString) LOG4CXX_STR("Could not read
configuration file ["))
- + configFileName.getPath() + LOG4CXX_STR("]: ") +
lsMsg);
- return spi::ConfigurationStatus::NotConfigured;
+ LogLog::error(LOG4CXX_STR("Could not load properties from [")
+ + configFileName.getPath() + LOG4CXX_STR("]"), ex);
+ return result;
}
try
{
- if (LogLog::isDebugEnabled())
+ result = doConfigure(props, repository ? repository :
LogManager::getLoggerRepository());
+#if LOG4CXX_ABI_VERSION <= 15
+ if (m_priv->registry->empty())
+#else
+ if (!m_priv->appenderAdded)
+#endif
{
- LogString debugMsg = LOG4CXX_STR("Loading configuration
file [")
- + configFileName.getPath() +
LOG4CXX_STR("]");
- LogLog::debug(debugMsg);
+ LogLog::warn(LOG4CXX_STR("[") + configFileName.getPath()
+ + LOG4CXX_STR("] did not add an ") +
Appender::getStaticClass().getName()
+ + LOG4CXX_STR(" to a logger"));
}
- return doConfigure(props, hierarchy);
}
catch (const std::exception& ex)
{
- LogLog::error(((LogString) LOG4CXX_STR("Could not parse
configuration file ["))
+ LogLog::error(LOG4CXX_STR("Exception thrown processing [")
+ configFileName.getPath() + LOG4CXX_STR("]: "), ex);
}
- return spi::ConfigurationStatus::NotConfigured;
+ return result;
}
spi::ConfigurationStatus PropertyConfigurator::configure(const File&
configFilename)
@@ -175,8 +205,6 @@ spi::ConfigurationStatus
PropertyConfigurator::configureAndWatch(
spi::ConfigurationStatus
PropertyConfigurator::doConfigure(helpers::Properties& properties,
spi::LoggerRepositoryPtr hierarchy)
{
- hierarchy->setConfigured(true);
-
LogString
debugValue(properties.getProperty(LOG4CXX_STR("log4j.debug")));
if (!debugValue.empty())
{
@@ -225,14 +253,18 @@ spi::ConfigurationStatus
PropertyConfigurator::doConfigure(helpers::Properties&
configureRootLogger(properties, hierarchy);
configureLoggerFactory(properties);
parseCatsAndRenderers(properties, hierarchy);
-
LogLog::debug(LOG4CXX_STR("Finished configuring."));
+#if LOG4CXX_ABI_VERSION <= 15
+ auto result = m_priv->registry->empty()
+#else
+ auto result = !m_priv->appenderAdded
+#endif
+ ? spi::ConfigurationStatus::NotConfigured
+ : spi::ConfigurationStatus::Configured;
- // We don't want to hold references to appenders preventing their
- // destruction.
- registry->clear();
-
- return spi::ConfigurationStatus::Configured;
+ if (spi::ConfigurationStatus::Configured == result)
+ hierarchy->setConfigured(true);
+ return result;
}
void PropertyConfigurator::configureLoggerFactory(helpers::Properties& props)
@@ -252,9 +284,9 @@ void
PropertyConfigurator::configureLoggerFactory(helpers::Properties& props)
#endif
);
- loggerFactory = LOG4CXX_NS::cast<LoggerFactory>( instance );
+ m_priv->loggerFactory = LOG4CXX_NS::cast<LoggerFactory>(
instance );
Pool p;
- PropertySetter::setProperties(loggerFactory, props,
LOG4CXX_STR("log4j.factory."), p);
+ PropertySetter::setProperties(m_priv->loggerFactory, props,
LOG4CXX_STR("log4j.factory."), p);
}
}
@@ -296,7 +328,7 @@ void
PropertyConfigurator::parseCatsAndRenderers(helpers::Properties& props,
).length();
auto loggerName = key.substr(prefixLength);
auto value = OptionConverter::findAndSubst(key, props);
- auto logger = hierarchy->getLogger(loggerName,
loggerFactory);
+ auto logger = hierarchy->getLogger(loggerName,
m_priv->loggerFactory);
auto additivity = parseAdditivityForLogger(props,
logger, loggerName);
parseLogger(props, logger, key, loggerName, value,
additivity);
@@ -406,7 +438,10 @@ void PropertyConfigurator::parseLogger(
newappenders.push_back(appender);
}
}
-
+#if 15 < LOG4CXX_ABI_VERSION
+ if (!newappenders.empty())
+ m_priv->appenderAdded = true;
+#endif
logger->reconfigure( newappenders, additivity );
}
@@ -545,10 +580,10 @@ AppenderPtr PropertyConfigurator::parseAppender(
void PropertyConfigurator::registryPut(const AppenderPtr& appender)
{
- (*registry)[appender->getName()] = appender;
+ (*m_priv->registry)[appender->getName()] = appender;
}
AppenderPtr PropertyConfigurator::registryGet(const LogString& name)
{
- return (*registry)[name];
+ return (*m_priv->registry)[name];
}
diff --git a/src/main/include/log4cxx/helpers/charsetdecoder.h
b/src/main/include/log4cxx/helpers/charsetdecoder.h
index 3c276ac8..d801e70b 100644
--- a/src/main/include/log4cxx/helpers/charsetdecoder.h
+++ b/src/main/include/log4cxx/helpers/charsetdecoder.h
@@ -77,14 +77,24 @@ class LOG4CXX_EXPORT CharsetDecoder : public Object
/**
- * Decodes as many bytes as possible from the given
- * input buffer, writing the results to the given output
string.
- * @param in input buffer.
- * @param out output string.
+ * Decodes as many bytes as possible from \c in,
+ * appending the result onto \c out.
+ * @param in a null terminated string.
+ * @param out the string onto which characters are appended.
* @return APR_SUCCESS if not encoding errors were found.
*/
- virtual log4cxx_status_t decode(ByteBuffer& in,
- LogString& out) = 0;
+ virtual log4cxx_status_t decode(ByteBuffer& in, LogString& out)
= 0;
+
+
+ /**
+ * Decodes up to \c maxByteCount bytes from \c in,
+ * appending the result onto \c out.
+ * @param in a null terminated string.
+ * @param maxByteCount the limit on the size of \c in.
+ * @param out the string onto which characters are appended.
+ * @return APR_SUCCESS if not encoding errors were found.
+ */
+ log4cxx_status_t decode(const char* in, size_t maxByteCount,
LogString& out);
/**
* Determins if status value indicates an invalid byte
sequence.
diff --git a/src/main/include/log4cxx/propertyconfigurator.h
b/src/main/include/log4cxx/propertyconfigurator.h
index b5e5872b..eac2aba4 100644
--- a/src/main/include/log4cxx/propertyconfigurator.h
+++ b/src/main/include/log4cxx/propertyconfigurator.h
@@ -249,6 +249,11 @@ class LOG4CXX_EXPORT PropertyConfigurator :
virtual public spi::Configurator,
virtual public helpers::Object
{
+#if 15 < LOG4CXX_ABI_VERSION
+ private:
+ struct PrivateData;
+ LOG4CXX_DECLARE_PRIVATE_MEMBER_PTR(PrivateData, m_priv)
+#else
protected:
/**
@@ -260,7 +265,7 @@ class LOG4CXX_EXPORT PropertyConfigurator :
Used to create new instances of logger
*/
LOG4CXX_DECLARE_PRIVATE_MEMBER(spi::LoggerFactoryPtr,
loggerFactory)
-
+#endif
public:
DECLARE_LOG4CXX_OBJECT(PropertyConfigurator)
BEGIN_LOG4CXX_CAST_MAP()
diff --git a/src/test/cpp/asyncappendertestcase.cpp
b/src/test/cpp/asyncappendertestcase.cpp
index ea6781fc..206efc1f 100644
--- a/src/test/cpp/asyncappendertestcase.cpp
+++ b/src/test/cpp/asyncappendertestcase.cpp
@@ -360,7 +360,8 @@ class AsyncAppenderTestCase : public
AppenderSkeletonTestCase
#if LOG4CXX_HAS_DOMCONFIGURATOR
void testConfiguration()
{
-
log4cxx::xml::DOMConfigurator::configure("input/xml/asyncAppender1.xml");
+ auto status =
xml::DOMConfigurator::configure("input/xml/asyncAppender1.xml");
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
AsyncAppenderPtr asyncAppender =
log4cxx::cast<AsyncAppender>(Logger::getRootLogger()->getAppender(LOG4CXX_STR("ASYNC")));
LOGUNIT_ASSERT(!(asyncAppender == 0));
LOGUNIT_ASSERT_EQUAL(100,
asyncAppender->getBufferSize());
diff --git a/src/test/cpp/customlogger/xloggertestcase.cpp
b/src/test/cpp/customlogger/xloggertestcase.cpp
index 74302e5c..7a4ef690 100644
--- a/src/test/cpp/customlogger/xloggertestcase.cpp
+++ b/src/test/cpp/customlogger/xloggertestcase.cpp
@@ -74,7 +74,8 @@ public:
std::string fn("input/xml/customLogger");
fn.append(number);
fn.append(".xml");
- DOMConfigurator::configure(fn);
+ auto status = DOMConfigurator::configure(fn);
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
int i = 0;
LOG4CXX_LOG(logger, log4cxx::XLevel::getTrace(), "Message " <<
i);
diff --git a/src/test/cpp/db/odbcappendertestcase.cpp
b/src/test/cpp/db/odbcappendertestcase.cpp
index ca568aed..2e7dec99 100644
--- a/src/test/cpp/db/odbcappendertestcase.cpp
+++ b/src/test/cpp/db/odbcappendertestcase.cpp
@@ -84,7 +84,8 @@ class ODBCAppenderTestCase : public AppenderSkeletonTestCase
//
void testConnectUsingDSN()
{
-
xml::DOMConfigurator::configure("input/xml/odbcAppenderDSN-Log4cxxTest.xml");
+ auto status =
xml::DOMConfigurator::configure("input/xml/odbcAppenderDSN-Log4cxxTest.xml");
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
auto odbc = Logger::getLogger("DB.UnitTest");
for (int i = 0; i < 100; ++i)
{
diff --git a/src/test/cpp/fmttest.cpp b/src/test/cpp/fmttest.cpp
index 3827f69c..c7674d70 100644
--- a/src/test/cpp/fmttest.cpp
+++ b/src/test/cpp/fmttest.cpp
@@ -85,21 +85,24 @@ public:
void test1()
{
-
PropertyConfigurator::configure(LOG4CXX_FILE("input/fmtLayout1.properties"));
+ auto status =
PropertyConfigurator::configure(LOG4CXX_FILE("input/fmtLayout1.properties"));
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
common();
LOGUNIT_ASSERT(Compare::compare(TEMP,
LOG4CXX_FILE("witness/patternLayout.1")));
}
void test1_expanded()
{
-
PropertyConfigurator::configure(LOG4CXX_FILE("input/fmtLayout1_expanded.properties"));
+ auto status =
PropertyConfigurator::configure(LOG4CXX_FILE("input/fmtLayout1_expanded.properties"));
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
common();
LOGUNIT_ASSERT(Compare::compare(TEMP,
LOG4CXX_FILE("witness/patternLayout.1")));
}
void test10()
{
-
PropertyConfigurator::configure(LOG4CXX_FILE("input/fmtLayout10.properties"));
+ auto status =
PropertyConfigurator::configure(LOG4CXX_FILE("input/fmtLayout10.properties"));
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
common();
ControlFilter filter1;
diff --git a/src/test/cpp/helpers/messagebuffertest.cpp
b/src/test/cpp/helpers/messagebuffertest.cpp
index f953ea30..e257528d 100644
--- a/src/test/cpp/helpers/messagebuffertest.cpp
+++ b/src/test/cpp/helpers/messagebuffertest.cpp
@@ -148,7 +148,8 @@ public:
root = Logger::getRootLogger();
logger =
Logger::getLogger(LOG4CXX_STR("java.org.apache.log4j.PatternLayoutTest"));
-
PropertyConfigurator::configure(LOG4CXX_FILE("input/messagebuffer1.properties"));
+ auto status =
PropertyConfigurator::configure(LOG4CXX_FILE("input/messagebuffer1.properties"));
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
int num = 220;
LOG4CXX_INFO(logger, "number in hex: " << std::hex << num);
diff --git a/src/test/cpp/hierarchythresholdtestcase.cpp
b/src/test/cpp/hierarchythresholdtestcase.cpp
index de836f09..65383cd8 100644
--- a/src/test/cpp/hierarchythresholdtestcase.cpp
+++ b/src/test/cpp/hierarchythresholdtestcase.cpp
@@ -59,56 +59,64 @@ public:
void test1()
{
-
PropertyConfigurator::configure(LOG4CXX_FILE("input/hierarchyThreshold1.properties"));
+ auto status =
PropertyConfigurator::configure(LOG4CXX_FILE("input/hierarchyThreshold1.properties"));
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
common();
LOGUNIT_ASSERT(Compare::compare(TEMP,
LOG4CXX_FILE("witness/hierarchyThreshold.1")));
}
void test2()
{
-
PropertyConfigurator::configure(LOG4CXX_FILE("input/hierarchyThreshold2.properties"));
+ auto status =
PropertyConfigurator::configure(LOG4CXX_FILE("input/hierarchyThreshold2.properties"));
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
common();
LOGUNIT_ASSERT(Compare::compare(TEMP,
LOG4CXX_FILE("witness/hierarchyThreshold.2")));
}
void test3()
{
-
PropertyConfigurator::configure(LOG4CXX_FILE("input/hierarchyThreshold3.properties"));
+ auto status =
PropertyConfigurator::configure(LOG4CXX_FILE("input/hierarchyThreshold3.properties"));
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
common();
LOGUNIT_ASSERT(Compare::compare(TEMP,
LOG4CXX_FILE("witness/hierarchyThreshold.3")));
}
void test4()
{
-
PropertyConfigurator::configure(LOG4CXX_FILE("input/hierarchyThreshold4.properties"));
+ auto status =
PropertyConfigurator::configure(LOG4CXX_FILE("input/hierarchyThreshold4.properties"));
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
common();
LOGUNIT_ASSERT(Compare::compare(TEMP,
LOG4CXX_FILE("witness/hierarchyThreshold.4")));
}
void test5()
{
-
PropertyConfigurator::configure(LOG4CXX_FILE("input/hierarchyThreshold5.properties"));
+ auto status =
PropertyConfigurator::configure(LOG4CXX_FILE("input/hierarchyThreshold5.properties"));
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
common();
LOGUNIT_ASSERT(Compare::compare(TEMP,
LOG4CXX_FILE("witness/hierarchyThreshold.5")));
}
void test6()
{
-
PropertyConfigurator::configure(LOG4CXX_FILE("input/hierarchyThreshold6.properties"));
+ auto status =
PropertyConfigurator::configure(LOG4CXX_FILE("input/hierarchyThreshold6.properties"));
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
common();
LOGUNIT_ASSERT(Compare::compare(TEMP,
LOG4CXX_FILE("witness/hierarchyThreshold.6")));
}
void test7()
{
-
PropertyConfigurator::configure(LOG4CXX_FILE("input/hierarchyThreshold7.properties"));
+ auto status =
PropertyConfigurator::configure(LOG4CXX_FILE("input/hierarchyThreshold7.properties"));
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
common();
LOGUNIT_ASSERT(Compare::compare(TEMP,
LOG4CXX_FILE("witness/hierarchyThreshold.7")));
}
void test8()
{
-
PropertyConfigurator::configure(LOG4CXX_FILE("input/hierarchyThreshold8.properties"));
+ auto status =
PropertyConfigurator::configure(LOG4CXX_FILE("input/hierarchyThreshold8.properties"));
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
common();
LOGUNIT_ASSERT(Compare::compare(TEMP,
LOG4CXX_FILE("witness/hierarchyThreshold.8")));
}
diff --git a/src/test/cpp/l7dtestcase.cpp b/src/test/cpp/l7dtestcase.cpp
index 7c70b74a..36b5eea8 100644
--- a/src/test/cpp/l7dtestcase.cpp
+++ b/src/test/cpp/l7dtestcase.cpp
@@ -77,7 +77,8 @@ public:
void test1()
{
-
PropertyConfigurator::configure(LOG4CXX_FILE("input/l7d1.properties"));
+ auto status =
PropertyConfigurator::configure(LOG4CXX_FILE("input/l7d1.properties"));
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
log4cxx::helpers::Pool pool;
diff --git a/src/test/cpp/locationdisabledtest.cpp
b/src/test/cpp/locationdisabledtest.cpp
index fa682f61..976e4d81 100644
--- a/src/test/cpp/locationdisabledtest.cpp
+++ b/src/test/cpp/locationdisabledtest.cpp
@@ -48,7 +48,8 @@ public:
void test1()
{
-
PropertyConfigurator::configure(LOG4CXX_FILE("input/locationdisabled.properties"));
+ auto status =
PropertyConfigurator::configure(LOG4CXX_FILE("input/locationdisabled.properties"));
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
common();
LOGUNIT_ASSERT(Compare::compare(LOG4CXX_STR("output/location-disabled-test"),
LOG4CXX_FILE("witness/location1-disabled")));
}
diff --git a/src/test/cpp/locationtest.cpp b/src/test/cpp/locationtest.cpp
index aa98a63d..701e1896 100644
--- a/src/test/cpp/locationtest.cpp
+++ b/src/test/cpp/locationtest.cpp
@@ -48,7 +48,8 @@ public:
void test1()
{
-
PropertyConfigurator::configure(LOG4CXX_FILE("input/location1.properties"));
+ auto status =
PropertyConfigurator::configure(LOG4CXX_FILE("input/location1.properties"));
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
common();
LOGUNIT_ASSERT(Compare::compare(LOG4CXX_STR("output/location-good-test"),
LOG4CXX_FILE("witness/location1-good")));
}
diff --git a/src/test/cpp/ndctestcase.cpp b/src/test/cpp/ndctestcase.cpp
index 75e55371..383f7a71 100644
--- a/src/test/cpp/ndctestcase.cpp
+++ b/src/test/cpp/ndctestcase.cpp
@@ -68,7 +68,8 @@ public:
void test1()
{
-
PropertyConfigurator::configure(File("input/ndc/NDC1.properties"));
+ auto status =
PropertyConfigurator::configure(File("input/ndc/NDC1.properties"));
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
common();
LOGUNIT_ASSERT(Compare::compare(TEMP,
File("witness/ndc/NDC.1")));
}
diff --git a/src/test/cpp/net/smtpappendertestcase.cpp
b/src/test/cpp/net/smtpappendertestcase.cpp
index 213cf4f3..d3036239 100644
--- a/src/test/cpp/net/smtpappendertestcase.cpp
+++ b/src/test/cpp/net/smtpappendertestcase.cpp
@@ -106,7 +106,8 @@ class SMTPAppenderTestCase : public AppenderSkeletonTestCase
*/
void testTrigger()
{
-
xml::DOMConfigurator::configure("input/xml/smtpAppender1.xml");
+ auto status =
xml::DOMConfigurator::configure("input/xml/smtpAppender1.xml");
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
auto appender =
log4cxx::cast<SMTPAppender>(Logger::getRootLogger()->getAppender(LOG4CXX_STR("A1")));
LOGUNIT_ASSERT(appender);
auto evaluator = appender->getEvaluator();
@@ -135,7 +136,8 @@ class SMTPAppenderTestCase : public AppenderSkeletonTestCase
void testValid()
{
-
xml::DOMConfigurator::configure("input/xml/smtpAppenderValid.xml");
+ auto status =
xml::DOMConfigurator::configure("input/xml/smtpAppenderValid.xml");
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
auto root = Logger::getRootLogger();
LOG4CXX_INFO(root, "Hello, World.\n\nThis paragraph
should be preceeded by a blank line.");
diff --git a/src/test/cpp/net/xmlsocketappendertestcase.cpp
b/src/test/cpp/net/xmlsocketappendertestcase.cpp
index cfd715b8..95b450e7 100644
--- a/src/test/cpp/net/xmlsocketappendertestcase.cpp
+++ b/src/test/cpp/net/xmlsocketappendertestcase.cpp
@@ -48,7 +48,8 @@ class XMLSocketAppenderTestCase : public
AppenderSkeletonTestCase
void test_fluent_bit()
{
-
xml::DOMConfigurator::configure("input/xml/fluent-bit.xml");
+ auto status =
xml::DOMConfigurator::configure("input/xml/fluent-bit.xml");
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
auto log = Logger::getRootLogger();
for (int i = 0; i < 100; ++i)
{
diff --git a/src/test/cpp/patternlayouttest.cpp
b/src/test/cpp/patternlayouttest.cpp
index a5723bbf..c142ae04 100644
--- a/src/test/cpp/patternlayouttest.cpp
+++ b/src/test/cpp/patternlayouttest.cpp
@@ -105,14 +105,16 @@ public:
void test1()
{
-
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout1.properties"));
+ auto status =
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout1.properties"));
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
common();
LOGUNIT_ASSERT(Compare::compare(TEMP,
LOG4CXX_FILE("witness/patternLayout.1")));
}
void test2()
{
-
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout2.properties"));
+ auto status =
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout2.properties"));
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
common();
ControlFilter filter1;
@@ -140,7 +142,8 @@ public:
void test3()
{
-
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout3.properties"));
+ auto status =
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout3.properties"));
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
common();
ControlFilter filter1;
@@ -170,7 +173,8 @@ public:
// 06 avr. 2002 18:30:58,937 [12345] DEBUG atternLayoutTest - Message 0
void test4()
{
-
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout4.properties"));
+ auto status =
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout4.properties"));
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
common();
ControlFilter filter1;
@@ -198,7 +202,8 @@ public:
void test5()
{
-
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout5.properties"));
+ auto status =
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout5.properties"));
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
common();
ControlFilter filter1;
@@ -226,7 +231,8 @@ public:
void test6()
{
-
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout6.properties"));
+ auto status =
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout6.properties"));
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
common();
ControlFilter filter1;
@@ -254,7 +260,8 @@ public:
void test7()
{
-
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout7.properties"));
+ auto status =
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout7.properties"));
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
common();
ControlFilter filter1;
@@ -282,7 +289,8 @@ public:
void test8()
{
-
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout8.properties"));
+ auto status =
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout8.properties"));
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
common();
@@ -313,7 +321,8 @@ public:
void test9()
{
-
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout9.properties"));
+ auto status =
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout9.properties"));
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
common();
ControlFilter filter1;
@@ -339,7 +348,8 @@ public:
void test10()
{
-
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout10.properties"));
+ auto status =
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout10.properties"));
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
common();
ControlFilter filter1;
@@ -371,7 +381,8 @@ public:
void test11()
{
-
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout11.properties"));
+ auto status =
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout11.properties"));
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
common();
ControlFilter filter1;
@@ -397,7 +408,8 @@ public:
void test12()
{
-
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout12.properties"));
+ auto status =
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout12.properties"));
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
common();
ControlFilter filter1;
@@ -427,21 +439,24 @@ public:
void test13()
{
-
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout13.properties"));
+ auto status =
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout13.properties"));
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
common();
LOGUNIT_ASSERT(Compare::compare(TEMP,
LOG4CXX_FILE("witness/patternLayout.13")));
}
void test14()
{
-
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout14.properties"));
+ auto status =
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout14.properties"));
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
common();
LOGUNIT_ASSERT(Compare::compare(TEMP,
LOG4CXX_FILE("witness/patternLayout.14")));
}
void testMDC1()
{
-
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout.mdc.1.properties"));
+ auto status =
PropertyConfigurator::configure(LOG4CXX_FILE("input/patternLayout.mdc.1.properties"));
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
MDC::put(LOG4CXX_TEST_STR("key1"), LOG4CXX_TEST_STR("va11"));
MDC::put(LOG4CXX_TEST_STR("key2"), LOG4CXX_TEST_STR("va12"));
logger->debug(LOG4CXX_TEST_STR("Hello World"));
diff --git a/src/test/cpp/propertyconfiguratortest.cpp
b/src/test/cpp/propertyconfiguratortest.cpp
index b051614e..2d57ee67 100644
--- a/src/test/cpp/propertyconfiguratortest.cpp
+++ b/src/test/cpp/propertyconfiguratortest.cpp
@@ -41,7 +41,8 @@ public:
props.put(LOG4CXX_STR("log4j.logger.org.apache.log4j.PropertyConfiguratorTest"),
LOG4CXX_STR("inherited,VECTOR2"));
props.put(LOG4CXX_STR("log4j.appender.VECTOR1"),
LOG4CXX_STR("org.apache.log4j.VectorAppender"));
props.put(LOG4CXX_STR("log4j.appender.VECTOR2"),
LOG4CXX_STR("org.apache.log4j.VectorAppender"));
- PropertyConfigurator::configure(props);
+ auto status = PropertyConfigurator::configure(props);
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
LoggerPtr logger =
Logger::getLogger("org.apache.log4j.PropertyConfiguratorTest");
LOGUNIT_ASSERT_EQUAL((int) Level::DEBUG_INT,
logger->getEffectiveLevel()->toInt());
@@ -58,7 +59,8 @@ public:
props.put(LOG4CXX_STR("log4j.logger.org.apache.log4j.PropertyConfiguratorTest"),
LOG4CXX_STR("NuLL,VECTOR2"));
props.put(LOG4CXX_STR("log4j.appender.VECTOR1"),
LOG4CXX_STR("org.apache.log4j.VectorAppender"));
props.put(LOG4CXX_STR("log4j.appender.VECTOR2"),
LOG4CXX_STR("org.apache.log4j.VectorAppender"));
- PropertyConfigurator::configure(props);
+ auto status = PropertyConfigurator::configure(props);
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
LoggerPtr logger =
Logger::getLogger("org.apache.log4j.PropertyConfiguratorTest");
LOGUNIT_ASSERT_EQUAL((int) Level::DEBUG_INT,
logger->getEffectiveLevel()->toInt());
@@ -74,7 +76,8 @@ public:
props.put(LOG4CXX_STR("log4j.rootLogger"),
LOG4CXX_STR("ALL,VECTOR1"));
props.put(LOG4CXX_STR("log4j.appender.VECTOR1"),
LOG4CXX_STR("org.apache.log4j.VectorAppender"));
props.put(LOG4CXX_STR("log4j.appender.VECTOR1.threshold"),
LOG4CXX_STR("WARN"));
- PropertyConfigurator::configure(props);
+ auto status = PropertyConfigurator::configure(props);
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
LoggerPtr root(Logger::getRootLogger());
VectorAppenderPtr appender =
log4cxx::cast<VectorAppender>(root->getAppender(LOG4CXX_STR("VECTOR1")));
LOGUNIT_ASSERT_EQUAL((int) Level::WARN_INT,
appender->getThreshold()->toInt());
diff --git a/src/test/cpp/rolling/filterbasedrollingtest.cpp
b/src/test/cpp/rolling/filterbasedrollingtest.cpp
index 43448125..bbff3fdc 100644
--- a/src/test/cpp/rolling/filterbasedrollingtest.cpp
+++ b/src/test/cpp/rolling/filterbasedrollingtest.cpp
@@ -60,9 +60,8 @@ public:
void test1()
{
#if LOG4CXX_HAS_DOMCONFIGURATOR
- log4cxx::xml::DOMConfigurator::configure(
- "./input/rolling/filter1.xml" /*,
LogManager::getLoggerRepository() */);
-
+ auto status =
xml::DOMConfigurator::configure("./input/rolling/filter1.xml");
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
common(LOG4CXX_STR("output/filterBased-test1"));
#endif
}
diff --git a/src/test/cpp/varia/errorhandlertestcase.cpp
b/src/test/cpp/varia/errorhandlertestcase.cpp
index 468ab4bf..5a479258 100644
--- a/src/test/cpp/varia/errorhandlertestcase.cpp
+++ b/src/test/cpp/varia/errorhandlertestcase.cpp
@@ -85,7 +85,8 @@ public:
void test1()
{
- DOMConfigurator::configure("input/xml/fallback1.xml");
+ auto status =
DOMConfigurator::configure("input/xml/fallback1.xml");
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
auto appender = root->getAppender(LOG4CXX_STR("PRIMARY"));
auto primary = log4cxx::cast<FileAppender>(appender);
auto errHandle = primary->getErrorHandler();
@@ -127,7 +128,8 @@ public:
void test2()
{
- DOMConfigurator::configure("input/xml/fallback2.xml");
+ auto status =
DOMConfigurator::configure("input/xml/fallback2.xml");
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
auto appender = root->getAppender(LOG4CXX_STR("PRIMARY"));
auto primary = log4cxx::cast<FileAppender>(appender);
auto errHandle = primary->getErrorHandler();
diff --git a/src/test/cpp/xml/customleveltestcase.cpp
b/src/test/cpp/xml/customleveltestcase.cpp
index d2259a56..b58c0081 100644
--- a/src/test/cpp/xml/customleveltestcase.cpp
+++ b/src/test/cpp/xml/customleveltestcase.cpp
@@ -69,7 +69,8 @@ public:
void test1()
{
-
DOMConfigurator::configure(LOG4CXX_TEST_STR("input/xml/customLevel1.xml"));
+ auto status =
DOMConfigurator::configure(LOG4CXX_TEST_STR("input/xml/customLevel1.xml"));
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
common();
const File witness("witness/customLevel.1");
LOGUNIT_ASSERT(Compare::compare(TEMP, witness));
@@ -77,7 +78,8 @@ public:
void test2()
{
-
DOMConfigurator::configure(LOG4CXX_TEST_STR("input/xml/customLevel2.xml"));
+ auto status =
DOMConfigurator::configure(LOG4CXX_TEST_STR("input/xml/customLevel2.xml"));
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
common();
const File witness("witness/customLevel.2");
LOGUNIT_ASSERT(Compare::compare(TEMP, witness));
@@ -86,6 +88,7 @@ public:
void test3()
{
DOMConfigurator::configure(LOG4CXX_TEST_STR("input/xml/customLevel3.xml"));
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
common();
const File witness("witness/customLevel.3");
LOGUNIT_ASSERT(Compare::compare(TEMP, witness));
@@ -93,7 +96,8 @@ public:
void test4()
{
-
DOMConfigurator::configure(LOG4CXX_TEST_STR("input/xml/customLevel4.xml"));
+ auto status =
DOMConfigurator::configure(LOG4CXX_TEST_STR("input/xml/customLevel4.xml"));
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
common();
const File witness("witness/customLevel.4");
LOGUNIT_ASSERT(Compare::compare(TEMP, witness));
diff --git a/src/test/cpp/xml/domtestcase.cpp b/src/test/cpp/xml/domtestcase.cpp
index 5f98b29e..b94ab641 100644
--- a/src/test/cpp/xml/domtestcase.cpp
+++ b/src/test/cpp/xml/domtestcase.cpp
@@ -17,6 +17,7 @@
#include <log4cxx/logger.h>
#include <log4cxx/xml/domconfigurator.h>
+#include <log4cxx/defaultconfigurator.h>
#include "../logunit.h"
#include "../util/compare.h"
#include "xlevel.h"
@@ -56,6 +57,7 @@ LOGUNIT_CLASS(DOMTestCase)
LOGUNIT_TEST(recursiveAppenderRef);
LOGUNIT_TEST(invalidAppender);
LOGUNIT_TEST(invalidLevel);
+ LOGUNIT_TEST(testAutoFallback);
LOGUNIT_TEST_SUITE_END();
LoggerPtr root;
@@ -73,6 +75,7 @@ LOGUNIT_CLASS(DOMTestCase)
public:
void setUp()
{
+ LogLog::setInternalDebugging(true);
root = Logger::getRootLogger();
logger =
Logger::getLogger(LOG4CXX_TEST_STR("org.apache.log4j.xml.DOMTestCase"));
}
@@ -89,8 +92,8 @@ public:
void test1()
{
- LogLog::setInternalDebugging(true);
-
DOMConfigurator::configure(LOG4CXX_TEST_STR("input/xml/DOMTestCase1.xml"));
+ auto status =
DOMConfigurator::configure(LOG4CXX_TEST_STR("input/xml/DOMTestCase1.xml"));
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
common();
ControlFilter cf1;
@@ -134,7 +137,8 @@ public:
//
void test2()
{
-
DOMConfigurator::configure(LOG4CXX_TEST_STR("input\\xml\\DOMTestCase2.xml"));
+ auto status =
DOMConfigurator::configure(LOG4CXX_TEST_STR("input\\xml\\DOMTestCase2.xml"));
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
common();
ThreadFilter threadFilter;
@@ -196,7 +200,8 @@ public:
*/
void test3()
{
-
DOMConfigurator::configure(LOG4CXX_TEST_STR("input/xml/DOMTestCase3.xml"));
+ auto status =
DOMConfigurator::configure(LOG4CXX_TEST_STR("input/xml/DOMTestCase3.xml"));
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
LOG4CXX_INFO(logger, "File name is expected to end with a
superscript 3");
#if LOG4CXX_LOGCHAR_IS_UTF8
const logchar fname[] = { 0x6F, 0x75, 0x74, 0x70, 0x75, 0x74,
0x2F, 0x64, 0x6F, 0x6D, static_cast<logchar>(0xC2), static_cast<logchar>(0xB3),
0 };
@@ -216,7 +221,8 @@ public:
*/
void test4()
{
-
DOMConfigurator::configure(LOG4CXX_TEST_STR("input/xml/DOMTestCase4.xml"));
+ auto status =
DOMConfigurator::configure(LOG4CXX_TEST_STR("input/xml/DOMTestCase4.xml"));
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
LOG4CXX_INFO(logger, "File name is expected to end with an
ideographic 4");
#if LOG4CXX_LOGCHAR_IS_UTF8
const logchar fname[] = { 0x6F, 0x75, 0x74, 0x70, 0x75, 0x74,
0x2F, 0x64, 0x6F, 0x6D, static_cast<logchar>(0xE3), static_cast<logchar>(0x86),
static_cast<logchar>(0x95), 0 };
@@ -234,22 +240,47 @@ public:
void recursiveAppenderRef()
{
// Load a bad XML file, make sure that we don't crash in
endless recursion
-
DOMConfigurator::configure(LOG4CXX_TEST_STR("input/xml/DOMConfiguratorRecursive.xml"));
- }
+ auto status =
DOMConfigurator::configure(LOG4CXX_TEST_STR("input/xml/DOMConfiguratorRecursive.xml"));
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::NotConfigured);
+ }
void invalidAppender()
{
// Load an XML file that attempts to use a levelmatchfilter as
an appender.
// We should not crash when loading this file.
-
DOMConfigurator::configure(LOG4CXX_TEST_STR("input/xml/DOMInvalidAppender.xml"));
- }
+ auto status =
DOMConfigurator::configure(LOG4CXX_TEST_STR("input/xml/DOMInvalidAppender.xml"));
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::NotConfigured);
+ }
void invalidLevel()
{
// Load an XML file that attempts to use a filter as a level.
// We should not crash when loading this file.
-
DOMConfigurator::configure(LOG4CXX_TEST_STR("input/xml/DOMInvalidLevel.xml"));
+ auto status =
DOMConfigurator::configure(LOG4CXX_TEST_STR("input/xml/DOMInvalidLevel.xml"));
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
}
+
+ void testAutoFallback()
+ {
+ std::vector<LogString> paths
+ { LOG4CXX_STR("input/xml")
+ };
+ std::vector<LogString> names
+ { LOG4CXX_STR("DOMTestCase5_bad0.xml")
+ , LOG4CXX_STR("DOMTestCase5_bad1.xml")
+ , LOG4CXX_STR("DOMTestCase5_bad2.xml")
+ , LOG4CXX_STR("DOMTestCase5_bad3.xml")
+ , LOG4CXX_STR("DOMTestCase5_good.xml")
+ };
+ LogString configFile;
+ spi::ConfigurationStatus status;
+ std::tie(status, configFile) =
DefaultConfigurator::configureFromFile(paths, names);
+ LOGUNIT_ASSERT_EQUAL(status,
spi::ConfigurationStatus::Configured);
+ LOGUNIT_ASSERT(configFile.npos !=
configFile.find(LOG4CXX_STR("DOMTestCase5_good.xml")));
+ // Prevent "DOMTestCase5_good.xml" use in subsequent default
configuration
+ DefaultConfigurator::setConfigurationFileName(LogString());
+ }
+
};
LOGUNIT_TEST_SUITE_REGISTRATION(DOMTestCase);
diff --git a/src/test/resources/input/xml/DOMTestCase5_bad0.xml
b/src/test/resources/input/xml/DOMTestCase5_bad0.xml
new file mode 100644
index 00000000..afd73782
--- /dev/null
+++ b/src/test/resources/input/xml/DOMTestCase5_bad0.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+<!--
+ 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.
+
+-->
+
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
+</log4j:configuration>
diff --git a/src/test/resources/input/xml/DOMTestCase5_bad1.xml
b/src/test/resources/input/xml/DOMTestCase5_bad1.xml
new file mode 100644
index 00000000..213a8824
--- /dev/null
+++ b/src/test/resources/input/xml/DOMTestCase5_bad1.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+<!--
+ 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.
+
+-->
+
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
+ <appender name="A1" class="org.apache.log4j.UnknownAppender">
+ <layout class="org.apache.log4j.PatternLayout">
+ <param name="ConversionPattern" value="%-5p %c{2} - %m%n"/>
+ </layout>
+ </appender>
+
+ <root>
+ <priority value ="debug" />
+ <appender-ref ref="A1" />
+ </root>
+
+</log4j:configuration>
diff --git a/src/test/resources/input/xml/DOMTestCase5_bad2.xml
b/src/test/resources/input/xml/DOMTestCase5_bad2.xml
new file mode 100644
index 00000000..bc26d9fc
--- /dev/null
+++ b/src/test/resources/input/xml/DOMTestCase5_bad2.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+<!--
+ 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.
+
+-->
+
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
+ <appender class="org.apache.log4j.FileAppender">
+ <layout class="org.apache.log4j.PatternLayout">
+ <param name="ConversionPattern" value="%-5p %c{2} - %m%n"/>
+ </layout>
+ </appender>
+
+ <root>
+ <priority value ="debug" />
+ <appender-ref ref="A1" />
+ </root>
+
+</log4j:configuration>
diff --git a/src/test/resources/input/xml/DOMTestCase5_bad3.xml
b/src/test/resources/input/xml/DOMTestCase5_bad3.xml
new file mode 100644
index 00000000..fe1696ab
--- /dev/null
+++ b/src/test/resources/input/xml/DOMTestCase5_bad3.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+<!--
+ 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.
+
+-->
+
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
+</log4j:confguration>
diff --git a/src/test/resources/input/xml/DOMTestCase5_good.xml
b/src/test/resources/input/xml/DOMTestCase5_good.xml
new file mode 100644
index 00000000..568df13e
--- /dev/null
+++ b/src/test/resources/input/xml/DOMTestCase5_good.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+<!--
+ 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.
+
+-->
+
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
+ <appender name="A1" class="org.apache.log4j.ConsoleAppender">
+ <layout class="org.apache.log4j.PatternLayout">
+ <param name="ConversionPattern" value="%Y%-5p %c{2} - %m%y%n"/>
+ </layout>
+ </appender>
+
+ <root>
+ <priority value ="debug" />
+ <appender-ref ref="A1" />
+ </root>
+
+</log4j:configuration>