以前曾经有同事问我,如何使用直接使用Enterprise Library Logging Application Block,而不需要写任何配置文件。我的回答是可以的。是的,今天让我们实现下。
我们知道能常EntLib需要读取config中配置节信息,那我们可以在Code里传送相应的信息给它,看以下的代码:
public class LoggingConfigurationSource : IConfigurationSource
{
#region Public Methods
public void Add(IConfigurationParameter saveParameter, string sectionName, ConfigurationSection configurationSection)
{
}
public void AddSectionChangeHandler(string sectionName, ConfigurationChangedEventHandler handler)
{
}
public ConfigurationSection GetSection(string sectionName)
{
if (sectionName.Equals("loggingConfiguration", StringComparison.CurrentCulture))
{
// Logging configuration
var loggingSettings = new LoggingSettings();
loggingSettings.DefaultCategory = "General";
loggingSettings.TracingEnabled = true;
loggingSettings.LogWarningWhenNoCategoriesMatch = true;
// Listners
var listenerReference = new TraceListenerReferenceData();
listenerReference.Name = "RollingFiletLogListener";
var rollingFlatFileTraceListenerData = new RollingFlatFileTraceListenerData();
rollingFlatFileTraceListenerData.FileName = "mylog.txt";
rollingFlatFileTraceListenerData.RollSizeKB = 1024;
rollingFlatFileTraceListenerData.RollInterval = RollInterval.Day;
rollingFlatFileTraceListenerData.RollFileExistsBehavior = RollFileExistsBehavior.Increment;
rollingFlatFileTraceListenerData.Type = typeof (RollingFlatFileTraceListener);
rollingFlatFileTraceListenerData.ListenerDataType = typeof (RollingFlatFileTraceListenerData);
rollingFlatFileTraceListenerData.Filter = SourceLevels.All;
rollingFlatFileTraceListenerData.TraceOutputOptions = TraceOptions.None;
rollingFlatFileTraceListenerData.Name = "RollingFiletLogListener";
rollingFlatFileTraceListenerData.Header = "---------------Header---------------";
rollingFlatFileTraceListenerData.Footer = "-----------------Footer----------------";
loggingSettings.TraceListeners.Add(rollingFlatFileTraceListenerData);
// Formatters
var template = new StringBuilder();
template.AppendLine("Timestamp: {timestamp}");
template.AppendLine("Message: {message}");
template.AppendLine("Category: {category}");
template.AppendLine("Priority: {priority}");
template.AppendLine("EventId: {eventid}");
template.AppendLine("Severity: {severity}");
template.AppendLine("Title:{title}");
template.AppendLine("Machine: {machine}");
template.AppendLine("Application Domain: {appDomain}");
template.AppendLine("Process {processId}");
template.AppendLine("Process Name: {processName}");
template.AppendLine("Win32 Thread {win32ThreadId}");
template.AppendLine("Thread Name: {threadName}");
template.AppendLine("Extended Properties: {dictionary({key} - {value})}");
var formatter = new TextFormatterData();
formatter.Name = "TextFormatter";
formatter.Type = typeof (TextFormatter);
formatter.Template = template.ToString();
loggingSettings.Formatters.Add(formatter);
// Category Sources
var exceptionsSource = new TraceSourceData();
exceptionsSource.TraceListeners.Add(listenerReference);
exceptionsSource.Name = "Exceptions";
exceptionsSource.DefaultLevel = SourceLevels.All;
loggingSettings.TraceSources.Add(exceptionsSource);
var traceSource = new TraceSourceData();
traceSource.TraceListeners.Add(listenerReference);
traceSource.Name = "Trace";
traceSource.DefaultLevel = SourceLevels.All;
loggingSettings.TraceSources.Add(traceSource);
var generalSource = new TraceSourceData();
generalSource.TraceListeners.Add(listenerReference);
generalSource.Name = "General";
generalSource.DefaultLevel = SourceLevels.All;
loggingSettings.TraceSources.Add(generalSource);
// Special Sources
loggingSettings.SpecialTraceSources.AllEventsTraceSource.Name = "AllEvents";
loggingSettings.SpecialTraceSources.AllEventsTraceSource.DefaultLevel = SourceLevels.All;
loggingSettings.SpecialTraceSources.NotProcessedTraceSource.Name = "NotProcessed";
loggingSettings.SpecialTraceSources.NotProcessedTraceSource.DefaultLevel = SourceLevels.All;
loggingSettings.SpecialTraceSources.ErrorsTraceSource.Name = "LoggingErrorsAndWarnings";
loggingSettings.SpecialTraceSources.ErrorsTraceSource.DefaultLevel = SourceLevels.All;
loggingSettings.SpecialTraceSources.ErrorsTraceSource.TraceListeners.Clear();
loggingSettings.SpecialTraceSources.ErrorsTraceSource.TraceListeners.Add(listenerReference);
// Return
return loggingSettings;
}
return null;
}
public void Remove(IConfigurationParameter removeParameter, string sectionName)
{
}
public void RemoveSectionChangeHandler(string sectionName, ConfigurationChangedEventHandler handler)
{
}
#endregion
}
注意,这里我们配置是使用RollingFlatFileTraceListener,也就是写磁盘文件Logfile.你可以替换其它的Listener.从上面的Code,我们可以看出,config配置节也就是写着这些信息。
接下来建立一个Class来调用它:
public static class LoggingHandler
{
#region Constants
private readonly static string CategoryExceptions = "Exceptions";
private readonly static int PriorityExceptions = 1000;
private readonly static int EventIdExceptions = 1000;
private readonly static string TitleExceptions = "Errors Log";
private readonly static TraceEventType SeverityExceptions = TraceEventType.Error;
#endregion
#region Members
private static LogWriter writer;
#endregion
#region Properties
internal static LogWriter Writer
{
get
{
if (writer == null)
{
writer = CreateWriter();
}
return writer;
}
}
#endregion
#region Public Methods
public static void Exception(Exception ex)
{
// Validation
if (ex == null)
{
throw new ArgumentNullException();
}
// Log
WriteEntry(CategoryExceptions, TitleExceptions, ex.ToString(), PriorityExceptions, EventIdExceptions,
SeverityExceptions);
}
#endregion
#region Private Methods
private static void WriteEntry(string category, string title, string message, int priority, int eventId,
TraceEventType severity)
{
var entry = new LogEntry();
entry.Categories.Add(category);
entry.TimeStamp = DateTime.Now;
entry.EventId = eventId;
entry.Message = message;
entry.Priority = priority;
entry.Severity = severity;
entry.Title = title;
Writer.Write(entry);
}
private static LogWriter CreateWriter()
{
var factory = new LogWriterFactory(new LoggingConfigurationSource());
return factory.Create();
}
#endregion
}
使用:
[TestFixture]
public class TestNonConfigEntLibLogger
{
[Test]
public void TestWrite()
{
var log = new LogEntry() { Message = "This a test message", Title = "logging title" };
LoggingHandler.Writer.Write(log);
LoggingHandler.Exception(new Exception("This is a test exception"));
string path = Path.Combine(Environment.CurrentDirectory + "\\mylog.txt");
Assert.IsNotNull(path);
}
}
在mylog.txt文件中,我们看到以下内容:
---------------Header---------------
General Information: 0 : Timestamp: 9/24/2010 4:02:40 AM
Message: This a test message
Category: General
Priority: -1
EventId: 0
Severity: Information
Title:logging title
App Domain: domain-nunit.tdnet.dll
ProcessId: 5400
Process Name: D:\Program Files (x86)\TestDriven.NET 3\ProcessInvocation86.exe
Thread Name: TestRunnerThread
Win32 ThreadId:4636
Extended Properties:
-----------------Footer----------------
---------------Header---------------
Exceptions Error: 1000 : Timestamp: 9/24/2010 12:02:40 PM
Message: System.Exception: This is a test exception
Category: Exceptions
Priority: 1000
EventId: 1000
Severity: Error
Title:Errors Log
App Domain: domain-nunit.tdnet.dll
ProcessId: 5400
Process Name: D:\Program Files (x86)\TestDriven.NET 3\ProcessInvocation86.exe
Thread Name: TestRunnerThread
Win32 ThreadId:4636
Extended Properties:
-----------------Footer----------------
实际上做为EntLib,并不用推荐这么使用,因为这样做损失了很多优势了。我们的测试所用的Version是EntLib 4.1。希望对您开发有帮助。
作者:Petter Liu
出处:http://www.cnblogs.com/wintersun/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
该文章也同时发布在我的独立博客中-Petter Liu Blog。