2012-07-14 47 views
0

我有很多地方在我的代码库中,我希望在事情出错时得到通知 - 我想象的很常见。看下面的代码,我怎么能重新分析这个方法来抽象出电子邮件/日志记录的细节?目前,这分散在大约100个地方,我真的需要做一些事情!我怎样才能抽象出日志细节?

public bool MethodOne() { 
    string message; 
    bool success = new Task().Execute(); 

    message = string.Format("MethodOne was {0} successful.", 
     success ? "" : "not"); 

    if(!success) 
     SMTP.send(to, from, message); 

    System.Diagnostic.EventLog.WriteEntry(executingAssembly, message); 

    return success; 
}; 

我现在的想法是做类似下面的内容:

public class Log 
{ 
    string to = "[email protected]", 
     from = "[email protected]", 
     subject = "Error occured"; 

    public void Write(string executingAssembly, string message, bool sendEmail) 
    { 
     System.Diagnostic.EventLog.WriteEntry(executingAssembly, message); 

     if(sendEmail) 
      SendEmail(to, from, subject, message); 
    } 

    private void SendEmail(to, from, subject, message) 
    { 
     // Details to send email. 
    } 
} 

问: 我怎么能提高记录的错误我的应用程序内的可维护性和发送通知?

回答

5

考虑使用日志记录和日志管理器程序,例如NLog。然后,您可以编写一组业务规则来登录指定要记录到不同位置(目标)的nlog.config(或application.config)文件,并且您可以指定要为每个位置记录的内容(取决于严重性和类别) 。

从NLOG网站

采取了一些NLOG支持的目标

  • 文件 - 单个文件或多个,具有自动文件命名和归档
  • 事件日志 - 本地或远程
  • 数据库 - 将您的日志存储在.NET支持的数据库中
  • 网络 - 使用TCP,UDP,SOAP,MS MQ协议
  • 命令行控制台 - 包括消息的颜色编码
  • 电子邮件 - 您可以接收应用程序时出现错误使用NLOG

  • ASP.NET跟踪

一些关键功能的电子邮件

  • 很容易配置,均通过配置文件和编程
  • 易于使用记录器模式从升已知og4xxx
  • 使用缓冲,异步日志,负载平衡,故障转移和更
  • 跨平台支持
  • 高级路由:.NET框架,.NET Compact Framework的单(在Windows和Unix)
+1

NLog支持许多日志记录目标,包括文件和电子邮件。它处理日志文件旋转之类的事情,并允许在需要时进行大量的自定义。 – 2012-07-14 16:39:12

0

微软企业库有两个非常好的块,Logging Application BlockException Handling Application Block

这是一个基于策略的系统,允许您在.config文件中定义不同的策略。随着地方政策和一些异常处理程序,你可以写你的catch块这样的:

catch(Exception ex) 
{ 
    if(HandleException("My Datalayer Policy", ex)) throw; 
} 

例外策略可以配置成泡沫的情况下,还是不行。非常好的图书馆。

日志记录块还使用“策略”。配置称为类别。例如,如果我想记录一些消息,但其他人也想发电子邮件,我会使用两个类别和两个侦听器,一个用于记录事件,另一个用于通过电子邮件发送事件的详细信息。如果未指定电子邮件类别,例如Sucess为true,则仅发生日志记录事件。当成功为假时,将应用“电子邮件”类别,并且两个听众都会触发。

0

几点意见:

你的日志类应该是一个静态类。
你应该尝试/捕获所有的错误处理代码,因为错误管理应该做的最后一件事是......导致错误!
您可以使用枚举来列出主要错误类型和/或严重性/另一个...
我更喜欢将日志错误记录到与App相同的文件夹中的一个小文本文件中。更容易处理,客户可以通过邮件发送邮件(我不喜欢应用程序通过邮件发送数据的想法,您应该检查您的客户/用户是否可以使用这种方式)。
您可以从Reflection获得正在执行的程序集或其他信息。
您可能还会从StackTrace中获得其他有价值的信息(我在我的错误日志中编写Stacktrace,为我节省了相当一段时间)。
您还应该在应用程序级别捕获未处理的异常。 请为更具体的答案描述更多的错误。

+0

我同意通过邮件发送邮件。我应该提到这是一项自动化任务,所以我实际上并没有“看它”,并想知道是否有任何错误。这些消息将发给我/ dev团队。 – Daniel 2012-07-14 16:24:00

0

我假设不成功的任务执行是例外(否则你会发送大量的电子邮件给某人)。因此,在任务失败时抛出异常(您也可以提供有关为什么任务失败的更多详细信息)。下面是一些代码的NLog用法:

private static Logger _logger = LogManager.GetCurrentClassLogger(); 

public bool MethodFoo() 
{ 
    try 
    { 
     new Task().Execute(); 
     _logger.Info("Task executed successfully"); 
     return true;   
    } 
    catch(YourCustomException ex) 
    { 
     _logger.ErrorException("Cannot execute task", ex); 
     return false; 
    } 
} 

剩下的唯一的事情就是NLOG配置:

<?xml version="1.0" encoding="utf-8" ?> 
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <targets> 
     <target name="eventLog" xsi:type="EventLog" 
       log="Application" source="Your Source" machineName="." 
       layout="${longdate}|${level}|${callsite:methodName=true}${message}" /> 
     <target name="email" xsi:type="Mail" 
       subject="Error occured" 
       to="[email protected]" 
       from="[email protected]" 
       smtpServer="127.0.0.1" 
       smtpPort="25" 
       body="${longdate}|${message}" /> 
    </targets> 
    <rules> 
     <logger name="*" minlevel="Info" writeTo="eventLog" /> 
     <logger name="*" minlevel="Error" writeTo="email" /> 
    </rules> 
</nlog> 

你需要两个目标 - 一个用于信息写入和错误信息记录到事件日志,二来通过邮件发送错误通知。此外,我创建了两条规则 - 级别为Info和更高级别的所有消息都将发送到事件日志,但错误和致命消息将通过电子邮件发送。

顺便说一句,调用站点布局渲染器${callsite:methodName=true}方法名将被插入到日志消息中。因此你不需要在代码中指定它。

0

如果你想抽象其他人在这里建议的日志抽象,你可以使用Commons Logging。是的,这是两层间接的,但有些情况下可能有用。

您可以安装NuGet包,然后用它在你的代码是这样的:

// obtain logger instance 
ILog log = LogManager.GetCurrentClassLogger(); 

// log something 
log.Info("Some Debug Log Output"); 

然后配置公共日志库使用NLOG这样的:

<common> 
    <logging> 
    <factoryAdapter type="Common.Logging.NLog.NLogLoggerFactoryAdapter, Common.Logging.NLog20"> 
     <arg key="configType" value="INLINE" /> 
    </factoryAdapter> 
    </logging> 
</common> 

然后你就可以配置NLOG。 @Sergey Berezovskiy的回答就是一个例子。

问题是,Commons Logging库不会让您在NLog或log4net或Logging Application Block之间进行选择或其他任何操作。你可以将后端切换到任何你想要的。如果您正在编写一个dll或可能托管在各种项目类型中的东西,这会非常有用。当然,它也可能是一个无用的额外的间接层。这取决于你在做什么。