在开发应用程序时,日志记录是一个重要的功能,它可以帮助开发者追踪错误、监控应用行为以及分析用户行为。对于Silverlight应用,实现一个有效的服务器端日志记录机制尤其重要,因为它可以集中管理日志,并且不会影响客户端的性能。本文将展示如何使用NLog2.0来实现这一机制。
在日志记录领域,NLog和Log4Net是两个非常流行的平台。NLog 2.0的发布专注于为新平台(如Silverlight、.NET Framework 4、Windows Phone 7.x)提供支持,改进日志架构和管理性,并解决用户最常报告的问题。它完全支持异步操作,因此对于Silverlight应用来说,NLog是最佳选择。
在Silverlight应用中,可以选择客户端日志记录或服务器端日志记录。客户端日志记录会降低性能,并且无法在集中的地方查看日志。因此,服务器端日志记录是一个更优的选择。
为了实现这个应用,将使用以下技术:
首先,创建一个新的Silverlight业务应用,并将其命名为‘BusinessAppMVVM’。
接下来,将在Web项目中添加NLog.Config文件。将以下代码复制/粘贴到NLog.Config中。这里不会深入讨论配置的不同部分,详细信息可以在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="file" xsi:type="AsyncWrapper" queueLimit="5000" overflowAction="Discard">
<target xsi:type="File" fileName="${basedir}/logs/${level}.txt" layout="${longdate} ${logger} ${message}" archiveFileName="${basedir}/logs/archives/${level}.{#####}.txt" archiveAboveSize="10240" archiveNumbering="Sequence" concurrentWrites="true" keepFileOpen="false" encoding="iso-8859-2" />
</target>
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="file" />
</rules>
</nlog>
在配置中,设置了异步日志记录和日志归档。
以下是配置文件中各个标签的简要说明:
在web.config文件中添加以下appSettings,以启用/禁用日志记录。
<appSettings>
<add key="IsEventLogOn" value="true" />
</appSettings>
接下来,将添加一个空的RIA服务‘LoggingService.cs’到Web项目中,并在WCF RIA服务中编写以下方法。
using NLog;
// Add in namespace section
private static readonly Logger Logger = LogManager.GetLogger("LoggingService");
[Invoke]
public string GetLogONOFFFlag()
{
string flag = ConfigurationManager.AppSettings.Get("IsEventLogOn");
return flag;
}
protected override void OnError(DomainServiceErrorInfo errorInfo)
{
// Log exception errorInfo.Error
LogException("Error in BriteDomainService RIA Service. ", errorInfo.ToString());
base.OnError(errorInfo);
}
[Invoke]
public void LogException(string errorCommentOrType, string Detail)
{
string errorMessage = String.Empty;
string strUser = string.Empty;
try
{
if (this.ServiceContext.User != null)
if (this.ServiceContext.User.Identity != null)
strUser = this.ServiceContext.User.Identity.Name;
Detail = "[UserName: " + strUser + "] Time: " + DateTime.Now.ToString() + " " + Detail;
}
catch (Exception ex)
{
Logger.Error("Logging Error: " + ex);
}
finally
{
errorMessage = errorCommentOrType + "- " + Detail;
switch (errorCommentOrType)
{
case "Fatal":
Logger.Fatal(errorMessage);
break;
case "Error":
Logger.Error(errorMessage);
break;
case "Warn":
Logger.Warn(errorMessage);
break;
case "Info":
Logger.Info(errorMessage);
break;
case "Debug":
Logger.Debug(errorMessage);
break;
case "Trace":
Logger.Trace(errorMessage);
break;
default:
Logger.Error(errorMessage);
break;
}
}
}
在‘app.xaml.cs’中声明‘IsEventLogOn’属性。这个属性将用于存储日志记录是否开启。
public bool IsEventLogOn { get; set; }
编写以下代码,以便在‘Application_UserLoaded’中调用RIA服务获取‘IsEventLogOn’值。
var context = new BusinessAppMVVM.Web.Services.LoggingContext();
context.GetLogONOFFFlag(GetLogONOFFFlagCompleted, null);
定义‘GetLogONOFFFlagCompleted’方法如下:
private void GetLogONOFFFlagCompleted(InvokeOperation args)
{
try
{
bool b = false;
bool.TryParse(args.Value, out b);
IsEventLogOn = b;
}
catch (Exception ex)
{
// Handle exception
}
}
在‘Helpers’文件夹中添加‘LoggerManager’类文件。这个类将用于将错误发送到日志服务。代码如下:
public class LoggerManager
{
/// <summary>
/// Writing the Error and Activity logs in the log files.
/// </summary>
/// <param name="errorCommentOrType">Error Comment or Error Type or in case of event enter Event Name</param>
/// <param name="errorDetails">Error Details</param>
/// <returns>bool</returns>
public static bool WriteLog(string errorCommentOrType, string errorDetails)
{
try
{
MessageBox.Show("Some error is occured in application. Please try again after refresh. " + errorDetails);
if (((App)Application.Current).IsEventLogOn)
{
LoggingContext logErrorServiceClient = new LoggingContext();
logErrorServiceClient.LogException(errorCommentOrType, errorDetails, invokeOperation =>
{
if (invokeOperation.HasError)
{
MessageBox.Show("Some error is occurred while error logging!");
}
else MessageBox.Show(@"Error is logged in BusinessAppMVVM\BusinessAppMVVM.Web\logs\.");
}, null);
}
return true;
}
catch (Exception ex)
{
return false;
}
}
}
定义日志类型枚举:
public enum LogType
{
DEBUG,
ERROR,
FATAL,
INFO,
WARN
}
在‘Home.xaml’中添加按钮控件。在按钮点击事件中编写以下代码:
private void button1_Click(object sender, System.Windows.RoutedEventArgs e)
{
try
{
// Manually generating error to test error logging
throw new Exception();
}
catch (Exception ex)
{
LoggerManager.WriteLog(LogType.ERROR.ToString(), ex.ToString());
}
}