当前位置:  开发笔记 > 编程语言 > 正文

异常处理中函数参数的通用日志记录

如何解决《异常处理中函数参数的通用日志记录》经验,为你挑选了3个好方法。

我的很多C#代码遵循这种模式:

void foo(string param1, string param2, string param3)
{
    try
    {
         // do something...
    }
    catch(Exception ex)
    {
        LogError(String.Format("Error in foo(param1={0}, param2={1}, param3={2}), exception={3}", param1, param2, param3, ex.Message));
    }
}

有没有办法在.NET中获取函数的键/值列表,以便我可以调用另一个函数来构造我的错误记录字符串?或者你有更通用/更好的方法吗?



1> Panos..:

您可以使用Reflection和必须以正确的顺序将参数传递给LogError的约定:

private static void MyMethod(string s, int x, int y)
{
    try
    {
        throw new NotImplementedException();
    }
    catch (Exception ex)
    {
        LogError(MethodBase.GetCurrentMethod(), ex, s, x, y);
    }
}

private static void LogError(MethodBase method, Exception ex, params object[] values)
{
    ParameterInfo[] parms = method.GetParameters();
    object[] namevalues = new object[2 * parms.Length];

    string msg = "Error in " + method.Name + "(";
    for (int i = 0, j = 0; i < parms.Length; i++, j += 2)
    {
        msg += "{" + j + "}={" + (j + 1) + "}, ";
        namevalues[j] = parms[i].Name;
        if (i < values.Length) namevalues[j + 1] = values[i];
    }
    msg += "exception=" + ex.Message + ")";
    Console.WriteLine(string.Format(msg, namevalues));
}



2> Jacob..:

您可以在PostSharp中使用面向方面的编程(请参阅http://www.postsharp.org,以及http://www.codeproject.com/KB/cs/ps-custom-attributes-1.aspx上的教程)).基本上你可以这样做:

public class LogExceptionAttribute : OnExceptionAspect
{
 public override void OnException(MethodExecutionEventArgs eventArgs)
 {
  log.error("Exception occurred in method {0}", eventArgs); 
 }
}

[LoggingOnExceptionAspect]
public foo(int number, string word, Person customer)
{
   // ... something here throws an exception
}

也许不是你想要的,但我相信它可以根据你的需要进行调整.



3> Joe..:

没有办法做到这一点.

通常的做法是不捕获异常,除非你能处理它们.

也就是说,您通常只会捕获异常并将它们记录在顶级异常处理程序中.然后,您将获得堆栈跟踪,但当然不会获得堆栈中所有方法调用的所有参数的详细信息.

显然,在调试时,您需要尽可能多的细节.其他实现方法是:

使用Debug.Assert语句来测试您正在进行的假设.

使用可以选择性激活的日志记录来检测应用程序.我使用Log4Net,但也有其他选择,包括使用System.Diagnostics.Trace类.

在任何情况下,如果您只捕获异常以记录它们(我在n层应用程序的层边界执行此操作,以便在服务器上记录异常),那么您应该始终重新抛出它们:

try
{
    ...
}
catch(Exception ex)
{
    log(ex);
    throw;
}

推荐阅读
kikokikolove
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有