You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by rm...@apache.org on 2022/12/02 23:33:44 UTC

[logging-log4cxx] branch better-ioexception created (now 5891fd83)

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

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


      at 5891fd83 Better internal logging as part of LOGCXX-524

This branch includes the following new commits:

     new 5891fd83 Better internal logging as part of LOGCXX-524

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: Better internal logging as part of LOGCXX-524

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

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

commit 5891fd833b140c9e6fe81c62ffabbb5aeb6c0481
Author: Robert Middleton <ro...@rm5248.com>
AuthorDate: Fri Dec 2 18:33:28 2022 -0500

    Better internal logging as part of LOGCXX-524
---
 src/main/cpp/defaultconfigurator.cpp  |  3 ++
 src/main/cpp/domconfigurator.cpp      | 13 +++++++--
 src/main/cpp/exception.cpp            |  5 ++++
 src/main/cpp/loglog.cpp               |  3 ++
 src/main/cpp/propertyconfigurator.cpp |  7 +++--
 src/main/cpp/rollingfileappender.cpp  | 16 ++++++++---
 src/site/markdown/usage.md            | 54 ++++++++++++++++++++++-------------
 7 files changed, 73 insertions(+), 28 deletions(-)

diff --git a/src/main/cpp/defaultconfigurator.cpp b/src/main/cpp/defaultconfigurator.cpp
index b7df7239..0fdd99e7 100644
--- a/src/main/cpp/defaultconfigurator.cpp
+++ b/src/main/cpp/defaultconfigurator.cpp
@@ -65,6 +65,9 @@ void DefaultConfigurator::configure(LoggerRepositoryPtr repository)
 		{
 			File candidate(names[i]);
 
+			LogString debugMsg = LOG4CXX_STR("Checking file ");
+			debugMsg.append(names[i]);
+			LogLog::debug(debugMsg);
 			if (candidate.exists(pool))
 			{
 				configuration = candidate;
diff --git a/src/main/cpp/domconfigurator.cpp b/src/main/cpp/domconfigurator.cpp
index 4786e842..68b154b2 100644
--- a/src/main/cpp/domconfigurator.cpp
+++ b/src/main/cpp/domconfigurator.cpp
@@ -796,15 +796,24 @@ void DOMConfigurator::doConfigure(const File& filename, spi::LoggerRepositoryPtr
 
 	if (rv != APR_SUCCESS)
 	{
-		LogString msg2(LOG4CXX_STR("Could not open file ["));
+		// 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("]."));
+		msg2.append(LOG4CXX_STR("]. "));
+		msg2.append(io.what());
 		LogLog::error(msg2);
 	}
 	else
 	{
 		apr_xml_parser* parser = NULL;
 		apr_xml_doc* doc = NULL;
+
+		LogString debugMsg = LOG4CXX_STR("Loading configuration file [")
+				+ filename.getPath() + LOG4CXX_STR("].");
+		LogLog::debug(debugMsg);
+
 		rv = apr_xml_parse_file(p.getAPRPool(), &parser, &doc, fd, 2000);
 
 		if (rv != APR_SUCCESS)
diff --git a/src/main/cpp/exception.cpp b/src/main/cpp/exception.cpp
index 759d074c..7eeaf005 100644
--- a/src/main/cpp/exception.cpp
+++ b/src/main/cpp/exception.cpp
@@ -22,6 +22,7 @@
 #include <log4cxx/helpers/stringhelper.h>
 #include <log4cxx/helpers/transcoder.h>
 #include <log4cxx/helpers/pool.h>
+#include <apr_errno.h>
 
 using namespace log4cxx;
 using namespace log4cxx::helpers;
@@ -170,9 +171,13 @@ IOException& IOException::operator=(const IOException& src)
 
 LogString IOException::formatMessage(log4cxx_status_t stat)
 {
+	char err_buff[32];
 	LogString s(LOG4CXX_STR("IO Exception : status code = "));
 	Pool p;
 	StringHelper::toString(stat, p, s);
+	s.append("(");
+	s.append(apr_strerror(stat, err_buff, sizeof(err_buff)));
+	s.append(")");
 	return s;
 }
 
diff --git a/src/main/cpp/loglog.cpp b/src/main/cpp/loglog.cpp
index ce37ec1d..55929fd8 100644
--- a/src/main/cpp/loglog.cpp
+++ b/src/main/cpp/loglog.cpp
@@ -25,6 +25,7 @@
 #include <log4cxx/private/log4cxx_private.h>
 #include <log4cxx/helpers/aprinitializer.h>
 #include <log4cxx/helpers/systemerrwriter.h>
+#include <log4cxx/helpers/optionconverter.h>
 #include <mutex>
 
 using namespace log4cxx;
@@ -47,6 +48,8 @@ struct LogLog::LogLogPrivate {
 LogLog::LogLog() :
 	m_priv(std::make_unique<LogLogPrivate>())
 {
+	LogString log4cxxDebug = OptionConverter::getSystemProperty(LOG4CXX_STR("LOG4CXX_DEBUG"), "false");
+	m_priv->debugEnabled = OptionConverter::toBoolean(log4cxxDebug, false);
 }
 
 LogLog::~LogLog(){}
diff --git a/src/main/cpp/propertyconfigurator.cpp b/src/main/cpp/propertyconfigurator.cpp
index c9dd0888..221674a6 100644
--- a/src/main/cpp/propertyconfigurator.cpp
+++ b/src/main/cpp/propertyconfigurator.cpp
@@ -101,15 +101,18 @@ void PropertyConfigurator::doConfigure(const File& configFileName,
 		InputStreamPtr inputStream = InputStreamPtr( new FileInputStream(configFileName) );
 		props.load(inputStream);
 	}
-	catch (const IOException&)
+	catch (const IOException& ex)
 	{
 		LogLog::error(((LogString) LOG4CXX_STR("Could not read configuration file ["))
-			+ configFileName.getPath() + LOG4CXX_STR("]."));
+			+ configFileName.getPath() + LOG4CXX_STR("].") + ": " + ex.what());
 		return;
 	}
 
 	try
 	{
+		LogString debugMsg = LOG4CXX_STR("Loading configuration file [")
+				+ configFileName.getPath() + LOG4CXX_STR("].");
+		LogLog::debug(debugMsg);
 		doConfigure(props, hierarchy);
 	}
 	catch (const std::exception& ex)
diff --git a/src/main/cpp/rollingfileappender.cpp b/src/main/cpp/rollingfileappender.cpp
index a6bc4e0e..fa543fcb 100644
--- a/src/main/cpp/rollingfileappender.cpp
+++ b/src/main/cpp/rollingfileappender.cpp
@@ -332,7 +332,9 @@ bool RollingFileAppender::rolloverInternal(Pool& p)
 								}
 								catch (std::exception& ex)
 								{
-									LogLog::warn(LOG4CXX_STR("Exception on rollover"));
+									LogString errorMsg = LOG4CXX_STR("Exception on rollover: ");
+									errorMsg.append(ex.what());
+									LogLog::error(errorMsg);
 									LogString exmsg;
 									log4cxx::helpers::Transcoder::decode(ex.what(), exmsg);
 									_priv->errorHandler->error(exmsg, ex, 0);
@@ -393,7 +395,9 @@ bool RollingFileAppender::rolloverInternal(Pool& p)
 								}
 								catch (std::exception& ex)
 								{
-									LogLog::warn(LOG4CXX_STR("Exception during rollover"));
+									LogString errorMsg = LOG4CXX_STR("Exception during rollover: ");
+									errorMsg.append(ex.what());
+									LogLog::warn(errorMsg);
 									LogString exmsg;
 									log4cxx::helpers::Transcoder::decode(ex.what(), exmsg);
 									_priv->errorHandler->error(exmsg, ex, 0);
@@ -429,7 +433,9 @@ bool RollingFileAppender::rolloverInternal(Pool& p)
 				}
 				catch (std::exception& ex)
 				{
-					LogLog::warn(LOG4CXX_STR("Exception during rollover"));
+					LogString errorMsg = LOG4CXX_STR("Exception during rollover: ");
+					errorMsg.append(ex.what());
+					LogLog::warn(errorMsg);
 					LogString exmsg;
 					log4cxx::helpers::Transcoder::decode(ex.what(), exmsg);
 					_priv->errorHandler->error(exmsg, ex, 0);
@@ -463,7 +469,9 @@ void RollingFileAppender::subAppend(const LoggingEventPtr& event, Pool& p)
 		}
 		catch (std::exception& ex)
 		{
-			LogLog::warn(LOG4CXX_STR("Exception during rollover attempt."));
+			LogString errorMsg = LOG4CXX_STR("Exception during rollover attempt: ");
+			errorMsg.append(ex.what());
+			LogLog::warn(errorMsg);
 			LogString exmsg;
 			log4cxx::helpers::Transcoder::decode(ex.what(), exmsg);
 			_priv->errorHandler->error(exmsg);
diff --git a/src/site/markdown/usage.md b/src/site/markdown/usage.md
index aefa0df1..a79b65d6 100644
--- a/src/site/markdown/usage.md
+++ b/src/site/markdown/usage.md
@@ -192,7 +192,7 @@ hierarchy. This rule is summarized below.
 A log request of level *p* in a logger with (either assigned or
 inherited, whichever is appropriate) level *q*, is enabled if *p \>= q*.
 
-This rule is at the heart of log4cxx. It assumes that levels are
+This rule is at the heart of Log4cxx. It assumes that levels are
 ordered. For the standard levels, we have *TRACE \< DEBUG \< INFO \<
 WARN \< ERROR \< FATAL*. 
 
@@ -240,11 +240,11 @@ For example, in
 Thus, it is possible to configure a logger and then to retrieve the same
 instance somewhere else in the code without passing around references.
 In fundamental contradiction to biological parenthood, where parents
-always preceed their children, log4cxx loggers can be created and
+always preceed their children, Log4cxx loggers can be created and
 configured in any order. In particular, a "parent" logger will find and
 link to its descendants even if it is instantiated after them. 
 
-Configuration of the log4cxx environment is typically done at
+Configuration of the Log4cxx environment is typically done at
 application initialization. The preferred way is by reading a
 configuration file. This approach will be discussed shortly. 
 
@@ -265,7 +265,7 @@ seems to be the best strategy known so far.
 
 The ability to selectively enable or disable logging requests based on
 their logger is only part of the picture. Log4cxx allows logging
-requests to print to multiple destinations. In log4cxx speak, an output
+requests to print to multiple destinations. In Log4cxx speak, an output
 destination is called an *appender*. Currently, appenders exist for the
 [console](@ref log4cxx.ConsoleAppender), [files](@ref log4cxx.FileAppender),
 GUI components, [remote socket](@ref log4cxx.net.SocketAppender)
@@ -327,7 +327,7 @@ an appender takes care of sending the formatted output to its
 destination. 
 
 The [PatternLayout](@ref log4cxx.PatternLayout),
-part of the standard log4cxx distribution, lets the user specify the
+part of the standard Log4cxx distribution, lets the user specify the
 output format according to conversion patterns similar to the C language
 *printf* function. 
 
@@ -353,13 +353,13 @@ applications will have thousands of logging statements embedded within
 their code. Given their number, it becomes imperative to manage these
 log statements without the need to modify them manually. 
 
-The log4cxx environment is fully configurable programmatically. However,
-it is far more flexible to configure log4cxx using configuration files.
+The Log4cxx environment is fully configurable programmatically. However,
+it is far more flexible to configure Log4cxx using configuration files.
 Currently, configuration files can be written in XML or in Java
 properties (key=value) format. 
 
 Let us give a taste of how this is done with the help of an imaginary
-application *MyApp* that uses log4cxx. 
+application *MyApp* that uses Log4cxx. 
 
 ~~~{.cpp}
     #include "com/foo/bar.h"
@@ -397,7 +397,7 @@ application *MyApp* that uses log4cxx.
     }
 ~~~
 
-*MyApp* begins by including log4cxx headers. It then defines a static
+*MyApp* begins by including Log4cxx headers. It then defines a static
 logger variable with the name *MyApp* which happens to be the fully
 qualified name of the class. 
 
@@ -435,7 +435,7 @@ qualified name of the class.
 
 The invocation of the
 [BasicConfigurator::configure](@ref log4cxx.BasicConfigurator.configure)
-method creates a rather simple log4cxx setup. This method is hardwired
+method creates a rather simple Log4cxx setup. This method is hardwired
 to add to the root logger a [ConsoleAppender](@ref log4cxx.ConsoleAppender).
 The output will be formatted using a
 [PatternLayout](@ref log4cxx.PatternLayout)
@@ -592,13 +592,13 @@ version of *example.log* is automatically moved to *example.log.1*.
 Note that to obtain these different logging behaviors we did not need to
 recompile code. We could just as easily have logged to a UNIX Syslog
 daemon, redirected all *com.foo* output to an NT Event logger, or
-forwarded logging events to a remote log4cxx server, which would log
+forwarded logging events to a remote Log4cxx server, which would log
 according to local server policy, for example by forwarding the log
-event to a second log4cxx server. 
+event to a second Log4cxx server. 
 
 # Default Initialization Procedure {#default-initialization-procedure}
 
-The log4cxx library does not make any assumptions about its environment.
+The Log4cxx library does not make any assumptions about its environment.
 In particular, when initially created the root [Logger](@ref log4cxx.Logger) has no appender.
 However the library will attempt automatic configuration.
 
@@ -615,6 +615,20 @@ To use automatic configuration with a non-standard file name
 create and use your own wrapper for [getLogger](@ref log4cxx.LogManager.getLogger).
 A full example can be seen in the src/examples/cpp/UserLib/logmanager.cpp file.
 
+# Internal Debugging {#internal-debugging}
+
+Because Log4cxx is a logging library, we can't use it to output errors from
+the library itself.  There are several ways to activate internal logging:
+
+1. Configure the library directly by calling the
+[LogLog::setInternalDebugging](@ref log4cxx.helpers.LogLog.setInternalDebugging)
+method
+2. If using a properties file, set the value `log4j.debug=true` in your configuration file
+3. If using an XML file, set the attribute `internalDebug=true` in the root node
+4. From the environment: `LOG4CXX_DEBUG=true`
+
+All error and warning messages are sent to stderr.
+
 # Nested Diagnostic Contexts {#nested-diagnostic-contexts}
 
 Most real-world systems have to deal with multiple clients
@@ -657,7 +671,7 @@ class is shown below.
 The NDC is managed per thread as a *stack* of contextual information.
 Note that all methods of the *log4cxx::NDC* class are static. Assuming
 that NDC printing is turned on, every time a log request is made, the
-appropriate log4cxx component will include the *entire* NDC stack for
+appropriate Log4cxx component will include the *entire* NDC stack for
 the current thread in the log output. This is done without the
 intervention of the user, who is responsible only for placing the
 correct information in the NDC by using the *push* and *pop* methods at
@@ -679,7 +693,7 @@ client's request.
 Nevertheless, some sophisticated applications, such as virtual hosting
 web servers, must log differently depending on the virtual host context
 and also depending on the software component issuing the request. Recent
-log4cxx releases support multiple hierarchy trees. This enhancement
+Log4cxx releases support multiple hierarchy trees. This enhancement
 allows each virtual host to possess its own copy of the logger
 hierarchy. 
 
@@ -760,7 +774,7 @@ The levels are set as follows:
 Note that this has no effect on other macros, such as using the
 `LOG4CXX_LOG`, `LOG4CXX_LOGLS`, or `LOG4CXX_L7DLOG` family of macros.
 
-# Removing location information {#removing-location information}
+# Removing location information {#removing-location-information}
 
 Whenever you log a message with Log4cxx, metadata about the location of the
 logging statement is captured as well through the preprocessor.  This includes
@@ -804,7 +818,7 @@ This will output data similar to the following:
 
 # Logging with {fmt} {#logging-with-fmt}
 
-One issue with utilizing log4cxx and its ostream style of logging is that log
+One issue with utilizing Log4cxx and its ostream style of logging is that log
 statements can be very awkward if you need to precisely format something:
 
 ~~~{.cpp}
@@ -826,7 +840,7 @@ code like the following:
 LOG4CXX_INFO_FMT( rootLogger, "Numbers can be formatted with a format string {:.1f} and as hex: {:x}", 22.456, 123 );
 ~~~
 
-Note that log4cxx does not include a copy of {fmt}, so you must include the
+Note that Log4cxx does not include a copy of {fmt}, so you must include the
 correct headers and linker flags in order to use the `LOG4CXX_[level]_FMT`
 family of macros.
 
@@ -863,9 +877,9 @@ logger hierarchy it is possible to control which log statements are
 output at arbitrary granularity. This helps reduce the volume of logged
 output and minimize the cost of logging. 
 
-One of the advantages of the log4cxx API is its manageability. Once the
+One of the advantages of the Log4cxx API is its manageability. Once the
 log statements have been inserted into the code, they can be controlled
 with configuration files. They can be selectively enabled or disabled,
 and sent to different and multiple output targets in user-chosen
-formats. The log4cxx package is designed so that log statements can
+formats. The Log4cxx package is designed so that log statements can
 remain in shipped code without incurring a heavy performance cost.