How do I log all current locals/parameters with log4net?
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 muc开发者_如何学Goh.[how about without log4net? is there another method to capture all locals?]
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));
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);
}
}
精彩评论