Исключительный блок для многоуровневой внутренней системы - PullRequest
0 голосов
/ 14 марта 2012

Мой проект довольно большой, он включает в себя серверы IIS и службы Windows, даже некоторые службы UNIX / cgi, которые будут считываться с помощью инфраструктуры WCF

Он будет включать 3 уровня, веб-сайт Ms MVC, Multiple Serviceшлюзы и т.д ..

Мне интересно, какой механизм обработки исключений вы бы порекомендовали для меня.

Я ищу что-то универсальное, но мы не хотим идти за борт.Я проверил ELMAH

Из того, что я понимаю, ELMAH использует HttpModules, поэтому он не будет работать с моими службами Windows, не настроив его немного.

Вы рекомендуете что-то еще?

ps
У меня нет проблем безопасности между слоями.Все они в моем домене

1 Ответ

1 голос
/ 14 марта 2012

Использовать 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 - Web.config для WCF должен выглядеть следующим образом.особенно раздел 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.

Надеюсь, она вам поможет.

...