我的项目非常庞大,它包括IIS服务器和Windows服务,甚至一些UNIX / cgi服务也将使用WCF框架读取
它将包括3层,一个MVC女士网站,多个服务网关等。
我想知道你会为我推荐哪种异常处理机制。
我正在寻找多才多艺的东西,但我们不想过火。我查看了ELMAH
根据我的理解,ELMAH使用HttpModules,因此如果不稍微调整它,它将无法用于我的Windows服务。
你推荐别的吗?
P.S。
我没有层之间的安全问题。它们都在我的域中
答案 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服务。
希望它会对你有所帮助。