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 2023/01/19 06:36:24 UTC

[logging-log4cxx] branch windows_server_issue created (now b47bec5a)

This is an automated email from the ASF dual-hosted git repository.

swebb2066 pushed a change to branch windows_server_issue
in repository https://gitbox.apache.org/repos/asf/logging-log4cxx.git


      at b47bec5a Allow use on Window Server 2016 (issue #180). Put more than the first character of thread name into the event log on Windows.

This branch includes the following new commits:

     new b47bec5a Allow use on Window Server 2016 (issue #180). Put more than the first character of thread name into the event log on Windows.

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[logging-log4cxx] 01/01: Allow use on Window Server 2016 (issue #180). Put more than the first character of thread name into the event log on Windows.

Posted by sw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

swebb2066 pushed a commit to branch windows_server_issue
in repository https://gitbox.apache.org/repos/asf/logging-log4cxx.git

commit b47bec5ac05b60af5042a20edee0a85c16875aef
Author: Stephen Webb <st...@sabreautonomous.com.au>
AuthorDate: Thu Jan 19 17:35:37 2023 +1100

    Allow use on Window Server 2016 (issue #180).
    Put more than the first character of thread name into the event log on
    Windows.
---
 src/main/cpp/loggingevent.cpp                      | 32 +++++++++++++++++-----
 src/main/cpp/threadutility.cpp                     | 25 +++++++++++++----
 src/main/include/CMakeLists.txt                    |  7 -----
 src/test/cpp/autoconfiguretestcase.cpp             | 27 ++++++++++++++++++
 .../resources/input/autoConfigureTest.properties   |  3 +-
 5 files changed, 73 insertions(+), 21 deletions(-)

diff --git a/src/main/cpp/loggingevent.cpp b/src/main/cpp/loggingevent.cpp
index daf89500..cc7f7479 100644
--- a/src/main/cpp/loggingevent.cpp
+++ b/src/main/cpp/loggingevent.cpp
@@ -374,13 +374,31 @@ const LogString& LoggingEvent::getCurrentThreadUserName()
 	}
 
 	log4cxx::helpers::Transcoder::decode(reinterpret_cast<const char*>(result), thread_name);
-#elif LOG4CXX_HAS_GETTHREADDESCRIPTION
-	PWSTR result;
-	HANDLE threadId = GetCurrentThread();
-	if( GetThreadDescription( threadId, &result ) == 0 ){
-		// Success
-		log4cxx::helpers::Transcoder::decode(reinterpret_cast<const char*>(result), thread_name);
-		LocalFree(result);
+#elif WIN32
+	typedef HRESULT (WINAPI *TGetThreadDescription)(HANDLE, PWSTR*);
+	static struct initialiser
+	{
+		HMODULE hKernelBase;
+		TGetThreadDescription GetThreadDescription;
+		initialiser()
+			: hKernelBase(GetModuleHandleA("KernelBase.dll"))
+			, GetThreadDescription(nullptr)
+		{
+			if (hKernelBase)
+				GetThreadDescription = reinterpret_cast<TGetThreadDescription>(GetProcAddress(hKernelBase, "GetThreadDescription"));
+		}
+	} win32func;
+	if (win32func.GetThreadDescription)
+	{
+		PWSTR result = 0;
+		HRESULT hr = win32func.GetThreadDescription(GetCurrentThread(), &result);
+		if (SUCCEEDED(hr))
+		{
+			std::wstring wresult = result;
+			LOG4CXX_DECODE_UNICHAR(decoded, wresult);
+			LocalFree(result);
+			thread_name = decoded;
+		}
 	}else{
 		thread_name = LOG4CXX_STR("(noname)");
 	}
diff --git a/src/main/cpp/threadutility.cpp b/src/main/cpp/threadutility.cpp
index 877b06ea..b579965e 100644
--- a/src/main/cpp/threadutility.cpp
+++ b/src/main/cpp/threadutility.cpp
@@ -139,13 +139,26 @@ void ThreadUtility::threadStartedNameThread(LogString threadName,
 	if (pthread_setname_np(static_cast<pthread_t>(nativeHandle), sthreadName.c_str()) < 0) {
 		LOGLOG_ERROR(LOG4CXX_STR("unable to set thread name"));
 	}
-#elif LOG4CXX_HAS_SETTHREADDESCRIPTION
-	LOG4CXX_ENCODE_WCHAR(wthreadName, threadName);
-	HRESULT hr = SetThreadDescription(static_cast<HANDLE>(nativeHandle), wthreadName.c_str());
-	if(FAILED(hr)){
-		LOGLOG_ERROR( LOG4CXX_STR("unable to set thread name") );
+#elif WIN32
+	typedef HRESULT (WINAPI *TSetThreadDescription)(HANDLE, PCWSTR);
+	static struct initialiser
+	{
+		HMODULE hKernelBase;
+		TSetThreadDescription SetThreadDescription;
+		initialiser()
+			: hKernelBase(GetModuleHandleA("KernelBase.dll"))
+			, SetThreadDescription(nullptr)
+		{
+			if (hKernelBase)
+				SetThreadDescription = reinterpret_cast<TSetThreadDescription>(GetProcAddress(hKernelBase, "SetThreadDescription"));
+		}
+	} win32Func;
+	if (win32Func.SetThreadDescription)
+	{
+		LOG4CXX_ENCODE_WCHAR(wthreadName, threadName);
+		if(FAILED(win32Func.SetThreadDescription(static_cast<HANDLE>(nativeHandle), wthreadName.c_str())))
+			LOGLOG_ERROR( LOG4CXX_STR("unable to set thread name") );
 	}
-
 #endif
 }
 
diff --git a/src/main/include/CMakeLists.txt b/src/main/include/CMakeLists.txt
index 59982cf3..62f61bd4 100644
--- a/src/main/include/CMakeLists.txt
+++ b/src/main/include/CMakeLists.txt
@@ -146,11 +146,6 @@ if(UNIX)
     endif()
 endif(UNIX)
 
-if(WIN32)
-    CHECK_SYMBOL_EXISTS(SetThreadDescription "windows.h;processthreadsapi.h" HAS_SETTHREADDESCRIPTION)
-    CHECK_SYMBOL_EXISTS(GetThreadDescription "windows.h;processthreadsapi.h" HAS_GETTHREADDESCRIPTION)
-endif(WIN32)
-
 foreach(varName
   HAS_THREAD_LOCAL
   HAS_STD_LOCALE
@@ -163,8 +158,6 @@ foreach(varName
   HAS_PTHREAD_SIGMASK
   HAS_PTHREAD_SETNAME
   HAS_PTHREAD_GETNAME
-  HAS_SETTHREADDESCRIPTION
-  HAS_GETTHREADDESCRIPTION
   )
   if(${varName} EQUAL 0)
     continue()
diff --git a/src/test/cpp/autoconfiguretestcase.cpp b/src/test/cpp/autoconfiguretestcase.cpp
index e486727e..73527e73 100644
--- a/src/test/cpp/autoconfiguretestcase.cpp
+++ b/src/test/cpp/autoconfiguretestcase.cpp
@@ -24,6 +24,7 @@
 #include <log4cxx/helpers/loglog.h>
 #include <log4cxx/helpers/pool.h>
 #include <log4cxx/helpers/stringhelper.h>
+#include <log4cxx/helpers/threadutility.h>
 #include <thread>
 #include <apr_file_io.h>
 #include <apr_file_info.h>
@@ -104,11 +105,37 @@ public:
 		LOGUNIT_ASSERT(rep->isConfigured());
 	}
 
+	// Base for a template that identifies whather std::thread::id has a native_handle member
+	template< class, class = void >
+	struct has_native_handle_member : std::false_type { };
+
+	template< class T >
+	struct has_native_handle_member<T,
+		std::void_t<decltype(std::declval<T&>().native_handle)>
+	> : std::true_type { };
+
+	template <typename V>
+	void setThreadName(const V& n, const LogString& name,
+		typename std::enable_if<!has_native_handle_member<V>::value, bool>::type* tag = 0)
+	{
+#ifdef WIN32
+		log4cxx::helpers::ThreadUtility::instance()->threadStartedNameThread(name, n, ::GetCurrentThread());
+#endif
+	}
+	template <typename V>
+	void setThreadName(const V& n, const LogString& name,
+		typename std::enable_if<has_native_handle_member<V>::value, bool>::type* tag = 0)
+	{
+		log4cxx::helpers::ThreadUtility::instance()->threadStartedNameThread(name, n, n.native_handle())
+	}
+
 	void test2()
 	{
+		setThreadName(std::this_thread::get_id(), LOG4CXX_STR("main"));
 		auto debugLogger = LogManager::getLogger(LOG4CXX_STR("AutoConfig.test2"));
 		LOGUNIT_ASSERT(debugLogger);
 		LOGUNIT_ASSERT(debugLogger->isDebugEnabled());
+		LOG4CXX_DEBUG(debugLogger, "Test message");
 	}
 
 	void test3()
diff --git a/src/test/resources/input/autoConfigureTest.properties b/src/test/resources/input/autoConfigureTest.properties
index 1187d130..604f878f 100644
--- a/src/test/resources/input/autoConfigureTest.properties
+++ b/src/test/resources/input/autoConfigureTest.properties
@@ -14,12 +14,13 @@
 # limitations under the License.
 #
 log4j.rootCategory=INFO, A1
+log4j.threadConfiguration=NameThreadOnly
 
 log4j.appender.A1=org.apache.log4j.FileAppender
 log4j.appender.A1.File=output/autoConfigureTest.log
 log4j.appender.A1.Append=false
 log4j.appender.A1.layout=org.apache.log4j.PatternLayout
-log4j.appender.A1.layout.ConversionPattern=%m%n
+log4j.appender.A1.layout.ConversionPattern=%T %m%n
 
 #log4j.logger.AutoConfig.test1=DEBUG
 log4j.logger.AutoConfig.test2=DEBUG