在c#中记录异常

时间:2010-08-16 07:09:16

标签: c# exception logging

记录例外  下面的代码允许在文本文件中保存异常的内容。在这里,我只得到了错误的解释。

但它没有告诉我发生异常的位置,在哪一行。 任何人都可以告诉我,我怎么能得到这个,所以我甚至可以得到发生异常的行号?

#region WriteLogError
/// <summary>
/// Write an error Log in File
/// </summary>
/// <param name="errorMessage"></param>
public void WriteLogError(string errorMessage)
{
  try
  {
    string path = "~/Error/" + DateTime.Today.ToString("dd-mm-yy") + ".txt";
    if (!File.Exists(System.Web.HttpContext.Current.Server.MapPath(path)))
    {
      File.Create(System.Web.HttpContext.Current.Server.MapPath(path))
     .Close();
    }
    using (StreamWriter w = File.AppendText(System.Web.HttpContext.Current.Server.MapPath(path)))
    {
      w.WriteLine("\r\nLog Entry : ");
      w.WriteLine("{0}", DateTime.Now.ToString(CultureInfo.InvariantCulture));
      string err = "Error in: " + System.Web.HttpContext.Current.Request.Url.ToString() 
                 + ". Error Message:" + errorMessage;
      w.WriteLine(err);
      w.WriteLine("__________________________");
      w.Flush();
      w.Close();
    }
  }
  catch (Exception ex)
  {
    WriteLogError(ex.Message);
  }

}

#endregion

6 个答案:

答案 0 :(得分:36)

我发现在C#中记录异常的最简单方法是调用ToString()方法:

try
{

}
catch (Exception ex)
{
    Console.WriteLine(ex.ToString());
}

这通常会为您提供所需的所有信息,例如错误消息和堆栈跟踪,以及任何额外的异常特定上下文信息。 (但请注意,如果使用调试信息编译应用程序,堆栈跟踪将仅显示源文件和行号)

值得注意的是,看到完整的堆栈跟踪对于用户来说可能是相当不合适的,所以只要有可能,您应该尝试处理异常并打印出更友好的错误消息。

另一方面 - 您应该使用功能齐全的日志框架(例如Serilog替换您的方法WriteLogError,而不是尝试编写自己的方法。

您的日志记录方法不是线程安全的(您的日志文件可能最终会将日志消息相互混合)并且如果您捕获异常,也绝对不应该调用自身 - 这将意味着在记录时发生的任何异常错误可能会导致难以诊断StackOverflow异常。

我可以建议如何解决这些问题,但是使用正确的日志框架会更好。

答案 1 :(得分:7)

只需记录ToString()即可。它不仅会为您提供堆栈跟踪,还会包含内部异常。

答案 2 :(得分:4)

此外,例如,当您将代码的发布版本部署到生产环境时,请不要忘记在发布包中包含.pdb文件。您需要该文件来获取除外的代码的行号(请参阅How much information do pdb files contain? (C# / .NET)

答案 3 :(得分:1)

您的解决方案非常好。我经历了相同的阶段
并最终需要记录越来越多的日志(它将...):

  • 记录源位置
  • 异常之前的调用栈(可能在不同的地方)
  • 所有内部异常的使用方式相同
  • 进程ID /线程ID
  • 时间(或要求报价)
  • 用于网络-网址,http标头,客户端ip,cookie,网络会话内容
  • 其他一些关键变量值
  • 将程序集加载到内存中
  • ...

最好是单击发生错误的文件链接的方式,
或单击调用堆栈中的链接,Visual Studio就会在适当的位置打开。
(当然,您要做的只是*.PDB文件,这些文件来自IL代码的路径
存储到您在C#中发布的源代码中。)

所以我终于开始使用此解决方案:
它以Nuget package - Desharp的形式存在。
适用于两种应用程序类型-网络和桌面。
看到它是Desharp Github documentation。它具有许多配置选项。

try {
    var myStrangeObj = new { /*... something really mysterious ...*/ };
    throw new Exception("Something really baaaaad with my strange object :-)");
} catch (Exception ex) {

    // store any rendered object in debug.html or debug.log file
    Desharp.Debug.Log(myStrangeObj, Desharp.Level.DEBUG);

    // store exception with all inner exceptions and everything else
    // you need to know later in exceptions.html or exceptions.log file
    Desharp.Debug.Log(ex);
}

它具有HTML日志格式,每个异常都在一行中,
然后从html页面中打开浏览器,然后点击
在文件上链接并转到Visual Studio-真的很上瘾!
只需安装此Desharp editor opener

在此处查看一些演示:

尝试检出任何存储库并通过上述方式记录一些内容。
那么您可以在~/Logs目录中看到记录的结果。通常,任何东西都是可配置的。

答案 4 :(得分:0)

我只是回答这个问题,其他人已经提到了该代码。如果要在日志中包含行号,则需要在服务器部署中包括生成的调试文件(pdb)。如果仅是您的Dev / Test区域,那很好,但是我不建议在生产环境中使用。

答案 5 :(得分:0)

请注意,异常类是可序列化的。这意味着您可以使用内置的XmlSerializer轻松地将异常类写入磁盘-或使用自定义的序列化程序来写入txt文件。

当然,可以使用ToString()记录到输出,而不是像其他答案中提到的那样仅读取错误消息。

异常类

https://docs.microsoft.com/en-us/dotnet/api/system.exception?redirectedfrom=MSDN&view=netframework-4.7.2

有关序列化的信息,即将对象转换为磁盘上文件的操作,反之亦然。

https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/serialization/