Commits

Dominik P committed 9a22b94

Implemented a first version of a patch for issue LOG4NET-341

  • Participants
  • Parent commits d9c8d2f

Comments (0)

Files changed (2)

+# HG changeset patch
+# User Dominik Psenner <dpsenner@gmail.com>
+# Parent ecf5fe65b288aa42c6cf3e8ee051f65f5b4440d6
+Fix location info to not contain a reference to StackFrame any more. LOG4NET-341
+
+diff -r ecf5fe65b288 src/Core/LocationInfo.cs
+--- a/src/Core/LocationInfo.cs	Mon Mar 05 19:38:11 2012 +0000
++++ b/src/Core/LocationInfo.cs	Fri May 25 21:48:29 2012 +0200
+@@ -116,12 +116,12 @@
+ 					if (frameIndex < st.FrameCount)
+ 					{
+ 						// take into account the frames we skip above
+-						int adjustedFrameCount = st.FrameCount - frameIndex;
+-                        ArrayList stackFramesList = new ArrayList(adjustedFrameCount);
+-						m_stackFrames = new StackFrame[adjustedFrameCount];
++						int adjustedFrameCount = st.FrameCount - frameIndex;
++						ArrayList stackFramesList = new ArrayList(adjustedFrameCount);
++						m_stackFrames = new StackFrameItem[adjustedFrameCount];
+ 						for (int i=frameIndex; i < st.FrameCount; i++) 
+ 						{
+-							stackFramesList.Add(st.GetFrame(i));
++							stackFramesList.Add(new StackFrameItem(st.GetFrame(i)));
+ 						}
+ 												
+ 						stackFramesList.CopyTo(m_stackFrames, 0);
+@@ -275,7 +275,7 @@
+ 		/// <summary>
+ 		/// Gets the stack frames from the stack trace of the caller making the log request
+ 		/// </summary>
+-		public StackFrame[] StackFrames
++		public StackFrameItem[] StackFrames
+ 		{
+ 			get { return m_stackFrames; }
+ 		}
+@@ -291,7 +291,7 @@
+ 		private readonly string m_methodName;
+ 		private readonly string m_fullInfo;
+ #if !NETCF
+-		private readonly StackFrame[] m_stackFrames;
++		private readonly StackFrameItem[] m_stackFrames;
+ #endif
+ 
+ 		#endregion Private Instance Fields
+diff -r ecf5fe65b288 src/Core/MethodItem.cs
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/src/Core/MethodItem.cs	Fri May 25 21:48:29 2012 +0200
+@@ -0,0 +1,162 @@
++#region Apache License
++//
++// Licensed to the Apache Software Foundation (ASF) under one or more 
++// contributor license agreements. See the NOTICE file distributed with
++// this work for additional information regarding copyright ownership. 
++// The ASF licenses this file to you under the Apache License, Version 2.0
++// (the "License"); you may not use this file except in compliance with 
++// the License. You may obtain a copy of the License at
++//
++// http://www.apache.org/licenses/LICENSE-2.0
++//
++// Unless required by applicable law or agreed to in writing, software
++// distributed under the License is distributed on an "AS IS" BASIS,
++// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++// See the License for the specific language governing permissions and
++// limitations under the License.
++//
++#endregion
++using System;
++using System.Collections.Generic;
++using System.Linq;
++using System.Text;
++using System.Collections;
++
++using log4net.Util;
++
++namespace log4net.Core
++{
++	/// <summary>
++	/// provides method information without actually referencing a System.Reflection.MethodBase
++	/// as that would require that the containing assembly is loaded.
++	/// </summary>
++	/// 
++#if !NETCF
++	[Serializable]
++#endif
++	public class MethodItem
++	{
++		#region Public Instance Constructors
++
++		public MethodItem()
++		{
++			m_name = NA;
++			m_parameters = new string[0];
++		}
++
++		public MethodItem(string name)
++			: this()
++		{
++			m_name = name;
++		}
++
++		public MethodItem(string name, string[] parameters)
++			: this(name)
++		{
++			m_parameters = parameters;
++		}
++
++        /// <summary>
++        /// constructs a method item from a method base. 
++        /// </summary>
++        /// <param name="frame"></param>
++        /// <returns></returns>
++		public MethodItem(System.Reflection.MethodBase methodBase)
++			: this(methodBase.Name, GetMethodParameterNames(methodBase))
++        {
++		}
++
++		#endregion
++
++		private static string[] GetMethodParameterNames(System.Reflection.MethodBase methodBase)
++		{
++			ArrayList methodParameterNames = new ArrayList();
++			try
++			{
++				System.Reflection.ParameterInfo[] methodBaseGetParameters = methodBase.GetParameters();
++
++				int methodBaseGetParametersCount = methodBaseGetParameters.GetUpperBound(0);
++
++				for (int i = 0; i <= methodBaseGetParametersCount; i++)
++				{
++					methodParameterNames.Add(methodBaseGetParameters[i].ParameterType + " " + methodBaseGetParameters[i].Name);
++				}
++			}
++			catch (Exception ex)
++			{
++				LogLog.Error(declaringType, "An exception ocurred while retreiving method parameters.", ex);
++			}
++
++			return (string[])methodParameterNames.ToArray(typeof(string));
++		}
++
++		#region Public Instance Properties
++
++		/// <summary>
++		/// Gets the method name of the caller making the logging 
++		/// request.
++		/// </summary>
++		/// <value>
++		/// The method name of the caller making the logging 
++		/// request.
++		/// </value>
++		/// <remarks>
++		/// <para>
++		/// Gets the method name of the caller making the logging 
++		/// request.
++		/// </para>
++		/// </remarks>
++		public string Name
++		{
++			get { return m_name; }
++		}
++
++		/// <summary>
++		/// Gets the method parameters of the caller making
++		/// the logging request.
++		/// </summary>
++		/// <value>
++		/// The method parameters of the caller making
++		/// the logging request
++		/// </value>
++		/// <remarks>
++		/// <para>
++		/// Gets the method parameters of the caller making
++		/// the logging request.
++		/// </para>
++		/// </remarks>
++		public string[] Parameters
++		{
++			get { return m_parameters; }
++		}
++
++		#endregion
++
++		#region Private Instance Fields
++
++		private readonly string m_name;
++		private readonly string[] m_parameters;
++
++		#endregion
++
++		#region Private Static Fields
++
++		/// <summary>
++		/// The fully qualified type of the StackFrameItem class.
++		/// </summary>
++		/// <remarks>
++		/// Used by the internal logger to record the Type of the
++		/// log message.
++		/// </remarks>
++		private readonly static Type declaringType = typeof(MethodItem);
++
++		/// <summary>
++		/// When location information is not available the constant
++		/// <c>NA</c> is returned. Current value of this string
++		/// constant is <b>?</b>.
++		/// </summary>
++		private const string NA = "?";
++
++		#endregion Private Static Fields
++	}
++}
+diff -r ecf5fe65b288 src/Core/StackFrameItem.cs
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/src/Core/StackFrameItem.cs	Fri May 25 21:48:29 2012 +0200
+@@ -0,0 +1,189 @@
++#region Apache License
++//
++// Licensed to the Apache Software Foundation (ASF) under one or more 
++// contributor license agreements. See the NOTICE file distributed with
++// this work for additional information regarding copyright ownership. 
++// The ASF licenses this file to you under the Apache License, Version 2.0
++// (the "License"); you may not use this file except in compliance with 
++// the License. You may obtain a copy of the License at
++//
++// http://www.apache.org/licenses/LICENSE-2.0
++//
++// Unless required by applicable law or agreed to in writing, software
++// distributed under the License is distributed on an "AS IS" BASIS,
++// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++// See the License for the specific language governing permissions and
++// limitations under the License.
++//
++#endregion
++using System;
++using System.Collections.Generic;
++using System.Linq;
++using System.Text;
++using System.Diagnostics;
++using System.Reflection;
++
++namespace log4net.Core
++{
++    /// <summary>
++    /// provides stack frame information without actually referencing a System.Diagnostics.StackFrame
++    /// as that would require that the containing assembly is loaded.
++    /// </summary>
++    /// 
++#if !NETCF
++    [Serializable]
++#endif
++    public class StackFrameItem
++    {
++        #region Public Instance Constructors
++
++        /// <summary>
++        /// returns a stack frame item from a stack frame. This 
++        /// </summary>
++        /// <param name="frame"></param>
++        /// <returns></returns>
++        public StackFrameItem(StackFrame frame)
++        {
++            // set default values
++            m_lineNumber = NA;
++            m_fileName = NA;
++            m_method = new MethodItem();
++            m_className = NA;
++
++            // get frame values
++            m_lineNumber = frame.GetFileLineNumber().ToString(System.Globalization.NumberFormatInfo.InvariantInfo);
++            m_fileName = frame.GetFileName();
++            // get method values
++            MethodBase method = frame.GetMethod();
++            if (method != null)
++            {
++				m_className = method.DeclaringType.FullName;
++				m_method = new MethodItem(method);
++            }
++
++            // set full info
++            m_fullInfo = m_className + '.' + m_method.Name + '(' + m_fileName + ':' + m_lineNumber + ')';
++        }
++
++        #endregion
++
++        #region Public Instance Properties
++
++        /// <summary>
++        /// Gets the fully qualified class name of the caller making the logging 
++        /// request.
++        /// </summary>
++        /// <value>
++        /// The fully qualified class name of the caller making the logging 
++        /// request.
++        /// </value>
++        /// <remarks>
++        /// <para>
++        /// Gets the fully qualified class name of the caller making the logging 
++        /// request.
++        /// </para>
++        /// </remarks>
++        public string ClassName
++        {
++            get { return m_className; }
++        }
++
++        /// <summary>
++        /// Gets the file name of the caller.
++        /// </summary>
++        /// <value>
++        /// The file name of the caller.
++        /// </value>
++        /// <remarks>
++        /// <para>
++        /// Gets the file name of the caller.
++        /// </para>
++        /// </remarks>
++        public string FileName
++        {
++            get { return m_fileName; }
++        }
++
++        /// <summary>
++        /// Gets the line number of the caller.
++        /// </summary>
++        /// <value>
++        /// The line number of the caller.
++        /// </value>
++        /// <remarks>
++        /// <para>
++        /// Gets the line number of the caller.
++        /// </para>
++        /// </remarks>
++        public string LineNumber
++        {
++            get { return m_lineNumber; }
++        }
++
++        /// <summary>
++        /// Gets the method name of the caller.
++        /// </summary>
++        /// <value>
++        /// The method name of the caller.
++        /// </value>
++        /// <remarks>
++        /// <para>
++        /// Gets the method name of the caller.
++        /// </para>
++        /// </remarks>
++        public MethodItem Method
++        {
++            get { return m_method; }
++        }
++
++        /// <summary>
++        /// Gets all available caller information
++        /// </summary>
++        /// <value>
++        /// All available caller information, in the format
++        /// <c>fully.qualified.classname.of.caller.methodName(Filename:line)</c>
++        /// </value>
++        /// <remarks>
++        /// <para>
++        /// Gets all available caller information, in the format
++        /// <c>fully.qualified.classname.of.caller.methodName(Filename:line)</c>
++        /// </para>
++        /// </remarks>
++        public string FullInfo
++        {
++            get { return m_fullInfo; }
++        }
++
++        #endregion Public Instance Properties
++
++        #region Private Instance Fields
++
++        private readonly string m_lineNumber;
++        private readonly string m_fileName;
++        private readonly string m_className;
++        private readonly string m_fullInfo;
++		private readonly MethodItem m_method;
++
++        #endregion
++
++        #region Private Static Fields
++
++        /// <summary>
++        /// The fully qualified type of the StackFrameItem class.
++        /// </summary>
++        /// <remarks>
++        /// Used by the internal logger to record the Type of the
++        /// log message.
++        /// </remarks>
++        private readonly static Type declaringType = typeof(StackFrameItem);
++
++        /// <summary>
++        /// When location information is not available the constant
++        /// <c>NA</c> is returned. Current value of this string
++        /// constant is <b>?</b>.
++        /// </summary>
++        private const string NA = "?";
++
++        #endregion Private Static Fields
++    }
++}
+diff -r ecf5fe65b288 src/Layout/Pattern/StackTraceDetailPatternConverter.cs
+--- a/src/Layout/Pattern/StackTraceDetailPatternConverter.cs	Mon Mar 05 19:38:11 2012 +0000
++++ b/src/Layout/Pattern/StackTraceDetailPatternConverter.cs	Fri May 25 21:48:29 2012 +0200
+@@ -41,14 +41,14 @@
+     /// <author>Adam Davies</author>
+     internal class StackTraceDetailPatternConverter : StackTracePatternConverter
+     {
+-        internal override string GetMethodInformation(System.Reflection.MethodBase method)
++        internal override string GetMethodInformation(MethodItem method)
+         {
+             string returnValue="";
+ 
+             try
+             {
+                 string param = "";
+-                string[] names = GetMethodParameterNames(method);
++                string[] names = method.Parameters;
+                 StringBuilder sb = new StringBuilder();
+                 if (names != null && names.GetUpperBound(0) > 0)
+                 {
+@@ -74,28 +74,6 @@
+             return returnValue;
+         }
+ 
+-        private string[] GetMethodParameterNames(System.Reflection.MethodBase methodBase)
+-        {
+-            ArrayList methodParameterNames = new ArrayList();
+-            try
+-            {
+-                System.Reflection.ParameterInfo[] methodBaseGetParameters = methodBase.GetParameters();
+-                
+-                int methodBaseGetParametersCount = methodBaseGetParameters.GetUpperBound(0);
+-
+-                for (int i = 0; i <= methodBaseGetParametersCount; i++)
+-                {
+-                    methodParameterNames.Add(methodBaseGetParameters[i].ParameterType + " " + methodBaseGetParameters[i].Name);
+-                }
+-            }
+-            catch (Exception ex)
+-            {
+-                LogLog.Error(declaringType, "An exception ocurred while retreiving method parameters.", ex);
+-            }
+-
+-            return (string[])methodParameterNames.ToArray(typeof (string));
+-        }
+-
+         #region Private Static Fields
+ 
+         /// <summary>
+diff -r ecf5fe65b288 src/Layout/Pattern/StackTracePatternConverter.cs
+--- a/src/Layout/Pattern/StackTracePatternConverter.cs	Mon Mar 05 19:38:11 2012 +0000
++++ b/src/Layout/Pattern/StackTracePatternConverter.cs	Fri May 25 21:48:29 2012 +0200
+@@ -95,7 +95,7 @@
+ 		/// </remarks>
+ 		override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
+ 		{
+-			StackFrame[] stackframes = loggingEvent.LocationInformation.StackFrames;
++			StackFrameItem[] stackframes = loggingEvent.LocationInformation.StackFrames;
+ 			if ((stackframes == null) || (stackframes.Length <= 0))
+ 			{
+ 				LogLog.Error(declaringType, "loggingEvent.LocationInformation.StackFrames was null or empty.");
+@@ -109,10 +109,10 @@
+ 				{
+ 					stackFrameIndex--;
+ 					continue;
+-				}
+-				
+-				StackFrame stackFrame = stackframes[stackFrameIndex];
+-                writer.Write("{0}.{1}", stackFrame.GetMethod().DeclaringType.Name, GetMethodInformation(stackFrame.GetMethod()));
++				}
++
++				StackFrameItem stackFrame = stackframes[stackFrameIndex];
++                writer.Write("{0}.{1}", stackFrame.ClassName, GetMethodInformation(stackFrame.Method));
+ 				if (stackFrameIndex > 0)
+ 				{
+                     // TODO: make this user settable?
+@@ -128,7 +128,7 @@
+         /// <param name="method"></param>
+         /// <remarks>This method was created, so this class could be used as a base class for StackTraceDetailPatternConverter</remarks>
+         /// <returns>string</returns>
+-        internal virtual string GetMethodInformation(System.Reflection.MethodBase method)
++        internal virtual string GetMethodInformation(MethodItem method)
+         {
+             return method.Name;
+         }
+diff -r ecf5fe65b288 src/log4net.vs2008.csproj
+--- a/src/log4net.vs2008.csproj	Mon Mar 05 19:38:11 2012 +0000
++++ b/src/log4net.vs2008.csproj	Fri May 25 21:48:29 2012 +0200
+@@ -301,12 +301,18 @@
+     <Compile Include="Core\LogImpl.cs">
+       <SubType>Code</SubType>
+     </Compile>
++    <Compile Include="Core\MethodItem.cs">
++      <SubType>Code</SubType>
++    </Compile>
+     <Compile Include="Core\SecurityContext.cs">
+       <SubType>Code</SubType>
+     </Compile>
+     <Compile Include="Core\SecurityContextProvider.cs">
+       <SubType>Code</SubType>
+     </Compile>
++    <Compile Include="Core\StackFrameItem.cs">
++      <SubType>Code</SubType>
++    </Compile>
+     <Compile Include="Core\TimeEvaluator.cs" />
+     <Compile Include="Core\WrapperMap.cs">
+       <SubType>Code</SubType>
+diff -r ecf5fe65b288 src/log4net.vs2010.csproj
+--- a/src/log4net.vs2010.csproj	Mon Mar 05 19:38:11 2012 +0000
++++ b/src/log4net.vs2010.csproj	Fri May 25 21:48:29 2012 +0200
+@@ -317,12 +317,18 @@
+     <Compile Include="Core\LogImpl.cs">
+       <SubType>Code</SubType>
+     </Compile>
++    <Compile Include="Core\MethodItem.cs">
++      <SubType>Code</SubType>
++    </Compile>
+     <Compile Include="Core\SecurityContext.cs">
+       <SubType>Code</SubType>
+     </Compile>
+     <Compile Include="Core\SecurityContextProvider.cs">
+       <SubType>Code</SubType>
+     </Compile>
++    <Compile Include="Core\StackFrameItem.cs">
++      <SubType>Code</SubType>
++    </Compile>
+     <Compile Include="Core\TimeEvaluator.cs" />
+     <Compile Include="Core\WrapperMap.cs">
+       <SubType>Code</SubType>
+@@ -784,4 +790,4 @@
+     <PostBuildEvent>
+     </PostBuildEvent>
+   </PropertyGroup>
+-</Project>
+\ No newline at end of file
++</Project>
+LOG4NET-341
 RFA-NG
 LOG4NET-190
 LOG4NET-108