Enterprise Library2.0(2):Logging Application Block学习

摘要:Logging Application Block可以使开发人员在其应用程序中集成日志监测功能,看看随着2.0的推出给我们带来了哪些改变。
一.改进的地方
1.Logging Application Block首先带来的是名称上的改变,在1.1下它的全称应该是Logging and Instrumentation Application Block,一般把它翻译为日志和检测应用程序块,而2.0下却完全变成了日志应用程序块。
2.在1.1下,每个LogEntry只能被记录到一个Sink,而这种情况在2.0下已经不复存在,对于每个LogEntry对象,我们都可以通过Category指定很多的Sink。回忆一下在1.1时记录一个日志项:
LogEntry logEntry =
new LogEntry();
logEntry.EventId
=
100;
logEntry.Priority
=
2;
logEntry.Message
=
"Informational message";
//只能设置一个
logEntry.Categorys =
"UI Events";

Logger.Write(logEntry);

2.0
下可以添加多次:


LogEntry logEntry =
new LogEntry();
logEntry.EventId
=
100;
logEntry.Priority
=
2;
logEntry.Message
=
"Informational message";
//设置多个Category
logEntry.Categories.Add("Trace");       
logEntry.Categories.Add(
"UI Events");

Logger.Write(logEntry);


3
.可以在代码中查询哪些日志项将被过滤,例如:
LogEntry logEntry =
new LogEntry();
logEntry.Priority
=
2;
logEntry.Categories.Add(
"Trace");
logEntry.Categories.Add(
"UI Events");

if (Logger.ShouldLog(logEntry))

{
 
// Event will be logged according to currently configured filters.
}
else

{
 
// Event will not be logged.
}


4
.配置文件的改变。在1.1下关于Logging & Instrumentation
Application Block的信息记录在loggingconfiguration.config文件中,2.0下所有的信息都放在了Web.config或App.config中,如:






<configuration>
    <configSections>
        <section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging" />
    </configSections>
    <loggingConfiguration tracingEnabled="true" defaultCategory="General">
        <logFilters>
            <add
                name="Category"
                type="Microsoft.Practices.EnterpriseLibrary.Logging.Filters.CategoryFilter, Microsoft.Practices.EnterpriseLibrary.Logging"
                categoryFilterMode="AllowAllExceptDenied">
        <categoryFilters>
          <add name="UI Events" />
        </categoryFilters>
            </add>
            <add
                name="Priority"
                type="Microsoft.Practices.EnterpriseLibrary.Logging.Filters.PriorityFilter, Microsoft.Practices.EnterpriseLibrary.Logging"
                minimumPriority="2"
                    />
      <add name="LogEnabled Filter"
        type="Microsoft.Practices.EnterpriseLibrary.Logging.Filters.LogEnabledFilter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null"
        enabled="true"
          />
    </logFilters>
</loggingConfiguration>
</configuration>


二.记录日志信息

1.添加相关的引用




using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Logging;
using Microsoft.Practices.EnterpriseLibrary.Logging.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Logging.ExtraInformation;
using Microsoft.Practices.EnterpriseLibrary.Logging.Filters;

2.创建一个日志项



LogEntry log = new LogEntry();
log.EventId = 300;
log.Message = "Sample message";
log.Categories.Add("UI Events");
log.Severity = TraceEventType.Information;
log.Priority = 5;

3.调用Logger.Write()方法


Logger.Write(log);




三.记录日志项的扩展属性

使用基于泛型的Dictionary来记录,如下



// Create the dictionary to hold the extra information, and populate it
// with managed security information. 
Dictionary<string, object> dictionary = new Dictionary<string, object>();
ManagedSecurityContextInformationProvider informationHelper = new ManagedSecurityContextInformationProvider();

informationHelper.PopulateDictionary(dictionary);

// Add a custom property for screen resolution
int width = Screen.PrimaryScreen.Bounds.Width;
int height = Screen.PrimaryScreen.Bounds.Height;
string resolution = String.Format("{0}x{1}", width, height);

dictionary.Add("Screen resolution", resolution);

// Write the log entry that contains the extra information
Logger.Write("Log entry with extra information", dictionary);


四.跟踪活动并记录上下文信息

1.调用DoDataAccess方法,完成后释放Trace对象



using (new Tracer("Trace"))
{
    DoDataAccess();
}


2.创建DoDataAccess方法



private void DoDataAccess()
{
    using (new Tracer("Data Access Events"))
    {
        // Peform work here

        // Assume an error condition was detected - perform some troubleshooting.
        DoTroubleShooting();
    }
}


3.创建另一个方法DoTroubleShooting,并在其中创建LogEntry。


private void DoTroubleShooting()
{
    string logMessage = "Simulated troubleshooting message for Logging QuickStart. " +
      "Current activity=\"" + Trace.CorrelationManager.ActivityId + "\"";

    LogEntry logEntry = new LogEntry();

    logEntry.Categories.Clear();
    logEntry.Categories.Add("Troubleshooting");
    logEntry.Priority = 5;
    logEntry.Severity = TraceEventType.Error;
    logEntry.Message = logMessage;

    Logger.Write(logEntry);
}


五.检测日志项是否被记录

创建一个日志项并设置它的信息,调用Logger.ShouldLog()方法

LogEntry logEntry = new LogEntry();
logEntry.Priority = 2;
logEntry.Categories.Add("Trace");
logEntry.Categories.Add("UI Events");

if (Logger.GetFilter<CategoryFilter>().ShouldLog(logEntry))
{
  // Event will be logged according to currently configured filters.
  // Perform operations (possibly expensive) to gather additional information
  // for the event to be logged.
}
else
{
  // Event will not be logged. Your application can avoid the performance
  // penalty of collecting information for an event that will not be
  // logged.
}


LogEntry logEntry = new LogEntry();
logEntry.Priority = 2;
logEntry.Categories.Add("Trace");
logEntry.Categories.Add("UI Events");

if (Logger.ShouldLog(logEntry))
{
  // Event will be logged according to currently configured filters.
}
else
{
  // Event will not be logged.
}


六.创建自定义的Trace Listener

1.添加特性ConfigurationElementType,需要继承自CustomTraceListener



[ConfigurationElementType(typeof(CustomTraceListenerData))]
public class DebugTraceListener : CustomTraceListener
{
    //
}


2.覆写TraceData方法



public override void TraceData(TraceEventCache eventCache, string source, TraceEventType eventType, int id, object data)
{
    if (data is LogEntry && this.Formatter != null)
    {
        this.WriteLine(this.Formatter.Format(data as LogEntry));
    }
    else
    {
        this.WriteLine(data.ToString());
    }
}


3.覆写Write()和WriteLine()方法



/**//// <summary>
/// Writes a message to the debug window
/// </summary>
/// <param name="message">The string to write to the debug window</param>
public override void Write(string message)
{
    Debug.Write(message);
}

/**//// <summary>
/// Writes a message to the debug window
/// </summary>
/// <param name="message">The string to write to the debug window</param>
public override void WriteLine(string message)
{
    Debug.WriteLine(message);
}


七.创建自定义的Formatter

1.在自定义的类上添加特性ConfigurationElementType,并实现接口ILogFormatter



[ConfigurationElementType(typeof(CustomFormatterData))]
public class MyFormatter : ILogFormatter
{
    //
}


2.构造函数接受一个类型为NameValueCollection的参数



public MyFormatter (NameValueCollection attributes)
{
    //
}


3.添加Format方法,它接受一个LogEntry的参数



public string Format(LogEntry log)
{
    //
}



八.使用场景

如果你的应用程序需要挟日志到Event Log, E-mail, Database, Message Queue, Windows Management Instrumentation (WMI), TextFile,你就应该考虑使用日志组件来提供这些功能,特别如果你需要基于分类和优先级来过滤日志消息,需要格式化消息,或者需要不改动代码的情况下改变消息的目的地。日志组件同时被设计成可扩展的,包括方便的创建客户订制的Formatter和TraceListener。



参考资料:Enterprise Libaray –January 2006帮助文档

原文出处:http://www.cnblogs.com/Terrylee/