Welcome to EMC Consulting Blogs Sign in | Join | Help

Merrick Chaffer's Blog

Using PostSharp to log method entry and exit in .NET code.

1. Add the following line to your assemblyinfo.cs for the project that you want logging to take place in. Note: In order to exclude method entry and exit for the get_ and set_ methods for property getters and setters you have to add the highlighted line below as well, otherwise just remove this line if you want everything logged, although be aware your log files can grow very quickly with everything logged!

using dh.Common.PostSharp;

using PostSharp.Extensibility;

[assembly: Logging(AttributeTargetElements= MulticastTargets.Method)]

[assembly: Logging(AttributeTargetMembers = "*et_*", AttributeExclude =true)]

2. Add a reference to log4net.dll, and associated entry in assemblyinfo.cs to enable it...

[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config")] 

3. Add the following to the app.config

<configuration>

<configSections>

      <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>

  </configSections>

  <log4net configSource="log4net.config"/>

</configuration> 

4. Add a log4net.config file to your project, and set the BuildAction property to Content, and Copy to output directory to Copy Always, and then update it with the following lines of xml...

<log4net>

      <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">

            <file value="C:\\logs\\myCompany.MyApplication.log"/>

            <appendToFile value="true"/>

            <rollingStyle value="Composite"/>

            <datePattern value="yyyyMMdd-hh"/>

            <maxSizeRollBackups value="168"/>

            <maximumFileSize value="1MB"/>

            <layout type="log4net.Layout.PatternLayout">

                  <conversionPattern value="%d %-5p %c - %m%n"/>

            </layout>

      </appender>

      <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">

            <layout type="log4net.Layout.PatternLayout">

                  <param name="ConversionPattern" value="%d %-5p %c - %m%n"/>

            </layout>

      </appender>

      <root>

            <level value="DEBUG"/>

            <appender-ref ref="RollingFileAppender"/>

            <appender-ref ref="ConsoleAppender"/>

      </root>

</log4net>

 

4. Create the following class.

namespace myCompany.Common.PostSharp

{

    #region

 

    usingSystem;

    using System.Collections;

    usingSystem.Collections.Generic;

    usingSystem.Reflection;

    usingSystem.Text;

    using global::PostSharp.Extensibility;

    using global::PostSharp.Laos;

    usinglog4net;

 

    #endregion

 

    /// <summary>

    /// Logging attribute.

    /// </summary>

    [Serializable]

    [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true, Inherited = false)]

    [MulticastAttributeUsage(MulticastTargets.Method, AllowMultiple = true)]

    public class LoggingAttribute: OnMethodBoundaryAspect

    {

        /// <summary>

        /// Log4net logger.

        /// </summary>

        privatestatic readonlyILog Logger = LogManager.GetLogger(typeof(LoggingAttribute));

 

        /// <summary>

        /// The on entry.

        /// </summary>

        /// <paramname="eventArgs">

        /// The event args.

        /// </param>

        public override voidOnEntry(MethodExecutionEventArgs eventArgs)

        {

            if(DetermineWhetherToLogMethod(eventArgs))

            {

                varlogMessage = new StringBuilder();

                logMessage.Append(

                        string.Format(

                                "==> Method Entry: {0}.{1}",eventArgs.Method.DeclaringType, eventArgs.Method.Name));

                object[]argumentValues = eventArgs.GetReadOnlyArgumentArray();

                ParameterInfo[]parameterInfos = eventArgs.Method.GetParameters();

 

                logMessage.Append("(");

                if(argumentValues != null &&parameterInfos != null)

                {

                    for(int i = 0; i < argumentValues.Length; i++)

                    {

                        logMessage.Append(

                                string.Format(

                                        "Argument Name:'{0}', Argument Value:'{1}'",

                                       parameterInfosIdea.Name,

                                       argumentValuesIdea));

 

                        if (parameterInfosIdea.GetType() == typeof(ICollection<>))

                        {

                            int count = ((ICollection)parameterInfosIdea).Count;

                           logMessage.AppendLine("Count is "+ count);

                        }

                    }

                }

 

                logMessage.Append(")");

               Logger.Debug(logMessage.ToString());

            }

        }

 

        /// <summary>

        /// The on exit.

        /// </summary>

        /// <paramname="eventArgs">

        /// The event args.

        /// </param>

        public override void OnExit(MethodExecutionEventArgs eventArgs)

        {

            if(DetermineWhetherToLogMethod(eventArgs))

            {

                Logger.Debug(

                        string.Format(

                                "<== Method Exit: {0}.{1} Return Value:{2}",

                               eventArgs.Method.DeclaringType,

                               eventArgs.Method.Name,

                               eventArgs.ReturnValue));

            }

        }

 

        /// <summary>

        /// Determines the whether to log method.

        /// </summary>

        /// <paramname="eventArgs">

        /// The <seecref="MethodExecutionEventArgs"/>instance containing the event data.

        /// </param>

        /// <returns>

        /// True if current method should be logged.

        /// </returns>

        privatestatic boolDetermineWhetherToLogMethod(MethodExecutionEventArgseventArgs)

        {

            if(Logger.IsDebugEnabled

                && (eventArgs != null && eventArgs.Method != null && eventArgs.Method.Name != null))

            {

                returntrue;

            }

 

            returnfalse;

        }

    }

}

Published Tuesday, August 04, 2009 4:04 PM by merrick.chaffer

Comments

No Comments
Anonymous comments are disabled

This Blog

Syndication

News

Powered by Community Server (Personal Edition), by Telligent Systems