0

我已经配置了 EntLib 5 日志记录应用程序块来为 WinForms 应用程序创建日志。

日志配置配置如下:

<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 也会因为格式化程序而写入时间戳和机器名称。

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

4

1 回答 1

1

一个跟踪侦听器只能有一个格式化程序,并且只有一个跟踪侦听器可以写入一个文件,因此您不能有多个格式化程序用于同一个跟踪侦听器。

据我了解您的问题,您想要记录一定数量的 LogEntry,并且在一定数量之后,您希望在日志文件中添加一个新行。

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

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 重载方法之一。

<?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);

这并不是特别优雅,因此您可能希望将此逻辑包装在一些帮助程序/扩展方法后面(即使这样,只是为了获得一个新行就需要做很多工作)。

输出如下所示:

[ 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
于 2013-06-13T20:22:33.550 回答