1

is there a way to log all local variables and values (inc. params) when logging using log4net?
I know I can just add each value to the log message, but was wondering if there was a simpler way.
I also understand that this could affect performance, however, it wouldn't be used that much.

[how about without log4net? is there another method to capture all locals?]

Anthony Mastrean
  • 21,850
  • 21
  • 110
  • 188
eych
  • 1,262
  • 2
  • 16
  • 37
  • 1
    I don't have one that captures locals, but I created a logging interceptor using Castle's Interceptor that will log all parameters and the return value as XML. Castle is great for creating dynamic decorators like that. – James Michael Hare Apr 20 '11 at 22:17
  • possible duplicate of [How to Trace all local variables when an exception occurs](http://stackoverflow.com/questions/362124/how-to-trace-all-local-variables-when-an-exception-occurs) – Anthony Mastrean Jun 15 '11 at 21:38

2 Answers2

2

log4net does not provide a way to log all parameter values and locals. You can print them all yourself with calls like

Log.DebugFormat("{0}: {1}", /* get parameter name */, /* get parameter value */)

I was thinking StackFrame could get you that information, but it can only tell you about parameter types and method return types. There is no way to get locals.

You would have to use an interception framework like Castle DynamicProxy. The IInvocation parameter of the Intercept method provides the arguments

Log.DebugFormat("{0}.{1}({2})", invocation.TargetType.Name, invocation.Method.Name, string.Join(", ", invocation.Arguments));
Anthony Mastrean
  • 21,850
  • 21
  • 110
  • 188
0

I've used the interceptor tecnique to log all WCF call. You need to add some parameters to your appender (controller, action, user, datain, dataout) Hope this help

public interface IOpenUserName
    {
        string UserName { get; set; }
    }

    [AttributeUsage(AttributeTargets.Method)]
    public class LogWcfAttribute : Attribute
    {

    }

    public class LogWcfInterceptor : IInterceptor
    {
        private readonly ILogger _logger;

        public LogWcfInterceptor(ILogger logger)
        {
            _logger = logger;
        }

        public void Intercept(IInvocation invocation)
        {
            if (WcfHelper.HasLogWcfAttribute(invocation.MethodInvocationTarget))
            {
                Exception exception = null;

                var openUser = (IOpenUserName) invocation.InvocationTarget;

                log4net.LogicalThreadContext.Properties["controller"] = invocation.InvocationTarget.GetType().Name;
                log4net.LogicalThreadContext.Properties["action"] = invocation.MethodInvocationTarget.Name;

                log4net.LogicalThreadContext.Properties["user"] = openUser != null ? openUser.UserName : string.Empty;
                log4net.LogicalThreadContext.Properties["datain"] = SerializeObject(invocation.Arguments);

                try
                {
                    invocation.Proceed();
                }
                catch (Exception ex)
                {
                    exception = ex;
                }
                finally
                {
                    log4net.LogicalThreadContext.Properties["dataout"] = SerializeObject(invocation.ReturnValue);
                    _logger.Debug("OPENOTA", exception);
                }

                if (exception != null) throw exception;
            }
            else
            {
                invocation.Proceed();
            }
        }

        public static string SerializeObject(object toSerialize)
        {
            if (toSerialize == null) return string.Empty;

            var xmlSerializer = new XmlSerializer(toSerialize.GetType());
            var textWriter = new StringWriter();

            xmlSerializer.Serialize(textWriter, toSerialize);
            return textWriter.ToString();
        }
    }

    public static class WcfHelper
    {
        public static bool HasLogWcfAttribute(MethodInfo methodInfo)
        {
            return methodInfo.IsDefined(typeof(LogWcfAttribute), false);
        }
    }