Author: nicko
Date: Fri Mar 17 12:26:53 2006
New Revision: 386707

URL: http://svn.apache.org/viewcvs?rev=386707&view=rev
Log:
Fix for LOG4NET-69.
Added new wrapped implementation of String.Format in Transform.StringFormat. 
This method will not throw exceptions. Added some more exception handling code 
to the Logger.

Modified:
    
logging/log4net/trunk/extensions/net/1.0/log4net.Ext.Trace/cs/src/TraceLogImpl.cs
    logging/log4net/trunk/log4net.build
    logging/log4net/trunk/src/Core/ILogger.cs
    logging/log4net/trunk/src/Core/LogImpl.cs
    logging/log4net/trunk/src/Repository/Hierarchy/Logger.cs
    logging/log4net/trunk/src/Util/Transform.cs

Modified: 
logging/log4net/trunk/extensions/net/1.0/log4net.Ext.Trace/cs/src/TraceLogImpl.cs
URL: 
http://svn.apache.org/viewcvs/logging/log4net/trunk/extensions/net/1.0/log4net.Ext.Trace/cs/src/TraceLogImpl.cs?rev=386707&r1=386706&r2=386707&view=diff
==============================================================================
--- 
logging/log4net/trunk/extensions/net/1.0/log4net.Ext.Trace/cs/src/TraceLogImpl.cs
 (original)
+++ 
logging/log4net/trunk/extensions/net/1.0/log4net.Ext.Trace/cs/src/TraceLogImpl.cs
 Fri Mar 17 12:26:53 2006
@@ -1,6 +1,6 @@
 #region Copyright & License
 //
-// Copyright 2001-2005 The Apache Software Foundation
+// Copyright 2001-2006 The Apache Software Foundation
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -17,8 +17,10 @@
 #endregion
 
 using System;
+using System.Globalization;
 
 using log4net.Core;
+using log4net.Util;
 
 namespace log4net.Ext.Trace
 {
@@ -68,7 +70,18 @@
 
                public void TraceFormat(string format, params object[] args)
                {
-                       Logger.Log(ThisDeclaringType, m_levelTrace, 
String.Format(format, args), null);
+                       if (IsTraceEnabled)
+                       {
+                               Logger.Log(ThisDeclaringType, m_levelTrace, 
Transform.StringFormat(CultureInfo.InvariantCulture, format, args), null);
+                       }
+               }
+
+               public void TraceFormat(IFormatProvider provider, string 
format, params object[] args)
+               {
+                       if (IsTraceEnabled)
+                       {
+                               Logger.Log(ThisDeclaringType, m_levelTrace, 
Transform.StringFormat(provider, format, args), null);
+                       }
                }
 
                public bool IsTraceEnabled

Modified: logging/log4net/trunk/log4net.build
URL: 
http://svn.apache.org/viewcvs/logging/log4net/trunk/log4net.build?rev=386707&r1=386706&r2=386707&view=diff
==============================================================================
--- logging/log4net/trunk/log4net.build (original)
+++ logging/log4net/trunk/log4net.build Fri Mar 17 12:26:53 2006
@@ -399,6 +399,10 @@
         </if>
         <if test="${not temp.build.skip}">
             <csc keyfile="${path::combine(log4net.basedir, 'log4net.snk')}" 
nostdlib="true" noconfig="true" warnaserror="true" target="library" 
debug="${current.build.debug}" define="${current.build.defines.csc}" 
output="${current.bin.dir}/log4net.dll" doc="${current.bin.dir}/log4net.xml">
+                <nowarn>
+                    <!-- warning CS1058: A previous catch clause already 
catches all exceptions. All non-exceptions thrown will be wrapped in a 
System.Runtime.CompilerServices.RuntimeWrappedException -->
+                    <warning number="1058" />
+                </nowarn>
                 <sources basedir="${log4net.basedir}/src">
                     <include name="**/*.cs" />
                 </sources>
@@ -437,6 +441,8 @@
                 <nowarn>
                     <!-- workaround for Mono bug #61902 -->
                     <warning number="0618" />
+                    <!-- warning CS1058: A previous catch clause already 
catches all exceptions. All non-exceptions thrown will be wrapped in a 
System.Runtime.CompilerServices.RuntimeWrappedException -->
+                    <warning number="1058" />
                 </nowarn>
                 <sources basedir="${log4net.basedir}/src">
                     <include name="**/*.cs" />
@@ -474,6 +480,8 @@
                 <nowarn>
                     <!-- workaround for Mono bug #61902 -->
                     <warning number="0618" />
+                    <!-- warning CS1058: A previous catch clause already 
catches all exceptions. All non-exceptions thrown will be wrapped in a 
System.Runtime.CompilerServices.RuntimeWrappedException -->
+                    <warning number="1058" />
                 </nowarn>
                 <sources basedir="${log4net.basedir}/src">
                     <include name="**/*.cs" />

Modified: logging/log4net/trunk/src/Core/ILogger.cs
URL: 
http://svn.apache.org/viewcvs/logging/log4net/trunk/src/Core/ILogger.cs?rev=386707&r1=386706&r2=386707&view=diff
==============================================================================
--- logging/log4net/trunk/src/Core/ILogger.cs (original)
+++ logging/log4net/trunk/src/Core/ILogger.cs Fri Mar 17 12:26:53 2006
@@ -1,6 +1,6 @@
 #region Copyright & License
 //
-// Copyright 2001-2005 The Apache Software Foundation
+// Copyright 2001-2006 The Apache Software Foundation
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -30,6 +30,11 @@
        /// <para>
        /// This interface supports logging events and testing if a level
        /// is enabled for logging.
+       /// </para>
+       /// <para>
+       /// These methods will not throw exceptions. Note to implementor, ensure
+       /// that the implementation of these methods cannot allow an exception
+       /// to be thrown to the caller.
        /// </para>
        /// </remarks>
        /// <author>Nicko Cadell</author>

Modified: logging/log4net/trunk/src/Core/LogImpl.cs
URL: 
http://svn.apache.org/viewcvs/logging/log4net/trunk/src/Core/LogImpl.cs?rev=386707&r1=386706&r2=386707&view=diff
==============================================================================
--- logging/log4net/trunk/src/Core/LogImpl.cs (original)
+++ logging/log4net/trunk/src/Core/LogImpl.cs Fri Mar 17 12:26:53 2006
@@ -1,6 +1,6 @@
 #region Copyright & License
 //
-// Copyright 2001-2005 The Apache Software Foundation
+// Copyright 2001-2006 The Apache Software Foundation
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@
 using System.Globalization;
 
 using log4net.Repository;
+using log4net.Util;
 
 namespace log4net.Core
 {
@@ -215,7 +216,7 @@
                {
                        if (IsDebugEnabled)
                        {
-                               Logger.Log(ThisDeclaringType, m_levelDebug, 
String.Format(CultureInfo.InvariantCulture, format, args), null);
+                               Logger.Log(ThisDeclaringType, m_levelDebug, 
Transform.StringFormat(CultureInfo.InvariantCulture, format, args), null);
                        }
                }
 
@@ -241,7 +242,7 @@
                {
                        if (IsDebugEnabled)
                        {
-                               Logger.Log(ThisDeclaringType, m_levelDebug, 
String.Format(provider, format, args), null);
+                               Logger.Log(ThisDeclaringType, m_levelDebug, 
Transform.StringFormat(provider, format, args), null);
                        }
                }
 
@@ -320,7 +321,7 @@
                {
                        if (IsInfoEnabled)
                        {
-                               Logger.Log(ThisDeclaringType, m_levelInfo, 
String.Format(CultureInfo.InvariantCulture, format, args), null);
+                               Logger.Log(ThisDeclaringType, m_levelInfo, 
Transform.StringFormat(CultureInfo.InvariantCulture, format, args), null);
                        }
                }
 
@@ -346,7 +347,7 @@
                {
                        if (IsInfoEnabled)
                        {
-                               Logger.Log(ThisDeclaringType, m_levelInfo, 
String.Format(provider, format, args), null);
+                               Logger.Log(ThisDeclaringType, m_levelInfo, 
Transform.StringFormat(provider, format, args), null);
                        }
                }
 
@@ -425,7 +426,7 @@
                {
                        if (IsWarnEnabled)
                        {
-                               Logger.Log(ThisDeclaringType, m_levelWarn, 
String.Format(CultureInfo.InvariantCulture, format, args), null);
+                               Logger.Log(ThisDeclaringType, m_levelWarn, 
Transform.StringFormat(CultureInfo.InvariantCulture, format, args), null);
                        }
                }
 
@@ -451,7 +452,7 @@
                {
                        if (IsWarnEnabled)
                        {
-                               Logger.Log(ThisDeclaringType, m_levelWarn, 
String.Format(provider, format, args), null);
+                               Logger.Log(ThisDeclaringType, m_levelWarn, 
Transform.StringFormat(provider, format, args), null);
                        }
                }
 
@@ -530,7 +531,7 @@
                {
                        if (IsErrorEnabled)
                        {
-                               Logger.Log(ThisDeclaringType, m_levelError, 
String.Format(CultureInfo.InvariantCulture, format, args), null);
+                               Logger.Log(ThisDeclaringType, m_levelError, 
Transform.StringFormat(CultureInfo.InvariantCulture, format, args), null);
                        }
                }
 
@@ -556,7 +557,7 @@
                {
                        if (IsErrorEnabled)
                        {
-                               Logger.Log(ThisDeclaringType, m_levelError, 
String.Format(provider, format, args), null);
+                               Logger.Log(ThisDeclaringType, m_levelError, 
Transform.StringFormat(provider, format, args), null);
                        }
                }
 
@@ -635,7 +636,7 @@
                {
                        if (IsFatalEnabled)
                        {
-                               Logger.Log(ThisDeclaringType, m_levelFatal, 
String.Format(CultureInfo.InvariantCulture, format, args), null);
+                               Logger.Log(ThisDeclaringType, m_levelFatal, 
Transform.StringFormat(CultureInfo.InvariantCulture, format, args), null);
                        }
                }
 
@@ -661,7 +662,7 @@
                {
                        if (IsFatalEnabled)
                        {
-                               Logger.Log(ThisDeclaringType, m_levelFatal, 
String.Format(provider, format, args), null);
+                               Logger.Log(ThisDeclaringType, m_levelFatal, 
Transform.StringFormat(provider, format, args), null);
                        }
                }
 

Modified: logging/log4net/trunk/src/Repository/Hierarchy/Logger.cs
URL: 
http://svn.apache.org/viewcvs/logging/log4net/trunk/src/Repository/Hierarchy/Logger.cs?rev=386707&r1=386706&r2=386707&view=diff
==============================================================================
--- logging/log4net/trunk/src/Repository/Hierarchy/Logger.cs (original)
+++ logging/log4net/trunk/src/Repository/Hierarchy/Logger.cs Fri Mar 17 
12:26:53 2006
@@ -1,6 +1,6 @@
 #region Copyright & License
 //
-// Copyright 2001-2005 The Apache Software Foundation
+// Copyright 2001-2006 The Apache Software Foundation
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -414,12 +414,26 @@
                /// Generate a logging event for the specified <paramref 
name="level"/> using
                /// the <paramref name="message"/> and <paramref 
name="exception"/>.
                /// </para>
+               /// <para>
+               /// This method must not throw any exception to the caller.
+               /// </para>
                /// </remarks>
                virtual public void Log(Type callerStackBoundaryDeclaringType, 
Level level, object message, Exception exception) 
                {
-                       if (IsEnabledFor(level))
+                       try
+                       {
+                               if (IsEnabledFor(level))
+                               {
+                                       
ForcedLog((callerStackBoundaryDeclaringType != null) ? 
callerStackBoundaryDeclaringType : ThisDeclaringType, level, message, 
exception);
+                               }
+                       }
+                       catch (Exception ex)
                        {
-                               ForcedLog((callerStackBoundaryDeclaringType != 
null) ? callerStackBoundaryDeclaringType : ThisDeclaringType , level, message, 
exception);
+                               log4net.Util.LogLog.Error("Log: Exception while 
logging", ex);
+                       }
+                       catch
+                       {
+                               log4net.Util.LogLog.Error("Log: Exception while 
logging");
                        }
                }
 
@@ -432,17 +446,29 @@
                /// <para>
                /// Logs the specified logging event through this logger.
                /// </para>
+               /// <para>
+               /// This method must not throw any exception to the caller.
+               /// </para>
                /// </remarks>
-               virtual public void Log(LoggingEvent logEvent) 
+               virtual public void Log(LoggingEvent logEvent)
                {
-                       if (logEvent == null)
+                       try
+                       {
+                               if (logEvent != null)
+                               {
+                                       if (IsEnabledFor(logEvent.Level))
+                                       {
+                                               ForcedLog(logEvent);
+                                       }
+                               }
+                       }
+                       catch (Exception ex)
                        {
-                               throw new ArgumentNullException("logEvent");
+                               log4net.Util.LogLog.Error("Log: Exception while 
logging", ex);
                        }
-
-                       if (IsEnabledFor(logEvent.Level))
+                       catch
                        {
-                               ForcedLog(logEvent);
+                               log4net.Util.LogLog.Error("Log: Exception while 
logging");
                        }
                }
 
@@ -457,14 +483,32 @@
                /// <para>
                /// Test if this logger is going to log events of the specified 
<paramref name="level"/>.
                /// </para>
+               /// <para>
+               /// This method must not throw any exception to the caller.
+               /// </para>
                /// </remarks>
-               virtual public bool IsEnabledFor(Level level) 
+               virtual public bool IsEnabledFor(Level level)
                {
-                       if (m_hierarchy.IsDisabled(level))
+                       try
+                       {
+                               if (level != null)
+                               {
+                                       if (m_hierarchy.IsDisabled(level))
+                                       {
+                                               return false;
+                                       }
+                                       return level >= this.EffectiveLevel;
+                               }
+                       }
+                       catch (Exception ex)
+                       {
+                               log4net.Util.LogLog.Error("Log: Exception while 
logging", ex);
+                       }
+                       catch
                        {
-                               return false;
+                               log4net.Util.LogLog.Error("Log: Exception while 
logging");
                        }
-                       return level >= this.EffectiveLevel;
+                       return false;
                }
 
                /// <summary>

Modified: logging/log4net/trunk/src/Util/Transform.cs
URL: 
http://svn.apache.org/viewcvs/logging/log4net/trunk/src/Util/Transform.cs?rev=386707&r1=386706&r2=386707&view=diff
==============================================================================
--- logging/log4net/trunk/src/Util/Transform.cs (original)
+++ logging/log4net/trunk/src/Util/Transform.cs Fri Mar 17 12:26:53 2006
@@ -1,6 +1,6 @@
 #region Copyright & License
 //
-// Copyright 2001-2005 The Apache Software Foundation
+// Copyright 2001-2006 The Apache Software Foundation
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -51,7 +51,7 @@
 
                #endregion Private Instance Constructors
 
-               #region Public Static Methods
+               #region XML String Methods
 
                /// <summary>
                /// Write a string to an <see cref="XmlWriter"/>
@@ -137,8 +137,158 @@
                        return INVALIDCHARS.Replace(textData, mask);
                }
 
-               #endregion Public Static Methods
+               #endregion XML String Methods
 
+               #region StringFormat
+
+               /// <summary>
+               /// Replaces the format item in a specified <see 
cref="System.String"/> with the text equivalent 
+               /// of the value of a corresponding <see cref="System.Object"/> 
instance in a specified array.
+               /// A specified parameter supplies culture-specific formatting 
information.
+               /// </summary>
+               /// <param name="provider">An <see 
cref="System.IFormatProvider"/> that supplies culture-specific formatting 
information.</param>
+               /// <param name="format">A <see cref="System.String"/> 
containing zero or more format items.</param>
+               /// <param name="args">An <see cref="System.Object"/> array 
containing zero or more objects to format.</param>
+               /// <returns>
+               /// A copy of format in which the format items have been 
replaced by the <see cref="System.String"/> 
+               /// equivalent of the corresponding instances of <see 
cref="System.Object"/> in args.
+               /// </returns>
+               /// <remarks>
+               /// <para>
+               /// This method does not throw exceptions. If an exception 
thrown while formatting the result the
+               /// exception and arguments are returned in the result string.
+               /// </para>
+               /// </remarks>
+               public static string StringFormat(IFormatProvider provider, 
string format, params object[] args)
+               {
+                       try
+                       {
+                               // The format is missing, log null value
+                               if (format == null)
+                               {
+                                       return null;
+                               }
+
+                               // The args are missing - should not happen 
unless we are called explicitly with a null array
+                               if (args == null)
+                               {
+                                       return format;
+                               }
+
+                               // Try to format the string
+                               return String.Format(provider, format, args);
+                       }
+                       catch(Exception ex)
+                       {
+                               log4net.Util.LogLog.Error("StringFormat: 
Exception while rendering format ["+format+"]", ex);
+                               return StringFormatError(ex, format, args);
+                       }
+                       catch
+                       {
+                               log4net.Util.LogLog.Error("StringFormat: 
Exception while rendering format ["+format+"]");
+                               return StringFormatError(null, format, args);
+                       }
+               }
+
+               /// <summary>
+               /// Process an error during StringFormat
+               /// </summary>
+               private static string StringFormatError(Exception 
formatException, string format, object[] args)
+               {
+                       try
+                       {
+                               StringBuilder buf = new 
StringBuilder("<log4net.Error>");
+
+                               if (formatException != null)
+                               {
+                                       buf.Append("Exception during 
StringFormat: ").Append(formatException.Message);
+                               }
+                               else
+                               {
+                                       buf.Append("Exception during 
StringFormat");
+                               }
+                               buf.Append(" 
<format>").Append(format).Append("</format>");
+                               buf.Append("<args>");
+                               RenderArray(args, buf);
+                               buf.Append("</args>");
+                               buf.Append("</log4net.Error>");
+
+                               return buf.ToString();
+                       }
+                       catch(Exception ex)
+                       {
+                               log4net.Util.LogLog.Error("StringFormat: 
INTERNAL ERROR during StringFormat error handling", ex);
+                               return "<log4net.Error>Exception during 
StringFormat. See Internal Log.</log4net.Error>";
+                       }
+                       catch
+                       {
+                               log4net.Util.LogLog.Error("StringFormat: 
INTERNAL ERROR during StringFormat error handling");
+                               return "<log4net.Error>Exception during 
StringFormat. See Internal Log.</log4net.Error>";
+                       }
+               }
+
+               /// <summary>
+               /// Dump the contents of an array into a string builder
+               /// </summary>
+               private static void RenderArray(Array array, StringBuilder 
buffer)
+               {
+                       if (array == null)
+                       {
+                               buffer.Append(SystemInfo.NullText);
+                       }
+                       else
+                       {
+                               if (array.Rank != 1)
+                               {
+                                       buffer.Append(array.ToString());
+                               }
+                               else
+                               {
+                                       buffer.Append("{");
+                                       int len = array.Length;
+
+                                       if (len > 0)
+                                       {
+                                               RenderObject(array.GetValue(0), 
buffer);
+                                               for (int i = 1; i < len; i++)
+                                               {
+                                                       buffer.Append(", ");
+                                                       
RenderObject(array.GetValue(i), buffer);
+                                               }
+                                       }
+                                       buffer.Append("}");
+                               }
+                       }
+               }
+
+               /// <summary>
+               /// Dump an object to a string
+               /// </summary>
+               private static void RenderObject(Object obj, StringBuilder 
buffer)
+               {
+                       if (obj == null)
+                       {
+                               buffer.Append(SystemInfo.NullText);
+                       }
+                       else
+                       {
+                               try
+                               {
+                                       buffer.Append(obj);
+                               }
+                               catch(Exception ex)
+                               {
+                                       buffer.Append("<Exception: 
").Append(ex.Message).Append(">");
+                               }
+                               catch
+                               {
+                                       buffer.Append("<Exception>");
+                               }
+                       }
+               }
+
+               #endregion StringFormat
+               
                #region Private Helper Methods
 
                /// <summary>


Reply via email to