.Net异常发布器的开发(3)

有了以上这些基本素材之后,便是要考虑发布器的核心了,如何分析异常、匹配异常,然后得到新的异常记录并将它发布出去,这个类的名字叫ExceptionManager,我不罗列整个类的全部代码,只对其中一些核心代码进行说明:

当一个异常进入发布器中进行处理的时候,首先会根据当前语言取得相应语言的异常匹配资料,如果没有,则取得后备匹配资料:

ExceptionDetailData exceptionDetailDS = LogAccess.GetExceptionDetail();

ExceptionDetailData.ExceptionDetailRow[] exceptionDetials = (ExceptionDetailData.ExceptionDetailRow[])exceptionDetailDS.ExceptionDetail.Select("Language = '" +language+ "'");

if (exceptionDetials.Length == 0)

{

exceptionDetials = (ExceptionDetailData.ExceptionDetailRow[])exceptionDetailDS.ExceptionDetail.Select("Language IS NULL");

}

然后分析异常,取出有关属性放入相应的字段中:

string exceptionType = ee.GetType().ToString().Trim();

string inMessage ="";

string outMessage ="";

string source = "";

string stackTrace = "";

string targetSite = "";

string helpLink = "";

string eventLever = "";

userHelpLink = "";

#region 分析异常属性

if (ee.Message != null)

{

inMessage = ee.Message.Trim();

}

if (ee.HelpLink != null)

{

helpLink = ee.HelpLink.Trim();

}

if (ee.Source != null)

{

source = ee.Source.Trim();

}

if ( ee.StackTrace != null)

{

stackTrace = ee.StackTrace.Trim();

}

if (ee.TargetSite != null)

{

targetSite = ee.TargetSite.ToString().Trim();

}

#endregion

接着,匹配异常资料,为了要实现结构化的查询,这里使用的是一个比较笨的算法,毕竟,我觉得这里的技巧并不是太重要:

#region 查询异常处理

bool find = false;

foreach (ExceptionDetailData.ExceptionDetailRow exceptionDetail in exceptionDetials)

{

if (exceptionDetail.Type.Trim().ToLower() == exceptionType.ToLower() && !exceptionDetail.IsInMessage1Null() && !exceptionDetail.IsInMessage2Null() && !exceptionDetail.IsInMessage3Null() && !exceptionDetail.IsInMessage4Null())

{

string[] mathString = new string[4];

mathString[0] = exceptionDetail.InMessage1.Trim();

mathString[1] = exceptionDetail.InMessage2.Trim();

mathString[2] = exceptionDetail.InMessage3.Trim();

mathString[3] = exceptionDetail.InMessage4.Trim();

find = MatchMessage(inMessage, mathString);

if(find == true)

{

GetErrorMessage(out userHelpLink,out outMessage,out eventLever, exceptionDetail);

break;

}

}

}

if (find == false)

{

……

这里用到了一个方法MatchMessage,用来判定异常资料是否匹配:

internal static bool MatchMessage(string message, string[] matchMessage)

{

foreach (string match in matchMessage)

{

if( message.ToLower().IndexOf(match.ToLower()) == -1)

{

return false;

}

}

return true;

}

还有另外一个方法,用来获取输出信息:

internal static void GetErrorMessage(out string userHelpLink, out string outMessage,out string eventLever, ExceptionDetailData.ExceptionDetailRow exceptionDetail )

{

outMessage = "";

if (!exceptionDetail.IsHelpLinkNull())

{

userHelpLink = exceptionDetail.HelpLink.Trim();

}

else

{

userHelpLink = "";

}

eventLever = exceptionDetail.EventLevel;

if (!exceptionDetail.IsOutMessageNull())

{

CustomOutMessageData ds = LogAccess.GetCustomOutMessage();

CustomOutMessageData.CustomOutMessageRow customOutMessage = null;

if (ds.CustomOutMessage.FindByLanguage(Thread.CurrentThread.CurrentUICulture.Name) != null)

{

customOutMessage = ds.CustomOutMessage.FindByLanguage(Thread.CurrentThread.CurrentUICulture.Name);

}

else if (ds.CustomOutMessage.FindByLanguage("Default") != null)

{

customOutMessage = ds.CustomOutMessage.FindByLanguage("Default");

}

if (customOutMessage != null)

{

if (exceptionDetail.EventLevel.ToLower() == EventLevel.Error.ToString().ToLower())

outMessage = customOutMessage.ErrorExceptionMessage +":" + exceptionDetail.OutMessage.Trim() +" " +customOutMessage.ErrorPleaseDoSomethingMessage;

else if (exceptionDetail.EventLevel.ToLower() == EventLevel.FailureAudit.ToString().ToLower())

outMessage = customOutMessage.FailureAuditExceptionMessage +":" + exceptionDetail.OutMessage.Trim() +" " +customOutMessage.FailureAuditPleaseDoSomethingMessage;

else if (exceptionDetail.EventLevel.ToLower() == EventLevel.Information.ToString().ToLower())

outMessage = customOutMessage.InformationExceptionMessage +":" + exceptionDetail.OutMessage.Trim() +" " +customOutMessage.InformationPleaseDoSomethingMessage;

else if (exceptionDetail.EventLevel.ToLower() == EventLevel.SuccessAudit.ToString().ToLower())

outMessage = customOutMessage.SuccessAuditExceptionMessage +":" + exceptionDetail.OutMessage.Trim() +" " +customOutMessage.SuccessAuditPleaseDoSomethingMessage;

else if (exceptionDetail.EventLevel.ToLower() == EventLevel.Warning.ToString().ToLower())

outMessage = customOutMessage.WarningExceptionMessage +":" + exceptionDetail.OutMessage.Trim() +" " +customOutMessage.WarningPleaseDoSomethingMessage;

}

else

{

outMessage = exceptionDetail.OutMessage.Trim();

}

}

}

这里便实现了输出信息的本地化,根据当前语言输出的信息头、友好信息,等等。

现在得到了这些输出信息后,便是要将其记入日志了,下面两个方法便分别向系统日志和XML文件写入日志:

向系统日志写入日志:

private static void PublishToSystemLog(ExceptionLogData.ExceptionLogRow exceptionLog)

{

if (!EventLog.SourceExists(AppConfig.ApplicationName))

{

EventLog.CreateEventSource(AppConfig.ApplicationName,"Storm");

}

EventLog eventLog = new EventLog();

eventLog.Source = AppConfig.ApplicationName;

string message = "";

CustomOutMessageData ds = LogAccess.GetCustomOutMessage();

CustomOutMessageData.CustomOutMessageRow customOutMessage;

if (ds.CustomOutMessage.FindByLanguage(Thread.CurrentThread.CurrentUICulture.Name) != null)

{

customOutMessage = ds.CustomOutMessage.FindByLanguage(Thread.CurrentThread.CurrentUICulture.Name);

}

else if (ds.CustomOutMessage.FindByLanguage("Default") != null)

{

customOutMessage = ds.CustomOutMessage.FindByLanguage("Default");

}

else

{

customOutMessage = null;

}

string eventLever = exceptionLog.EventLevel.ToLower();

EventLogEntryType logType = EventLogEntryType.Error;

if (eventLever == EventLogEntryType.Error.ToString().ToLower())

{

logType = EventLogEntryType.Error;

}

else if (eventLever == EventLogEntryType.FailureAudit.ToString().ToLower())

{

logType = EventLogEntryType.FailureAudit;

}

else if (eventLever == EventLogEntryType.Information.ToString().ToLower())

{

logType = EventLogEntryType.Information;

}

else if (eventLever == EventLogEntryType.SuccessAudit.ToString().ToLower())

{

logType = EventLogEntryType.SuccessAudit;

}

else if (eventLever == EventLogEntryType.Warning.ToString().ToLower())

{

logType = EventLogEntryType.Warning;

}

if (customOutMessage != null)

{

message += (customOutMessage.LogTimeHeader + ":" +(exceptionLog.IsLogTimeNull()?"":exceptionLog.LogTime.ToString("yyyy-MM-dd HH:mm:ss")) +"\n");

message += (customOutMessage.ExceptionTypeHeader + ":" + (exceptionLog.IsExceptionTypeNull()?"":exceptionLog.ExceptionType) + "\n");

message += (customOutMessage.ExceptiomOriginalMessageHeader + ":" + (exceptionLog.IsExceptiomOriginalMessageNull()?"":exceptionLog.ExceptiomOriginalMessage) +"\n");

message += (customOutMessage.ExceptionSourceHeader + ":" + (exceptionLog.IsExceptionSourceNull()?"":exceptionLog.ExceptionSource) +"\n");

message += (customOutMessage.ExceptionStackTraceHeader + ":" + (exceptionLog.IsExceptionStackTraceNull()?"":exceptionLog.ExceptionStackTrace) +"\n");

message += (customOutMessage.ExceptionTargetSiteHeader + ":" + (exceptionLog.IsExceptionTargetSiteNull()?"":exceptionLog.ExceptionTargetSite) + "\n");

message += (customOutMessage.ExceptionHelpLinkHeader + ":" + (exceptionLog.IsExceptionHelpLinkNull()?"":exceptionLog.ExceptionHelpLink) +"\n");

message += (customOutMessage.CustomMessageHeader + ":" + (exceptionLog.IsCustomMessageNull()?"":exceptionLog.CustomMessage) +"\n");

message += (customOutMessage.CustomHelpLinkHeader + ":" + (exceptionLog.IsCustomHelpLinkNull()?"":exceptionLog.CustomHelpLink) + "\n");

message += (customOutMessage.UserNameHeader + ":" + (exceptionLog.IsUserNameNull()?"":exceptionLog.UserName) + "\n");

message += (customOutMessage.ExceptionInducedPathHeader + ":" + (exceptionLog.IsExceptionInducedPathNull()?"":exceptionLog.ExceptionInducedPath) +"\n");

}

else

{

message += ("LogTime:" +(exceptionLog.IsLogTimeNull()?"":exceptionLog.LogTime.ToString("yyyy-MM-dd HH:mm:ss")) +"\n");

message += ("ExceptionType:" + (exceptionLog.IsExceptionTypeNull()?"":exceptionLog.ExceptionType) + "\n");

message += ("ExceptiomOriginalMessage:" + (exceptionLog.IsExceptiomOriginalMessageNull()?"":exceptionLog.ExceptiomOriginalMessage) +"\n");

message += ("ExceptionSource:" + (exceptionLog.IsExceptionSourceNull()?"":exceptionLog.ExceptionSource) +"\n");

message += ("ExceptionStackTrace:" + (exceptionLog.IsExceptionStackTraceNull()?"":exceptionLog.ExceptionStackTrace) +"\n");

message += ("ExceptionTargetSite:" + (exceptionLog.IsExceptionTargetSiteNull()?"":exceptionLog.ExceptionTargetSite) + "\n");

message += ("ExceptionHelpLink:" + (exceptionLog.IsExceptionHelpLinkNull()?"":exceptionLog.ExceptionHelpLink) +"\n");

message += ("CustomMessage:" + (exceptionLog.IsCustomMessageNull()?"":exceptionLog.CustomMessage) +"\n");

message += ("CustomHelpLink:" + (exceptionLog.IsCustomHelpLinkNull()?"":exceptionLog.CustomHelpLink) + "\n");

message += ("UserName:" + (exceptionLog.IsUserNameNull()?"":exceptionLog.UserName) + "\n");

message += ("ExceptionInducedPath:" + (exceptionLog.IsExceptionInducedPathNull()?"":exceptionLog.ExceptionInducedPath) +"\n");

}

eventLog.WriteEntry(message,logType);

}

将日志写入XML文件:

private static void PublishToXMLFile(ExceptionLogData.ExceptionLogRow exceptionLog)

{

ExceptionLogData ds = LogAccess.ReadLogFile();

ExceptionLogData.ExceptionLogRow log = ds.ExceptionLog.NewExceptionLogRow();

log.Guid = Guid.NewGuid();

log.EventLevel = exceptionLog.EventLevel;

if (!exceptionLog.IsLogTimeNull())

{

log.LogTime = exceptionLog.LogTime;

}

if (!exceptionLog.IsExceptionTypeNull())

{

log.ExceptionType = exceptionLog.ExceptionType;

}

if (!exceptionLog.IsExceptiomOriginalMessageNull())

{

log.ExceptiomOriginalMessage = exceptionLog.ExceptiomOriginalMessage;

}

if (!exceptionLog.IsExceptionSourceNull())

{

log.ExceptionSource = exceptionLog.ExceptionSource;

}

if (!exceptionLog.IsExceptionStackTraceNull())

{

log.ExceptionStackTrace = exceptionLog.ExceptionStackTrace;

}

if (!exceptionLog.IsExceptionTargetSiteNull())

{

log.ExceptionTargetSite = exceptionLog.ExceptionTargetSite;

}

if (!exceptionLog.IsExceptionHelpLinkNull())

{

log.ExceptionHelpLink = exceptionLog.ExceptionHelpLink;

}

if (!exceptionLog.IsCustomMessageNull())

{

log.CustomMessage = exceptionLog.CustomMessage;

}

if (!exceptionLog.IsUserNameNull())

{

log.UserName = exceptionLog.UserName;

}

if (!exceptionLog.IsExceptionInducedPathNull())

{

log.ExceptionInducedPath = exceptionLog.ExceptionInducedPath;

}

if (!exceptionLog.IsCustomHelpLinkNull())

{

log.CustomHelpLink = exceptionLog.CustomHelpLink;

}

ds.ExceptionLog.AddExceptionLogRow(log);

LogAccess.WriteLogFile(ds);

}

有了以上全部这些东西之后,我们来看看如果将它们组织在一起,当系统发生异常时,调用的便是这个方法:

///

1<summary>
2
3/// 处理异常并返回错误信息 
4
5/// </summary>

///

1<param name="ee"/>

要处理的异常

///

1<returns>错误信息</returns>

public static string PublishException(Exception ee)

{

string outMessage;

string helpLink;

ExceptionLogData ds = new ExceptionLogData();

ExceptionLogData.ExceptionLogRow exceptionLog = ds.ExceptionLog.NewExceptionLogRow();

outMessage = PublishException(out helpLink,ref exceptionLog,ee);

if (ExceptionSetting.ExceptionLogType == CanUseExceptionLogType.XMLFile)

{

PublishToXMLFile(exceptionLog);

}

else if (ExceptionSetting.ExceptionLogType == CanUseExceptionLogType.SystemLog)

{

PublishToSystemLog(exceptionLog);

}

else if (ExceptionSetting.ExceptionLogType == CanUseExceptionLogType.All)

{

PublishToXMLFile(exceptionLog);

PublishToSystemLog(exceptionLog);

}

return outMessage;

}

这样,我们的异常发布器便开发完成了,我们来看看在系统日志中和 XML 文件中会分别是什么样的记录:

最后,您可以将您的异常发布器在项目中使用了,适用的时候要注意,必须要授予 ASPnet 帐户对文章前面提到的三个 XML 文件以写读写的权限。

Published At
Categories with Web编程
Tagged with
comments powered by Disqus