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 c1b4b97e Ensure a Qt fatal message is flushed when using 
buffered/async output (#571)
c1b4b97e is described below

commit c1b4b97e29365202b8be29bde6cc48efd820459e
Author: Stephen Webb <[email protected]>
AuthorDate: Fri Dec 26 11:22:17 2025 +1100

    Ensure a Qt fatal message is flushed when using buffered/async output (#571)
    
    * Use qt::messageHandler() in web-site examples
    
    * Improve the web-site properties file examples
    
    * Avoid double character conversion when LOG4CXX_CHAR=wchar_t
---
 src/examples/cpp/MyApp.properties      | 11 +++++-----
 src/examples/cpp/com/foo/config-qt.cpp | 23 +++++++++-----------
 src/main/cpp-qt/configuration.cpp      | 39 ++++++++++++++++++----------------
 src/main/cpp-qt/messagehandler.cpp     | 30 +++++++++++++++-----------
 src/site/markdown/example-programs.md  | 28 +++++++++++++++---------
 5 files changed, 73 insertions(+), 58 deletions(-)

diff --git a/src/examples/cpp/MyApp.properties 
b/src/examples/cpp/MyApp.properties
index da4840cd..dd8ab234 100644
--- a/src/examples/cpp/MyApp.properties
+++ b/src/examples/cpp/MyApp.properties
@@ -3,12 +3,12 @@ log4j.rootLogger=DEBUG, stdout, R
 
 log4j.appender.stdout=org.apache.log4j.ConsoleAppender
 log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
-
-# Pattern to output the caller's file name and line number.
-log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%f:%L) - %m%n
+# Color the logging level and message and prefix with the logging request file 
name, line number and thread.
+log4j.appender.stdout.layout.ConversionPattern=%f:%L [%t] - %Y%p %m%y%n
 
 log4j.appender.R=org.apache.log4j.RollingFileAppender
-log4j.appender.R.File=example.log
+# Store the log file in the same directory as the program
+log4j.appender.R.File=${PROGRAM_FILE_PATH.PARENT_PATH}/${PROGRAM_FILE_PATH.STEM}.log
 
 # Move example.log to example.log.1 at 100 KB in size
 log4j.appender.R.MaxFileSize=100KB
@@ -16,4 +16,5 @@ log4j.appender.R.MaxFileSize=100KB
 log4j.appender.R.MaxBackupIndex=1
 
 log4j.appender.R.layout=org.apache.log4j.PatternLayout
-log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n
+# Output the date, thread, logging level, logger name and message
+log4j.appender.R.layout.ConversionPattern=%d %t %-5p %c - %m%n
diff --git a/src/examples/cpp/com/foo/config-qt.cpp 
b/src/examples/cpp/com/foo/config-qt.cpp
index 4a1dfcc1..afa50149 100644
--- a/src/examples/cpp/com/foo/config-qt.cpp
+++ b/src/examples/cpp/com/foo/config-qt.cpp
@@ -18,23 +18,27 @@
 #include <log4cxx/basicconfigurator.h>
 #include <log4cxx/logmanager.h>
 #include <log4cxx-qt/configuration.h>
-#include <log4cxx/helpers/loglog.h>
+#include <log4cxx-qt/messagehandler.h>
 #include <QCoreApplication>
-#include <QVector>
 #include <QFileInfo>
 #include <QDir>
 
 namespace com { namespace foo {
 
+using namespace log4cxx;
+
 // Provide the name of the configuration file to Log4cxx.
 // Reload the configuration on a QFileSystemWatcher::fileChanged event.
 void ConfigureLogging() {
-       using namespace log4cxx;
-       static struct log4cxx_finalizer {
-               ~log4cxx_finalizer() {
+       static struct log4cxx_initializer {
+               log4cxx_initializer() {
+                       qInstallMessageHandler(qt::messageHandler);
+               }
+               ~log4cxx_initializer() {
                        LogManager::shutdown();
                }
-       } finaliser;
+       } initialiser;
+
        QFileInfo app{QCoreApplication::applicationFilePath()};
        QString basename{app.baseName()};
        QVector<QString> paths =
@@ -47,12 +51,7 @@ void ConfigureLogging() {
                , QString("MyApp.properties")
                , QString("log4cxx.xml")
                , QString("log4cxx.properties")
-               , QString("log4j.xml")
-               , QString("log4j.properties")
        };
-#if defined(_DEBUG)
-       helpers::LogLog::setInternalDebugging(true);
-#endif
        auto status       = spi::ConfigurationStatus::NotConfigured;
        auto selectedPath = QString();
        std::tie(status, selectedPath) = 
qt::Configuration::configureFromFileAndWatch(paths, names);
@@ -62,7 +61,6 @@ void ConfigureLogging() {
 
 // Retrieve the \c name logger pointer.
 auto getLogger(const QString& name) -> LoggerPtr {
-       using namespace log4cxx;
        return name.isEmpty()
                ? LogManager::getRootLogger()
                : LogManager::getLogger(name.toStdString());
@@ -70,7 +68,6 @@ auto getLogger(const QString& name) -> LoggerPtr {
 
 // Retrieve the \c name logger pointer.
 auto getLogger(const char* name) -> LoggerPtr {
-       using namespace log4cxx;
        return name
                ? LogManager::getLogger(name)
                : LogManager::getRootLogger();
diff --git a/src/main/cpp-qt/configuration.cpp 
b/src/main/cpp-qt/configuration.cpp
index 10f8de3d..29ab7fe9 100644
--- a/src/main/cpp-qt/configuration.cpp
+++ b/src/main/cpp-qt/configuration.cpp
@@ -30,7 +30,7 @@ namespace LOG4CXX_NS
 {
 namespace qt
 {
-using LOG4CXX_NS::helpers::LogLog;
+using helpers::LogLog;
 
 static std::unique_ptr<QFileSystemWatcher> watcher;
 static QString configFilename;
@@ -40,7 +40,8 @@ static void loadXMLFile(const QString& path){
        if(!fi.exists()){
                return;
        }
-       LOG4CXX_NS::xml::DOMConfigurator::configure(path.toStdString());
+       LOG4CXX_DECODE_QSTRING(lsPath, path);
+       xml::DOMConfigurator::configure(lsPath);
 }
 
 static void loadPropertiesFile(const QString& path){
@@ -48,7 +49,8 @@ static void loadPropertiesFile(const QString& path){
        if(!fi.exists()){
                return;
        }
-       LOG4CXX_NS::PropertyConfigurator::configure(path.toStdString());
+       LOG4CXX_DECODE_QSTRING(lsPath, path);
+       PropertyConfigurator::configure(lsPath);
 }
 
 static void dirChanged(const QString&){
@@ -68,18 +70,19 @@ static void dirChanged(const QString&){
 
 Configuration::Configuration(){}
 
-LOG4CXX_NS::spi::ConfigurationStatus Configuration::tryLoadFile(const QString& 
filename){
-       LOG4CXX_NS::spi::ConfigurationStatus stat 
=LOG4CXX_NS::spi::ConfigurationStatus::NotConfigured;
-       bool isXML = false;
+spi::ConfigurationStatus Configuration::tryLoadFile(const QString& filename){
+       auto stat = spi:: ConfigurationStatus::NotConfigured;
+       auto isXML = false;
 
+       LOG4CXX_DECODE_QSTRING(lsFilename, filename);
        if(filename.endsWith(".xml")){
-               stat = 
LOG4CXX_NS::xml::DOMConfigurator::configure(filename.toStdString());
+               stat = xml::DOMConfigurator::configure(lsFilename);
                isXML = true;
        }else if(filename.endsWith(".properties")){
-               stat = 
LOG4CXX_NS::PropertyConfigurator::configure(filename.toStdString());
+               stat = PropertyConfigurator::configure(lsFilename);
        }
 
-       if( stat == LOG4CXX_NS::spi::ConfigurationStatus::Configured ){
+       if( stat == spi::ConfigurationStatus::Configured ){
                watcher = std::make_unique<QFileSystemWatcher>();
                configFilename = filename;
                QFileInfo fi(filename);
@@ -100,35 +103,35 @@ LOG4CXX_NS::spi::ConfigurationStatus 
Configuration::tryLoadFile(const QString& f
        return stat;
 }
 
-std::tuple<LOG4CXX_NS::spi::ConfigurationStatus,QString>
+std::tuple<spi::ConfigurationStatus,QString>
 Configuration::configureFromFileAndWatch(const QVector<QString>& directories,
                                                                                
 const QVector<QString>& filenames){
        for( QString dir : directories ){
                for( QString fname : filenames ){
-                       QString canidate_str = dir + "/" + fname;
-                       QFile candidate(canidate_str);
+                       QString candidate_str = dir + "/" + fname;
+                       QFile candidate(candidate_str);
 
                        if (LogLog::isDebugEnabled())
                        {
-                               LOG4CXX_DECODE_QSTRING(msg, "Checking file " + 
canidate_str);
+                               LOG4CXX_DECODE_QSTRING(msg, "Checking file " + 
candidate_str);
                                LogLog::debug(msg);
                        }
                        if (candidate.exists())
                        {
-                               LOG4CXX_NS::spi::ConfigurationStatus 
configStatus = tryLoadFile(canidate_str);
-                               if( configStatus == 
LOG4CXX_NS::spi::ConfigurationStatus::Configured ){
-                                       return {configStatus, canidate_str};
+                               auto configStatus = tryLoadFile(candidate_str);
+                               if( configStatus == 
spi::ConfigurationStatus::Configured ){
+                                       return {configStatus, candidate_str};
                                }
                                if (LogLog::isDebugEnabled())
                                {
-                                       LOG4CXX_DECODE_QSTRING(failmsg, "Unable 
to load  " + canidate_str + ": trying next");
+                                       LOG4CXX_DECODE_QSTRING(failmsg, "Unable 
to load  " + candidate_str + ": trying next");
                                        LogLog::debug(failmsg);
                                }
                        }
                }
        }
 
-       return {LOG4CXX_NS::spi::ConfigurationStatus::NotConfigured, QString()};
+       return {spi::ConfigurationStatus::NotConfigured, QString()};
 }
 
 } //namespace helpers
diff --git a/src/main/cpp-qt/messagehandler.cpp 
b/src/main/cpp-qt/messagehandler.cpp
index 67580935..29fd8ebc 100644
--- a/src/main/cpp-qt/messagehandler.cpp
+++ b/src/main/cpp-qt/messagehandler.cpp
@@ -15,7 +15,9 @@
  * limitations under the License.
  */
 #include <log4cxx-qt/messagehandler.h>
+#include <log4cxx-qt/transcoder.h>
 #include <log4cxx/logger.h>
+#include <log4cxx/logmanager.h>
 #include <log4cxx/spi/location/locationinfo.h>
 
 namespace LOG4CXX_NS {
@@ -23,34 +25,38 @@ namespace qt {
 
 void messageHandler(QtMsgType type, const QMessageLogContext& context, const 
QString& message )
 {
-       LOG4CXX_NS::LoggerPtr qtLogger = LOG4CXX_NS::Logger::getLogger( 
context.category );
-       LOG4CXX_NS::spi::LocationInfo location( context.file,
-                                                                               
 LOG4CXX_NS::spi::LocationInfo::calcShortFileName(context.file),
-                                                                               
 context.function,
-                                                                               
 context.line );
-
+       spi::LocationInfo location
+               ( context.file
+               , spi::LocationInfo::calcShortFileName(context.file)
+               , context.function
+               , context.line
+               );
+       LOG4CXX_DECODE_QSTRING(lsMsg, message);
+       auto qtLogger = Logger::getLogger( context.category );
        switch ( type )
        {
                case QtMsgType::QtDebugMsg:
-                       qtLogger->debug( message.toStdString(), location );
+                       qtLogger->debug(lsMsg, location);
                        break;
 
                case QtMsgType::QtWarningMsg:
-                       qtLogger->warn( message.toStdString(), location );
+               default:
+                       qtLogger->warn(lsMsg, location);
                        break;
-#if QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)
 
+#if QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)
                case QtMsgType::QtInfoMsg:
-                       qtLogger->info( message.toStdString(), location );
+                       qtLogger->info(lsMsg, location);
                        break;
 #endif
 
                case QtMsgType::QtCriticalMsg:
-                       qtLogger->error( message.toStdString(), location );
+                       qtLogger->error(lsMsg, location);
                        break;
 
                case QtMsgType::QtFatalMsg:
-                       qtLogger->fatal( message.toStdString(), location );
+                       qtLogger->fatal(lsMsg, location);
+                       LogManager::shutdown();
                        std::abort();
        }
 }
diff --git a/src/site/markdown/example-programs.md 
b/src/site/markdown/example-programs.md
index 35ae215e..ea17b662 100644
--- a/src/site/markdown/example-programs.md
+++ b/src/site/markdown/example-programs.md
@@ -145,10 +145,10 @@ configuration file shows one possible way of achieving 
this.
     log4j.appender.A1=org.apache.log4j.ConsoleAppender
     log4j.appender.A1.layout=org.apache.log4j.PatternLayout
 
-    # Print the date in ISO 8601 format
+    # Include the date (in ISO 8601 format), the thread, logging level, logger 
name and message
     log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p %c - %m%n
 
-    # Print only messages of level WARN or above in the package com.foo.
+    # Output only messages of level WARN or above in the package com.foo.
     log4j.logger.com.foo=WARN
 ~~~
 
@@ -165,16 +165,16 @@ file. The log statement from the *Bar::doIt* method has 
the level *DEBUG*,
 lower than the logger level WARN. Consequently, *doIt()* method's log
 request is suppressed.
 
-Here is another configuration file that uses multiple appenders.
+Here is a *MyApp.properties* configuration file that uses multiple appenders.
 \include MyApp.properties
 
-Calling the enhanced MyApp with the this configuration file will output
+Using the enhanced \ref MyApp.properties configuration file will output
 the following on the console.
 
 ~~~
-     INFO [12345] (MyApp.cpp:8) - Entering application.
-    DEBUG [12345] (bar.cpp:8) - Did it again!
-     INFO [12345] (MyApp.cpp:11) - Exiting application.
+    MyApp2.cpp:8 [0x00012345] - INFO Entering application.
+    bar.cpp:8 [0x00012345] - DEBUG Did it again!
+    MyApp2.cpp:11 [0x00012345] - INFO Exiting application.
 ~~~
 
 In addition, as the root logger has been allocated a second appender,
@@ -197,10 +197,18 @@ This header file is for encapsulating Log4cxx 
configuration.
 \example com/foo/config1.cpp
 This file is a simplified example of encapsulated Log4cxx configuration.
 
-\example com/foo/config3.cpp
-This file is an example of how to use the current module name to select the 
Log4cxx configuration file.
+\example MyApp.properties
+This is a configuration file that uses multiple appenders.
+
+\example MyApp2.cpp
+This example can be built with \ref com/foo/config2.cpp or \ref 
com/foo/config4.cpp
+to configure Log4cxx on the first call the com::foo::getLogger.
+
+\example com/foo/config2.cpp
+This file is a simplified example of encapsulated Log4cxx configuration.
 
 \example com/foo/config4.cpp
-This file is a simpler example of how to use the current module name to select 
the Log4cxx configuration file.
+This file is a example of how provide application specific values for use in 
the configuration file
+and to use the current module name to select the Log4cxx configuration file.
 
 [Configuration Samples]:configuration-files.html#configuration-samples

Reply via email to