我已经为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 & 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 & 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