[ 
https://issues.apache.org/jira/browse/LOG4NET-306?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Jon Abaunza updated LOG4NET-306:
--------------------------------

    Priority: Minor  (was: Blocker)

> Allowing the MethodLocationPatternConverter to skip certain methods from the 
> call stack when trying to log the caller method (Solution for Log4Net 
> wrappers)
> ------------------------------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: LOG4NET-306
>                 URL: https://issues.apache.org/jira/browse/LOG4NET-306
>             Project: Log4net
>          Issue Type: New Feature
>          Components: Other
>    Affects Versions: 1.2.9, 1.2.10
>            Reporter: Jon Abaunza
>            Priority: Minor
>
> There are several environments where it is required to develop a wrapper 
> around Log4Net for backward compatibility with previous logging systems.
> The problem comes when it is required to obtain the method name. The system 
> goes up in the StackTrace and identifies the wrapper method as the first user 
> method and therefore logs the name of the wrapper instead of the real caller 
> method.
> The solution would be as simple as creating a new MethodAtribute (lets say 
> log4Net.SkipMethodForMethodLocation). I would be able to decorate my method 
> with it and the MethodLocationPatternConverter would continue looking up in 
> the stackTrace for the next user method.
> Modifications made (just modified the constructor)
> LocationInfo.cs
> public class LocationInfo
> {
>               /// <summary>
>       /// Constructor
>       /// </summary>
>       /// <param name="callerStackBoundaryDeclaringType">The declaring type 
> of the method that is
>       /// the stack boundary into the logging system for this call.</param>
>       /// <remarks>
>       /// <para>
>       /// Initializes a new instance of the <see cref="LocationInfo" />
>       /// class based on the current thread.
>       /// </para>
>       /// </remarks>
>       public LocationInfo(Type callerStackBoundaryDeclaringType) 
>       {
>               // Initialize all fields
>               m_className = NA;
>               m_fileName = NA;
>               m_lineNumber = NA;
>               m_methodName = NA;
>               m_fullInfo = NA;
>               m_assembly = NA;
> #if !NETCF
>               if (callerStackBoundaryDeclaringType != null)
>               {
>                       try
>                       {
>                               StackTrace st = new StackTrace(true);
>                               int frameIndex = 0;
>                               // skip frames not from fqnOfCallingClass
>                               while (frameIndex < st.FrameCount)
>                               {
>                                       StackFrame frame = 
> st.GetFrame(frameIndex);
>                                       if (frame != null && 
> frame.GetMethod().DeclaringType == callerStackBoundaryDeclaringType)
>                                       {
>                                               break;
>                                       }
>                                       frameIndex++;
>                               }
>                               // skip frames from fqnOfCallingClass
>                               while (frameIndex < st.FrameCount)
>                               {
>                                       StackFrame frame = 
> st.GetFrame(frameIndex);
>                                       if (frame != null && 
> frame.GetMethod().DeclaringType != callerStackBoundaryDeclaringType)
>                                       {
>                                               break;
>                                       }
>                                       frameIndex++;
>                               }
>                               while (frameIndex < st.FrameCount)
>                               {
>                                            // now frameIndex is the first 
> 'user' caller frame
>                                       StackFrame locationFrame = 
> st.GetFrame(frameIndex);
>                                       if (locationFrame != null)
>                                       {
>                                               System.Reflection.MethodBase 
> method = locationFrame.GetMethod();
>                                       
>                                               if (method != null)
>                                               {
>                                                       bool skip = false;
>                                                                               
>                                   //NEW CHANGES:
>                                                                               
>                                   //We look for the new Custom attribute 
> SkipMethodInMethodLocationAttribute
>                                                                               
>                                   //if the method is decorated with the 
> attribute we will continue looking up in the stack
>                                                       object[] 
> customAttributes = 
> method.GetCustomAttributes(typeof(SkipMethodInMethodLocationAttribute), 
> false);
>                                                       foreach (object 
> customAttribute in customAttributes)
>                                                       {
>                                                               
> SkipMethodInMethodLocationAttribute skipMethodAttribute = customAttribute as 
> SkipMethodInMethodLocationAttribute;
>                                                               if 
> (skipMethodAttribute != null)
>                                                               {
>                                                                       skip = 
> skipMethodAttribute.Skip;
>                                                               }
>                                                       }
>                                                       //If the method was 
> decorated with the attribute we continue looking up in the stack
>                                                       if (!skip)
>                                                       {
>                                                               m_methodName = 
> method.Name;
>                                                               if 
> (method.DeclaringType != null)
>                                                               {
>                                                                       
> m_className = method.DeclaringType.FullName;
>                                                               }
>                                                               m_assembly = 
> method.Module.Assembly.FullName;
>                                                               m_fileName = 
> locationFrame.GetFileName();
>                                                               m_lineNumber = 
> locationFrame.GetFileLineNumber().ToString(System.Globalization.NumberFormatInfo.InvariantInfo);
>                                                               // Combine all 
> location info
>                                                               m_fullInfo = 
> m_className + '.' + m_methodName + '(' + m_fileName + ':' + m_lineNumber + 
> ')';
>                                                               break;
>                                                       }
>                                               }                               
>                         
>                                       }
>                                       frameIndex++;
>                               }
>                       }
>                       catch(System.Security.SecurityException)
>                       {
>                               // This security exception will occur if the 
> caller does not have 
>                               // some undefined set of SecurityPermission 
> flags.
>                               LogLog.Debug("LocationInfo: Security exception 
> while trying to get caller stack frame. Error Ignored. Location Information 
> Not Available.");
>                       }
>               }
> #endif
>       }
>       //.................End of modifications...............//
> }

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

Reply via email to