如何在EntLib日志应用程序块中为跟踪侦听器设置和使用多个格式化程序



我已经为WinForms应用程序配置了EntLib 5日志应用程序块。

日志配置如下:

<loggingConfiguration name="Logging Application Block" tracingEnabled="true" defaultCategory="Developer" logWarningsWhenNoCategoriesMatch="true">
    <listeners>
      <add listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.CustomTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" traceOutputOptions="None" filter="All" type="DataSynchronizationManager.CustomStatusTraceListener, DataSynchronizationManager, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Custom Trace Listener" initializeData="" />
      <add fileName="trace.log" header="" footer="" formatter="Text Formatter" listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.FlatFileTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" traceOutputOptions="DateTime" filter="Information" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.FlatFileTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" name="InformationListener" />
    </listeners>
    <formatters>
      <add template="[ {timestamp} ]    Machine: {machine}  Message: {message}" type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" name="Text Formatter" />
    </formatters>
    <logFilters>
      <add categoryFilterMode="AllowAllExceptDenied" type="Microsoft.Practices.EnterpriseLibrary.Logging.Filters.CategoryFilter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" name="Category Filter" />
    </logFilters>
    <categorySources>
      <add switchValue="Information" name="Developer">
        <listeners>
          <add name="Custom Trace Listener" />
          <add name="InformationListener" />
        </listeners>
      </add>
      <add switchValue="Information" name="User">
        <listeners>
          <add name="Custom Trace Listener" />
          <add name="InformationListener" />
        </listeners>
      </add>
    </categorySources>
    <specialSources>
      <allEvents switchValue="All" name="All Events" />
      <notProcessed switchValue="All" name="Unprocessed Category" />
      <errors switchValue="All" name="Logging Errors &amp; Warnings" />
    </specialSources>
  </loggingConfiguration>

我想要的是日志中的某种格式。当前日志只是一堆从开始到结束的行,如下所示:

[ 04-06-2013 08:54:20 ]    Machine: ABC  Message: sjfdj ajlfkdjlf ajflkdjf ajfkljadlk jlkafjlkds
[ 04-06-2013 14:24:20 ]    Machine: ABC  Message: iweurtweu mcxvnmcxnvmx dksjflkdjf eowiruoei
[ 04-06-2013 14:24:20 ]    Machine: ABC  Message: 
[ 04-06-2013 08:54:20 ]    Machine: ABC  Message: sjfdj ajlfkdjlf ajflkdjf ajfkljadlk jlkafjlkds
[ 04-06-2013 14:24:20 ]    Machine: ABC  Message: iweurtweu mcxvnmcxnvmx dksjflkdjf eowiruoei
[ 04-06-2013 14:24:20 ]    Machine: ABC  Message: 

所以代替第3和第6行写时间戳,机器和消息,我想有一个空行,像这样:

[ 04-06-2013 08:54:20 ]    Machine: ABC  Message: sjfdj ajlfkdjlf ajflkdjf ajfkljadlk jlkafjlkds
[ 04-06-2013 14:24:20 ]    Machine: ABC  Message: iweurtweu mcxvnmcxnvmx dksjflkdjf eowiruoei
[ 04-06-2013 08:54:20 ]    Machine: ABC  Message: sjfdj ajlfkdjlf ajflkdjf ajfkljadlk jlkafjlkds
[ 04-06-2013 14:24:20 ]    Machine: ABC  Message: iweurtweu mcxvnmcxnvmx dksjflkdjf eowiruoei

我想要的只是在需要的地方放一个空行。目前,由于格式化程序的关系,即使是空行,EntLib也会写入时间戳和机器名。

在日志中放一个空行应该怎么做?

一个跟踪侦听器只能有一个格式化器,并且只有一个跟踪侦听器可以写入一个文件,所以同一个跟踪侦听器不能有多个格式化器。

我理解你的问题,你想记录一定数量的LogEntry's,在一定数量之后,你想在日志文件中放一个新的行。

如果是这种情况,那么应用程序需要跟踪何时写入空行。最简单的方法是在message属性(格式化程序中的最后一个属性)中添加新行来强制换行:

LogEntry logEntry = new LogEntry()
{
    Message = "Test",
    Categories = new string[] { "User" }
};
var logWriter = EnterpriseLibraryContainer.Current.GetInstance<LogWriter>();
logWriter.Write(logEntry);
logWriter.Write(logEntry);
// Force a line break
logEntry.Message += Environment.NewLine;
logWriter.Write(logEntry);
logEntry.Message = "Next Set";
logWriter.Write(logEntry);

这将导致如下输出:

[ 6/13/2013 7:57:59 PM ]    Machine: MACHINE12  Message: Test
[ 6/13/2013 7:57:59 PM ]    Machine: MACHINE12  Message: Test
[ 6/13/2013 7:57:59 PM ]    Machine: MACHINE12  Message: Test
[ 6/13/2013 7:57:59 PM ]    Machine: MACHINE12  Message: Next Set

举例来说,我只重用一个LogEntry,但你几乎总是会为每个Write()调用创建一个新的LogEntry。

现在,如果您不知道要记录的LogEntry是什么(因为日志记录具有基于数据的条件逻辑),那么它就会变得有点混乱。我能想到的唯一方法就是预先格式化Message属性,然后将Message属性写入文件。

要做到这一点,我将创建两个格式化程序:一个格式化日志条目按照您的要求("文本格式化器")和一个简单地写出消息属性("消息文本格式化器")。基本上,您正在将格式化移动到代码中,并且只写出包含已经格式化的消息的Message属性。

你不需要使用Enterprise Library的格式化程序来做这个,但是这个例子可以。此外,由于格式化是在代码中完成的,因此您可以将格式化的消息字符串传递给Write overload方法之一。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" />
  </configSections>
  <loggingConfiguration name="Logging Application Block" tracingEnabled="true"
    defaultCategory="User" logWarningsWhenNoCategoriesMatch="true">
    <listeners>
      <add name="InformationListener" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.FlatFileTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.FlatFileTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        fileName="trace.log" header="" footer="" formatter="Message Text Formatter"
        traceOutputOptions="DateTime" filter="Information" />
    </listeners>
    <formatters>
      <add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        template="[ {timestamp} ]    Machine: {machine}  Message: {message}"
        name="Text Formatter" />
      <add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        template="{message}" name="Message Text Formatter" />
    </formatters>
    <logFilters>
      <add type="Microsoft.Practices.EnterpriseLibrary.Logging.Filters.CategoryFilter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        categoryFilterMode="AllowAllExceptDenied" name="Category Filter" />
    </logFilters>
    <categorySources>
      <add switchValue="All" name="User">
        <listeners>
          <add name="InformationListener" />
        </listeners>
      </add>
    </categorySources>
    <specialSources>
      <allEvents switchValue="All" name="All Events" />
      <notProcessed switchValue="All" name="Unprocessed Category" />
      <errors switchValue="All" name="Logging Errors &amp; Warnings" />
    </specialSources>
  </loggingConfiguration>
</configuration>

然后您可以获得格式化程序,格式化消息,将格式化的消息分配给message属性,然后记录消息。要编写新行,只需将Message属性设置为空字符串:

LogEntry logEntry = new LogEntry()
{
    Message = "Test",
    Categories = new string[] { "User" }
};
// Get the formatter
var formatter = EnterpriseLibraryContainer.Current.GetInstance<ILogFormatter>("Text Formatter");
// Format the message into the desired format and set as Message property
string formattedMessage = formatter.Format(logEntry);
logEntry.Message = formattedMessage;
var logWriter = EnterpriseLibraryContainer.Current.GetInstance<LogWriter>();
// Don't have to use a Log Entry...instead can pass in formatted message 
// string and category...the 3 lines below result in the same output
logWriter.Write(formattedMessage, "User");
logWriter.Write(logEntry);
logWriter.Write(logEntry);
// write new line
logEntry.Message = "";
logWriter.Write(logEntry);
logEntry.Message = "Next Set";
formattedMessage = formatter.Format(logEntry);
logEntry.Message = formattedMessage;
logWriter.Write(logEntry);
logWriter.Write(logEntry);
logWriter.Write(logEntry);
// write new line
logEntry.Message = "";
logWriter.Write(logEntry);

这不是特别优雅,所以您可能希望将此逻辑包装在一些helper/扩展方法后面(即使这样,仅仅获得新行也是相当多的工作)。

输出如下:

[ 6/13/2013 8:13:30 PM ]    Machine: MACHINE12  Message: Test
[ 6/13/2013 8:13:30 PM ]    Machine: MACHINE12  Message: Test
[ 6/13/2013 8:13:30 PM ]    Machine: MACHINE12  Message: Test
[ 6/13/2013 8:13:30 PM ]    Machine: MACHINE12  Message: Next Set
[ 6/13/2013 8:13:30 PM ]    Machine: MACHINE12  Message: Next Set
[ 6/13/2013 8:13:30 PM ]    Machine: MACHINE12  Message: Next Set

最新更新