You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by sw...@apache.org on 2022/10/03 06:39:49 UTC
[logging-log4cxx] branch next_stable updated: Document DefaultConfigurator actual behaviour (#137)
This is an automated email from the ASF dual-hosted git repository.
swebb2066 pushed a commit to branch next_stable
in repository https://gitbox.apache.org/repos/asf/logging-log4cxx.git
The following commit(s) were added to refs/heads/next_stable by this push:
new 633b8575 Document DefaultConfigurator actual behaviour (#137)
633b8575 is described below
commit 633b8575165d158e00c38e8261bb5f3d1b312df6
Author: Stephen Webb <st...@ieee.org>
AuthorDate: Mon Oct 3 17:39:44 2022 +1100
Document DefaultConfigurator actual behaviour (#137)
* Allow program specification of DefaultConfigurator attributes (as a result, autoconfiguretestcase no longer needs special environment variables)
* Make '#ifdef _DEBUG' true in tests in a Debug build on a non-Windows platform
---
src/main/cpp/defaultconfigurator.cpp | 46 +++++++++++++----
src/main/include/log4cxx/defaultconfigurator.h | 40 ++++++++++-----
src/test/cpp/CMakeLists.txt | 26 +++++-----
src/test/cpp/autoconfiguretestcase.cpp | 71 +++++++++++++++++++++++---
4 files changed, 141 insertions(+), 42 deletions(-)
diff --git a/src/main/cpp/defaultconfigurator.cpp b/src/main/cpp/defaultconfigurator.cpp
index eb6c26a8..db01845d 100644
--- a/src/main/cpp/defaultconfigurator.cpp
+++ b/src/main/cpp/defaultconfigurator.cpp
@@ -28,16 +28,37 @@ using namespace log4cxx;
using namespace log4cxx::spi;
using namespace log4cxx::helpers;
+namespace
+{
+ LogString DefaultConfiguratorPath;
+ int DefaultConfiguratorWatchSeconds = 0;
+}
+
+void DefaultConfigurator::setConfigurationFileName(const LogString& path)
+{
+ DefaultConfiguratorPath = path;
+}
+
+
+void DefaultConfigurator::setConfigurationWatchSeconds(int seconds)
+{
+ DefaultConfiguratorWatchSeconds = seconds;
+}
+
+static const int MillisecondsPerSecond = 1000;
+
void DefaultConfigurator::configure(LoggerRepositoryPtr repository)
{
repository->setConfigured(true);
const LogString configuratorClassName(getConfiguratorClass());
- LogString configurationOptionStr(getConfigurationFileName());
+ LogString configurationFileName = DefaultConfiguratorPath;
+ if (configurationFileName.empty())
+ configurationFileName = getConfigurationFileName();
Pool pool;
File configuration;
- if (configurationOptionStr.empty())
+ if (configurationFileName.empty())
{
const char* names[] = { "log4cxx.xml", "log4cxx.properties", "log4j.xml", "log4j.properties", 0 };
@@ -54,7 +75,7 @@ void DefaultConfigurator::configure(LoggerRepositoryPtr repository)
}
else
{
- configuration.setPath(configurationOptionStr);
+ configuration.setPath(configurationFileName);
}
if (configuration.exists(pool))
@@ -69,18 +90,21 @@ void DefaultConfigurator::configure(LoggerRepositoryPtr repository)
configuration,
configuratorClassName,
repo,
- getConfigurationWatchDelay());
+ 0 < DefaultConfiguratorWatchSeconds
+ ? DefaultConfiguratorWatchSeconds * MillisecondsPerSecond
+ : getConfigurationWatchDelay()
+ );
}
else
{
- if (configurationOptionStr.empty())
+ if (configurationFileName.empty())
{
LogLog::debug(LOG4CXX_STR("Could not find default configuration file."));
}
else
{
LogString msg(LOG4CXX_STR("Could not find configuration file: ["));
- msg += configurationOptionStr;
+ msg += configurationFileName;
msg += LOG4CXX_STR("].");
LogLog::debug(msg);
}
@@ -106,12 +130,12 @@ const LogString DefaultConfigurator::getConfigurationFileName()
{
static const LogString LOG4CXX_DEFAULT_CONFIGURATION_KEY(LOG4CXX_STR("LOG4CXX_CONFIGURATION"));
static const LogString LOG4J_DEFAULT_CONFIGURATION_KEY(LOG4CXX_STR("log4j.configuration"));
- const LogString log4jConfigurationOptionStr(
+ const LogString log4jConfigurationFileName(
OptionConverter::getSystemProperty(LOG4J_DEFAULT_CONFIGURATION_KEY, LOG4CXX_STR("")));
- const LogString configurationOptionStr(
+ const LogString configurationFileName(
OptionConverter::getSystemProperty(LOG4CXX_DEFAULT_CONFIGURATION_KEY,
- log4jConfigurationOptionStr));
- return configurationOptionStr;
+ log4jConfigurationFileName));
+ return configurationFileName;
}
@@ -121,7 +145,7 @@ int DefaultConfigurator::getConfigurationWatchDelay()
LogString optionStr = OptionConverter::getSystemProperty(LOG4CXX_DEFAULT_CONFIGURATION_WATCH_KEY, LogString());
int milliseconds = 0;
if (!optionStr.empty())
- milliseconds = StringHelper::toInt(optionStr) * 1000;
+ milliseconds = StringHelper::toInt(optionStr) * MillisecondsPerSecond;
return milliseconds;
}
diff --git a/src/main/include/log4cxx/defaultconfigurator.h b/src/main/include/log4cxx/defaultconfigurator.h
index d5d3f554..9c296b62 100644
--- a/src/main/include/log4cxx/defaultconfigurator.h
+++ b/src/main/include/log4cxx/defaultconfigurator.h
@@ -19,14 +19,10 @@
#define _LOG4CXX_DEFAULT_CONFIGURATOR_H
#include <log4cxx/spi/configurator.h>
+#include <log4cxx/spi/loggerrepository.h>
namespace log4cxx
{
-namespace spi
-{
-class LoggerRepository;
-typedef std::shared_ptr<LoggerRepository> LoggerRepositoryPtr;
-}
/**
* Configures the repository from environmental settings and files.
@@ -39,19 +35,39 @@ class LOG4CXX_EXPORT DefaultConfigurator
public:
/**
- Add a ConsoleAppender that uses PatternLayout
- using the PatternLayout#TTCC_CONVERSION_PATTERN and
- prints to <code>stdout</code> to the root logger.*/
- static void configure(log4cxx::spi::LoggerRepositoryPtr repository);
+ Configure \c repository.
+
+ If the configuration file name has not been provided by a call to setConfigurationFileName(),
+ the environment variables 'LOG4CXX_CONFIGURATION' and 'log4j.configuration' are examined.
+
+ If the configuration file name has not been provided by any of the previous approaches
+ the current directory is examined for a file named either
+ "log4cxx.xml", "log4cxx.properties", "log4j.xml" or "log4j.properties".
+
+ If a positive number has been provided by a call to setConfigurationWatchSeconds()
+ or the environment variables 'LOG4CXX_CONFIGURATION_WATCH_SECONDS' contains a positive number
+ a background thread is started that will periodically check for a change to the configuration file
+ and apply any configuration changes found.
+ .*/
+ static void configure(spi::LoggerRepositoryPtr repository);
+
+ /**
+ Make \c path the configuration file used by configure().
+ */
+ static void setConfigurationFileName(const LogString& path);
+
+ /**
+ Make \c seconds the time a background thread will delay before checking
+ for a change to the configuration file used by configure().
+ */
+ static void setConfigurationWatchSeconds(int seconds);
private:
static const LogString getConfigurationFileName();
static const LogString getConfiguratorClass();
static int getConfigurationWatchDelay();
-
-
-}; // class DefaultConfigurator
+}; // class DefaultConfigurator
} // namespace log4cxx
#endif //_LOG4CXX_DEFAULT_CONFIGURATOR_H
diff --git a/src/test/cpp/CMakeLists.txt b/src/test/cpp/CMakeLists.txt
index 60e9f096..0189b583 100644
--- a/src/test/cpp/CMakeLists.txt
+++ b/src/test/cpp/CMakeLists.txt
@@ -105,11 +105,18 @@ if( WIN32 )
foreach( ENTRY ${PATH_FOR_TESTS}${NORMAL_PATH} )
set(ESCAPED_PATH "${ESCAPED_PATH}${ENTRY}\\\;")
endforeach()
-endif( WIN32 )
+elseif(CMAKE_BUILD_TYPE)
+ string(TOUPPER ${CMAKE_BUILD_TYPE} UPPER_BUILD_TYPE)
+ if (UPPER_BUILD_TYPE STREQUAL "DEBUG")
+ set(TEST_COMPILE_DEFINITIONS _DEBUG)
+ endif()
+else()
+ set(TEST_COMPILE_DEFINITIONS _DEBUG)
+endif()
get_filename_component(UNIT_TEST_WORKING_DIR ../resources ABSOLUTE)
foreach(testName IN LISTS ALL_LOG4CXX_TESTS)
- target_compile_definitions(${testName} PRIVATE ${LOG4CXX_COMPILE_DEFINITIONS} ${APR_COMPILE_DEFINITIONS} ${APR_UTIL_COMPILE_DEFINITIONS} )
+ target_compile_definitions(${testName} PRIVATE ${TEST_COMPILE_DEFINITIONS} ${LOG4CXX_COMPILE_DEFINITIONS} ${APR_COMPILE_DEFINITIONS} ${APR_UTIL_COMPILE_DEFINITIONS} )
target_include_directories(${testName} PRIVATE ${CMAKE_CURRENT_LIST_DIR} $<TARGET_PROPERTY:log4cxx,INCLUDE_DIRECTORIES>)
target_link_libraries(${testName} PRIVATE testingFramework testingUtilities log4cxx ${APR_LIBRARIES} ${APR_SYSTEM_LIBS} Threads::Threads)
add_test(NAME ${testName}
@@ -132,13 +139,6 @@ foreach(testName IN LISTS ALL_LOG4CXX_TESTS)
set_tests_properties(socketservertestcase PROPERTIES
ENVIRONMENT "SOCKET_SERVER_PARAMETER_FILE=${START_SOCKET_SERVER_PARAMETER_FILE};PATH=${ESCAPED_PATH}"
)
- elseif(${testName} STREQUAL autoconfiguretestcase)
- set_target_properties(${testName} PROPERTIES
- VS_DEBUGGER_ENVIRONMENT "LOG4CXX_CONFIGURATION=${UNIT_TEST_WORKING_DIR}/input/autoConfigureTest.properties\nPATH=${ESCAPED_PATH}"
- )
- set_tests_properties(autoconfiguretestcase PROPERTIES
- ENVIRONMENT "LOG4CXX_CONFIGURATION=${UNIT_TEST_WORKING_DIR}/input/autoConfigureTest.properties;LOG4CXX_CONFIGURATION_WATCH_SECONDS=1;PATH=${ESCAPED_PATH}"
- )
elseif(${testName} STREQUAL optionconvertertestcase)
set_target_properties(${testName} PROPERTIES
VS_DEBUGGER_ENVIRONMENT "TOTO=wonderful\nkey1=value1\nkey2=value2\nPATH=${ESCAPED_PATH}"
@@ -166,13 +166,13 @@ foreach(testName IN LISTS ALL_LOG4CXX_TESTS)
set_tests_properties(socketservertestcase PROPERTIES
ENVIRONMENT "SOCKET_SERVER_PARAMETER_FILE=${START_SOCKET_SERVER_PARAMETER_FILE}"
)
- elseif(${testName} STREQUAL autoconfiguretestcase)
- set_tests_properties(autoconfiguretestcase PROPERTIES
- ENVIRONMENT "LOG4CXX_CONFIGURATION=${UNIT_TEST_WORKING_DIR}/input/autoConfigureTest.properties"
+ elseif(${testName} STREQUAL optionconvertertestcase)
+ set_tests_properties(optionconvertertestcase PROPERTIES
+ ENVIRONMENT "TOTO=wonderful;key1=value1;key2=value2"
)
else()
set_tests_properties(${testName} PROPERTIES
- ENVIRONMENT "TOTO=wonderful;key1=value1;key2=value2"
+ ENVIRONMENT "key1=value1;key2=value2"
)
endif()
endif()
diff --git a/src/test/cpp/autoconfiguretestcase.cpp b/src/test/cpp/autoconfiguretestcase.cpp
index 99546660..629ef630 100644
--- a/src/test/cpp/autoconfiguretestcase.cpp
+++ b/src/test/cpp/autoconfiguretestcase.cpp
@@ -17,9 +17,17 @@
#include "logunit.h"
#include <log4cxx/logger.h>
#include <log4cxx/logmanager.h>
+#include <log4cxx/defaultconfigurator.h>
+#include <log4cxx/helpers/bytebuffer.h>
+#include <log4cxx/helpers/fileinputstream.h>
+#include <log4cxx/helpers/fileoutputstream.h>
#include <log4cxx/helpers/loglog.h>
-#include <log4cxx/file.h>
+#include <log4cxx/helpers/pool.h>
+#include <log4cxx/helpers/stringhelper.h>
#include <thread>
+#include <apr_file_io.h>
+#include <apr_file_info.h>
+#include "apr_time.h"
#define LOGUNIT_TEST_THREADS(testName, threadCount) \
class testName ## ThreadTestRegistration { \
@@ -45,9 +53,11 @@ using namespace log4cxx;
LOGUNIT_CLASS(AutoConfigureTestCase)
{
LOGUNIT_TEST_SUITE(AutoConfigureTestCase);
+ LOGUNIT_TEST(copyPropertyFile);
LOGUNIT_TEST_THREADS(test1, 4);
LOGUNIT_TEST(test2);
- LOGUNIT_TEST(stop);
+ LOGUNIT_TEST(test3);
+ LOGUNIT_TEST(shutdown);
LOGUNIT_TEST_SUITE_END();
#ifdef _DEBUG
struct Fixture
@@ -56,9 +66,35 @@ LOGUNIT_CLASS(AutoConfigureTestCase)
helpers::LogLog::setInternalDebugging(true);
}
} suiteFixture;
+ apr_time_t m_initTime = apr_time_now();
#endif
+ helpers::Pool m_pool;
+ char m_buf[2048];
+ LogString m_configFile = LOG4CXX_STR("autoConfigureTest.properties");
public:
- void test1()
+
+ void copyPropertyFile()
+ {
+ LOGUNIT_ASSERT(File(LOG4CXX_STR("input/autoConfigureTest.properties")).exists(m_pool));
+ LOGUNIT_ASSERT(apr_file_copy
+ ( "input/autoConfigureTest.properties"
+ , "autoConfigureTest.properties"
+ , APR_FPROT_UREAD | APR_FPROT_UWRITE
+ , m_pool.getAPRPool()
+ ) == APR_SUCCESS);
+
+ DefaultConfigurator::setConfigurationFileName(m_configFile);
+ DefaultConfigurator::setConfigurationWatchSeconds(1);
+ LOGUNIT_ASSERT(File(m_configFile).exists(m_pool));
+ }
+
+ void shutdown()
+ {
+ LogManager::shutdown();
+ LOGUNIT_ASSERT(apr_file_remove("autoConfigureTest.properties", m_pool.getAPRPool()) == APR_SUCCESS);
+ }
+
+ void test1()
{
auto debugLogger = LogManager::getLogger(LOG4CXX_STR("AutoConfig.test1"));
LOGUNIT_ASSERT(debugLogger);
@@ -70,14 +106,37 @@ public:
void test2()
{
- auto debugLogger = Logger::getLogger(LOG4CXX_STR("AutoConfig.test2"));
+ auto debugLogger = LogManager::getLogger(LOG4CXX_STR("AutoConfig.test2"));
LOGUNIT_ASSERT(debugLogger);
LOGUNIT_ASSERT(debugLogger->isDebugEnabled());
}
- void stop()
+ void test3()
{
- LogManager::shutdown();
+ // wait 2 sec to ensure the modification time is different to that held in the WatchDog
+ apr_sleep(2000000);
+ auto debugLogger = LogManager::getLogger(LOG4CXX_STR("AutoConfig.test3"));
+ LOGUNIT_ASSERT(debugLogger);
+ LOGUNIT_ASSERT(!debugLogger->isDebugEnabled());
+
+ // Append a configuration for test3 logger
+ helpers::ByteBuffer bbuf(m_buf, sizeof(m_buf));
+ int sz = 0;
+ for (const char* p = "\nlog4j.logger.AutoConfig.test3=DEBUG\n"; *p; ++p)
+ {
+ bbuf.put(*p);
+ ++sz;
+ }
+ bbuf.position(0);
+ bbuf.limit(sz);
+ helpers::FileOutputStream of(m_configFile, true);
+ of.write(bbuf, m_pool);
+ of.flush(m_pool);
+ of.close(m_pool);
+
+ // wait 1.5 sec for the change to be noticed
+ apr_sleep(1500000);
+ LOGUNIT_ASSERT(debugLogger->isDebugEnabled());
}
};