Author: dpsenner Date: Tue May 28 11:40:46 2013 New Revision: 1486883 URL: http://svn.apache.org/r1486883 Log: LOG4NET-341 fix location info to not contain a reference to StackFrame any more
Added: logging/log4net/trunk/src/Core/MethodItem.cs logging/log4net/trunk/src/Core/StackFrameItem.cs Modified: logging/log4net/trunk/src/Core/LocationInfo.cs logging/log4net/trunk/src/DateFormatter/AbsoluteTimeDateFormatter.cs logging/log4net/trunk/src/Layout/Pattern/StackTraceDetailPatternConverter.cs logging/log4net/trunk/src/Layout/Pattern/StackTracePatternConverter.cs logging/log4net/trunk/src/log4net.vs2008.csproj logging/log4net/trunk/src/log4net.vs2010.csproj Modified: logging/log4net/trunk/src/Core/LocationInfo.cs URL: http://svn.apache.org/viewvc/logging/log4net/trunk/src/Core/LocationInfo.cs?rev=1486883&r1=1486882&r2=1486883&view=diff ============================================================================== --- logging/log4net/trunk/src/Core/LocationInfo.cs (original) +++ logging/log4net/trunk/src/Core/LocationInfo.cs Tue May 28 11:40:46 2013 @@ -118,10 +118,10 @@ namespace log4net.Core // take into account the frames we skip above int adjustedFrameCount = st.FrameCount - frameIndex; ArrayList stackFramesList = new ArrayList(adjustedFrameCount); - m_stackFrames = new StackFrame[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 @@ namespace log4net.Core /// <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 @@ namespace log4net.Core 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 Added: logging/log4net/trunk/src/Core/MethodItem.cs URL: http://svn.apache.org/viewvc/logging/log4net/trunk/src/Core/MethodItem.cs?rev=1486883&view=auto ============================================================================== --- logging/log4net/trunk/src/Core/MethodItem.cs (added) +++ logging/log4net/trunk/src/Core/MethodItem.cs Tue May 28 11:40:46 2013 @@ -0,0 +1,172 @@ +#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.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 + + /// <summary> + /// constructs a method item for an unknown method. + /// </summary> + public MethodItem() + { + m_name = NA; + m_parameters = new string[0]; + } + + /// <summary> + /// constructs a method item from the name of the method. + /// </summary> + /// <param name="name"></param> + public MethodItem(string name) + : this() + { + m_name = name; + } + + /// <summary> + /// constructs a method item from the name of the method and its parameters. + /// </summary> + /// <param name="name"></param> + /// <param name="parameters"></param> + public MethodItem(string name, string[] parameters) + : this(name) + { + m_parameters = parameters; + } + + /// <summary> + /// constructs a method item from a method base by determining the method name and its parameters. + /// </summary> + /// <param name="methodBase"></param> + 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 + } +} Added: logging/log4net/trunk/src/Core/StackFrameItem.cs URL: http://svn.apache.org/viewvc/logging/log4net/trunk/src/Core/StackFrameItem.cs?rev=1486883&view=auto ============================================================================== --- logging/log4net/trunk/src/Core/StackFrameItem.cs (added) +++ logging/log4net/trunk/src/Core/StackFrameItem.cs Tue May 28 11:40:46 2013 @@ -0,0 +1,188 @@ +#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.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 + } +} Modified: logging/log4net/trunk/src/DateFormatter/AbsoluteTimeDateFormatter.cs URL: http://svn.apache.org/viewvc/logging/log4net/trunk/src/DateFormatter/AbsoluteTimeDateFormatter.cs?rev=1486883&r1=1486882&r2=1486883&view=diff ============================================================================== --- logging/log4net/trunk/src/DateFormatter/AbsoluteTimeDateFormatter.cs (original) +++ logging/log4net/trunk/src/DateFormatter/AbsoluteTimeDateFormatter.cs Tue May 28 11:40:46 2013 @@ -101,71 +101,68 @@ namespace log4net.DateFormatter /// </remarks> virtual public void FormatDate(DateTime dateToFormat, TextWriter writer) { - lock (s_lastTimeStrings) - { - // Calculate the current time precise only to the second - long currentTimeToTheSecond = (dateToFormat.Ticks - (dateToFormat.Ticks % TimeSpan.TicksPerSecond)); + // Calculate the current time precise only to the second + long currentTimeToTheSecond = (dateToFormat.Ticks - (dateToFormat.Ticks % TimeSpan.TicksPerSecond)); - string timeString = null; - // Compare this time with the stored last time - // If we are in the same second then append - // the previously calculated time string - if (s_lastTimeToTheSecond != currentTimeToTheSecond) - { - s_lastTimeStrings.Clear(); - } - else - { - timeString = (string)s_lastTimeStrings[GetType()]; - } + string timeString = null; + // Compare this time with the stored last time + // If we are in the same second then append + // the previously calculated time string + if (s_lastTimeToTheSecond != currentTimeToTheSecond) + { + s_lastTimeStrings.Clear(); + } + else + { + timeString = (string) s_lastTimeStrings[GetType()]; + } + + if (timeString == null) + { + // lock so that only one thread can use the buffer and + // update the s_lastTimeToTheSecond and s_lastTimeStrings - if (timeString == null) + // PERF: Try removing this lock and using a new StringBuilder each time + lock(s_lastTimeBuf) { - // lock so that only one thread can use the buffer and - // update the s_lastTimeToTheSecond and s_lastTimeStrings + timeString = (string) s_lastTimeStrings[GetType()]; - // PERF: Try removing this lock and using a new StringBuilder each time - lock (s_lastTimeBuf) - { - timeString = (string)s_lastTimeStrings[GetType()]; - - if (timeString == null) - { - // We are in a new second. - s_lastTimeBuf.Length = 0; + if (timeString == null) + { + // We are in a new second. + s_lastTimeBuf.Length = 0; - // Calculate the new string for this second - FormatDateWithoutMillis(dateToFormat, s_lastTimeBuf); + // Calculate the new string for this second + FormatDateWithoutMillis(dateToFormat, s_lastTimeBuf); - // Render the string buffer to a string - timeString = s_lastTimeBuf.ToString(); + // Render the string buffer to a string + timeString = s_lastTimeBuf.ToString(); #if NET_1_1 // Ensure that the above string is written into the variable NOW on all threads. // This is only required on multiprocessor machines with weak memeory models System.Threading.Thread.MemoryBarrier(); #endif - // Store the time as a string (we only have to do this once per second) - s_lastTimeStrings[GetType()] = timeString; - s_lastTimeToTheSecond = currentTimeToTheSecond; - } + // Store the time as a string (we only have to do this once per second) + s_lastTimeStrings[GetType()] = timeString; + s_lastTimeToTheSecond = currentTimeToTheSecond; } } - writer.Write(timeString); - - // Append the current millisecond info - writer.Write(','); - int millis = dateToFormat.Millisecond; - if (millis < 100) - { - writer.Write('0'); - } - if (millis < 10) - { - writer.Write('0'); - } - writer.Write(millis); } + writer.Write(timeString); + + // Append the current millisecond info + writer.Write(','); + int millis = dateToFormat.Millisecond; + if (millis < 100) + { + writer.Write('0'); + } + if (millis < 10) + { + writer.Write('0'); + } + writer.Write(millis); } #endregion Implementation of IDateFormatter Modified: logging/log4net/trunk/src/Layout/Pattern/StackTraceDetailPatternConverter.cs URL: http://svn.apache.org/viewvc/logging/log4net/trunk/src/Layout/Pattern/StackTraceDetailPatternConverter.cs?rev=1486883&r1=1486882&r2=1486883&view=diff ============================================================================== --- logging/log4net/trunk/src/Layout/Pattern/StackTraceDetailPatternConverter.cs (original) +++ logging/log4net/trunk/src/Layout/Pattern/StackTraceDetailPatternConverter.cs Tue May 28 11:40:46 2013 @@ -41,14 +41,14 @@ namespace log4net.Layout.Pattern /// <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 @@ namespace log4net.Layout.Pattern 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> Modified: logging/log4net/trunk/src/Layout/Pattern/StackTracePatternConverter.cs URL: http://svn.apache.org/viewvc/logging/log4net/trunk/src/Layout/Pattern/StackTracePatternConverter.cs?rev=1486883&r1=1486882&r2=1486883&view=diff ============================================================================== --- logging/log4net/trunk/src/Layout/Pattern/StackTracePatternConverter.cs (original) +++ logging/log4net/trunk/src/Layout/Pattern/StackTracePatternConverter.cs Tue May 28 11:40:46 2013 @@ -95,7 +95,7 @@ namespace log4net.Layout.Pattern /// </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."); @@ -111,8 +111,8 @@ namespace log4net.Layout.Pattern 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 @@ namespace log4net.Layout.Pattern /// <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; } Modified: logging/log4net/trunk/src/log4net.vs2008.csproj URL: http://svn.apache.org/viewvc/logging/log4net/trunk/src/log4net.vs2008.csproj?rev=1486883&r1=1486882&r2=1486883&view=diff ============================================================================== --- logging/log4net/trunk/src/log4net.vs2008.csproj (original) +++ logging/log4net/trunk/src/log4net.vs2008.csproj Tue May 28 11:40:46 2013 @@ -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> Modified: logging/log4net/trunk/src/log4net.vs2010.csproj URL: http://svn.apache.org/viewvc/logging/log4net/trunk/src/log4net.vs2010.csproj?rev=1486883&r1=1486882&r2=1486883&view=diff ============================================================================== --- logging/log4net/trunk/src/log4net.vs2010.csproj (original) +++ logging/log4net/trunk/src/log4net.vs2010.csproj Tue May 28 11:40:46 2013 @@ -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>