Microsoft.Framework.Logging.NLog
使用Nlog擴展日志系統:按照我們上節說的,對于擴展的日志系統都要實現倆個接口ILogger、ILoggerPRovider。所以在當前工程中也沒例外,NLogLoggerProvider實現了ILoggerProvider、內部類Logger實現了ILogger。源代碼如下:
public class NLogLoggerProvider : ILoggerProvider { private readonly LogFactory _logFactory; public NLogLoggerProvider(LogFactory logFactory) { _logFactory = logFactory; } public ILogger CreateLogger(string name) { return new Logger(_logFactory.GetLogger(name)); } private class Logger : ILogger { private readonly global::NLog.Logger _logger; public Logger(global::NLog.Logger logger) { _logger = logger; } public void Log( LogLevel logLevel, int eventId, object state, Exception exception, Func<object, Exception, string> formatter) { var nLogLogLevel = GetLogLevel(logLevel); var message = string.Empty; if (formatter != null) { message = formatter(state, exception); } else { message = LogFormatter.Formatter(state, exception); } if (!string.IsNullOrEmpty(message)) { var eventInfo = LogEventInfo.Create(nLogLogLevel, _logger.Name, message, exception); eventInfo.Properties["EventId"] = eventId; _logger.Log(eventInfo); } } public bool IsEnabled(LogLevel logLevel) { return _logger.IsEnabled(GetLogLevel(logLevel)); } private global::NLog.LogLevel GetLogLevel(LogLevel logLevel) { switch (logLevel) { case LogLevel.Verbose: return global::NLog.LogLevel.Debug; case LogLevel.Information: return global::NLog.LogLevel.Info; case LogLevel.Warning: return global::NLog.LogLevel.Warn; case LogLevel.Error: return global::NLog.LogLevel.Error; case LogLevel.Critical: return global::NLog.LogLevel.Fatal; } return global::NLog.LogLevel.Debug; } public IDisposable BeginScopeImpl([NotNull] object state) { return NestedDiagnosticsContext.Push(state.ToString()); } } }NLog
這段代碼很容易讀懂,也就不過多解釋了,需要注意的一點是:LogFactory是NLog的工廠。下面我們主要就NLog和大名鼎鼎的Log4net進行比較(道聽途說比較多,歡迎指正)
下面是樓主參考的一些博文
測試代碼:
<?xml version="1.0" encoding="utf-8" ?><nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" autoReload="true"> <targets> <target name="logfile" xsi:type="File" fileName="file.txt" layout="${longdate}|${level:uppercase=true}|${logger}|${event-context:item=EventId}|${message}|${ndc}" /> <target name="console" xsi:type="ColoredConsole" layout="[${level:uppercase=true}:${logger}] ${message}"/> </targets> <rules> <logger name="*" minlevel="Info" writeTo="logfile,console" /> </rules></nlog>
public Program() { // a DI based application would get ILoggerFactory injected instead var factory = new LoggerFactory(); // getting the logger immediately using the class's name is conventional _logger = factory.CreateLogger(typeof(Program).FullName); // providers may be added to an ILoggerFactory at any time, existing ILoggers are updated#if !DNXCORE50 factory.AddNLog(new global::NLog.LogFactory());#endif factory.AddConsole(); factory.AddConsole((category, logLevel) => logLevel >= LogLevel.Critical && category.Equals(typeof(Program).FullName)); }
Microsoft.Framework.Logging.Console
實際上用控制臺直接寫日志的并不多,所以這個日志系統可能用途并不廣,不過精煉的代碼還是有很多可圈可點的地方:使用IConsole接口以及LogConsole類。我們一般來說肯定只會實現ILogger、ILoggerProvider倆個接口,也就是寫實現類ConsoleLogger、ConsoleLoggerProvider。但是我們主要到ConsoleLogger只是負責記錄的邏輯操作,具體對于介質的操作屬于IConsole的職責,如果將ConsoleLogger與LogConsole柔和在一起,問題也不大;但是明顯違反了面向對象設計的單一職責原則。所以麻雀雖小,五臟俱全,這幾個小類也能體現面向對象的能力的。
Microsoft.Framework.Logging.TraceSource
這個對于我來說是個陌生的東西,雖然是.net自帶的,并且從1.0就有了。最開始使用的時Debug和Trace進行跟蹤、記錄,到.net2.0時,使用TraceSource作為Debug和Trace的增強版本。
TraceSource的配置:
主要參考的文獻:
我們回頭看Microsoft.Framework.Logging.TraceSource代碼,也就一目了然了.
public class TraceSourceLoggerProvider : ILoggerProvider { private readonly SourceSwitch _rootSourceSwitch; private readonly TraceListener _rootTraceListener; private readonly ConcurrentDictionary<string, TraceSource> _sources = new ConcurrentDictionary<string, TraceSource>(StringComparer.OrdinalIgnoreCase); public TraceSourceLoggerProvider([NotNull]SourceSwitch rootSourceSwitch, [NotNull]TraceListener rootTraceListener) { _rootSourceSwitch = rootSourceSwitch; _rootTraceListener = rootTraceListener; } public ILogger CreateLogger(string name) { return new TraceSourceLogger(GetOrAddTraceSource(name)); } private TraceSource GetOrAddTraceSource(string name) { return _sources.GetOrAdd(name, InitializeTraceSource); } private TraceSource InitializeTraceSource(string traceSourceName) { var traceSource = new TraceSource(traceSourceName); string parentSourceName = ParentSourceName(traceSourceName); if (string.IsNullOrEmpty(parentSourceName)) { if (HasDefaultSwitch(traceSource)) { traceSource.Switch = _rootSourceSwitch; } if (_rootTraceListener != null) { traceSource.Listeners.Add(_rootTraceListener); } } else
新聞熱點
疑難解答