多层内部系统的异常块

时间:2012-03-14 11:56:25

标签: .net logging enterprise-library elmah error-logging

我的项目非常庞大,它包括IIS服务器和Windows服务,甚至一些UNIX / cgi服务也将使用WCF框架读取

它将包括3层,一个MVC女士网站,多个服务网关等。

我想知道你会为我推荐哪种异常处理机制。

我正在寻找多才多艺的东西,但我们不想过火。我查看了ELMAH

根据我的理解,ELMAH使用HttpModules,因此如果不稍微调整它,它将无法用于我的Windows服务。

你推荐别的吗?

P.S。
我没有层之间的安全问题。它们都在我的域中

1 个答案:

答案 0 :(得分:1)

使用log4net。为了使其更强大,您需要创建另一个WCF服务,只将您的异常,错误或消息记录到数据库中。

步骤。

1 - 修改客户端应用程序的web.config / app.config

<configuration>
  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
  </configSections>
</configuration>

2 - 添加log4net部分如下。

  <log4net>
    <appender name="WcfAppender" type="Problem.Common.Logging.WcfAppender, Problem.Common">
      <endpointAddress value="http://localhost.poc.trunk.site-dev.local/Services/Log.svc"/>
    </appender>
    <appender name="FileAppender" type="log4net.Appender.FileAppender">
      <file value="log.log" />
      <appendToFile value="true" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date{dd-MM-yyyy HH:mm:ss} %message%newline" />
      </layout>
    </appender>
    <appender name="ColoredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender">
      <target value="Console.Error" />
      <mapping>
        <level value="FATAL" />
        <foreColor value="Red" />
        <backColor value="White" />
      </mapping>
      <mapping>
        <level value="ERROR" />
        <foreColor value="Red, HighIntensity" />
      </mapping>
      <mapping>
        <level value="WARN" />
        <foreColor value="Yellow" />
      </mapping>
      <mapping>
        <level value="INFO" />
        <foreColor value="Cyan" />
      </mapping>
      <mapping>
        <level value="DEBUG" />
        <foreColor value="Green" />
      </mapping>
      <layout type="log4net.Layout.SimpleLayout" />
    </appender>
    <logger name="WcfLogger">
      <level value="ALL" />
      <appender-ref ref="WcfAppender" />
      <appender-ref ref="ColoredConsoleAppender" />
    </logger>
    <logger name="FileLogger">
      <level value="ALL" />
      <appender-ref ref="FileAppender" />
      <appender-ref ref="ColoredConsoleAppender" />
    </logger>
  </log4net>

3 - 创建log.svc,如下所述。

namespace Problem.CustomerCore.Services
{
using System;
using System.ServiceModel;
using Common.ExceptionHandling;
using log4net;
using log4net.Core;

/// <summary>
/// Service contract for instrumentation operations - such as logging and performance tracking
/// </summary>
[ServiceContract]
public interface ILogPOC
{
    /// <summary>
    /// Writes an entry to the logging framework
    /// </summary>
    /// <param name="logDateTime">The timestamp that the event occurred</param>
    /// <param name="logLevel">The level of the event</param>
    /// <param name="host">The host on which the event occurred</param>
    /// <param name="loggerName">The name of the type that originally raised the exception</param>
    /// <param name="message">The message describing the event context</param>
    /// <param name="exception">Excpetion object in case of the log entry being an error</param>
    /// <param name="version">The version number of the component reporting the log entry</param>
    /// <param name="tenancyExternalReference">The external reference identifying the current tenancy.</param>
    [OperationContract]
    [FaultContract(typeof(ProcessingResultsList))]
    void WriteLogEntry(DateTime logDateTime, Level logLevel, string host, string loggerName, string message, string exception, string version, Guid tenancyExternalReference);
}

/// <summary>
/// Methods for instrumenting the application
/// </summary>
public class Log : ILogPOC
{
    /// <summary>
    /// The logger to use for writing out exceptions nad info logs
    /// </summary>
    private static ILog logger = LogManager.GetLogger(typeof(Instrumentation));

    /// <summary>
    /// Writes an entry to the logging framework
    /// </summary>
    /// <param name="logDateTime">The timestamp that the event occurred</param>
    /// <param name="logLevel">The level of the event</param>
    /// <param name="host">The host on which the event occurred</param>
    /// <param name="loggerName">The name of the type that originally raised the exception</param>
    /// <param name="message">The message describing the event context</param>
    /// <param name="exception">Excpetion object in case of the log entry being an error</param>
    /// <param name="version">The version number of the component reporting the log entry</param>
    /// <param name="tenancyExternalReference">The external reference identifying the current tenancy.</param>
    public void WriteLogEntry(DateTime logDateTime, Level logLevel, string host, string loggerName, string message, string exception, string version, Guid tenancyExternalReference)
    {
        log4net.Config.XmlConfigurator.Configure();
        ThreadContext.Properties["Host"] = host;
        ThreadContext.Properties["Version"] = version;
        ThreadContext.Properties["Tenancy"] = tenancyExternalReference;
        ThreadContext.Properties["User"] = System.Threading.Thread.CurrentPrincipal.Identity.Name;

        var eventData = new LoggingEventData
                            {
                                Identity = System.Threading.Thread.CurrentPrincipal.Identity.Name,
                                UserName = System.Threading.Thread.CurrentPrincipal.Identity.Name,
                                Level = logLevel,
                                LoggerName = loggerName,
                                TimeStamp = logDateTime,
                                Message = message,
                                ExceptionString = exception
                            };
        var logEvent = new LoggingEvent(eventData);

        // log the exception
        logger.Logger.Log(logEvent);
    }
}
}

4 - 同时在数据库中创建一个日志表。

5 - WCF的Web.config应如下所示。特别是log4net部分。

<log4net>
    <appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
      <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=4.0.30319.1, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
      <bufferSize value="100" />
      <lossy value="true" />
      <evaluator type="log4net.Core.LevelEvaluator">
        <threshold value="INFO"/>
      </evaluator>
      <connectionString value="Database=XYZ-trunk;Server=localhost;User ID=a;Password=b;Trusted_Connection=False;" />
      <connectionStringName value="connectionException" /> 
      <commandText value="[dbo].[spLog_WriteEntry]" />
      <commandType value="StoredProcedure" />
      <parameter>
        <parameterName value="@LogDateTime" />
        <dbType value="DateTime" />
        <layout type="log4net.Layout.RawTimeStampLayout" /> 
      </parameter>
      <parameter>
        <parameterName value="@Component" />
        <dbType value="String" />
        <size value="255" />
        <layout type="log4net.Layout.PatternLayout" value="%logger" />
      </parameter>
      <parameter>
        <parameterName value="@LogLevel" /> 
        <dbType value="String" />
        <size value="50" />
        <layout type="log4net.Layout.PatternLayout" value="%level" />
      </parameter>
      <parameter>
        <parameterName value="@Host" />
        <dbType value="String" />
        <size value="255" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%property{Host}"/>
        </layout> 
      </parameter>
      <parameter>
        <parameterName value="@Message" /> 
        <dbType value="String" /> 
        <size value="4000" />
        <layout type="log4net.Layout.PatternLayout" value="%message" />
      </parameter>
      <parameter>
        <parameterName value="@Exception" />
        <dbType value="String" />
        <size value="2000" />
        <layout type="log4net.Layout.ExceptionLayout" />
      </parameter>
      <parameter>
        <parameterName value="@Coulmn1" />
        <dbType value="String" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%property{Tenancy}"/>
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@Username" />
        <dbType value="String" />
        <size value="255" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%property{User}"/>
        </layout>
      </parameter>
    </appender>
    <appender name="SmtpAppender" type="log4net.Appender.SmtpAppender">
       <threshold value="WARN"/>
       <to value="error@a.com" />
       <from value="build@abc.com" />
       <subject value="SmtpAppender" />
       <smtpHost value="xyz.com" />
       <bufferSize value="512" />
       <lossy value="false" />
       <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%newline%date [%thread] %-5level %logger [%property{NDC}] - %message%newline%newline%newline" />
       </layout>
    </appender>
    <root> 
      <level value="DEBUG" />
      <appender-ref ref="AdoNetAppender" />
    </root>
  </log4net>

现在您设置WCF服务。

希望它会对你有所帮助。