转载

NLog详解(二)

Git是个很好的源码管理系统,你可以瞬间切换为任何历史版本。为了更好的解析NLog这个组件,我们将时钟倒拨回2004年。(注意:NLog v0.9 has been released 是在2005-06-09)

架构

首先主体项目的代码结构是这个样子的:

NLog详解(二)

逻辑上是这个样子的:

NLog详解(二)

测试

这个时候,代码还没有很多的test case,处于相当的简单粗暴阶段。

static void Main(string[] args) {  var l = LogManager.GetLogger("Aaa");  var l2 = LogManager.GetLogger("Bbb");  l.Debug("to jest debug");  l.Info("to jest info");  l.Warn("to jest warning");  l2.Debug("to jest debug");  l2.Info("to jest info");  l2.Warn("to jest warning");  l.Error("to jest error");  l.Fatal("to jest fatal");  l2.Error("to jest error");  l2.Fatal("to jest fatal");  .... } 

GetLogger

入口显然还是LogManager的GetLogger。

    public static Logger GetLogger(string name) {     if (ReloadConfigOnNextLog)  ReloadConfig();     lock (typeof(LogManager))     {  object l = _loggerCache[name];  if (l != null)      return (Logger)l;  ArrayList[] appendersByLevel = GetAppendersByLevelForLogger(name, Configuration);  Logger newLogger = new LoggerImpl(name, appendersByLevel);  _loggerCache[name] = newLogger;  return newLogger;     } } 

这里采用经典的hashtable去储存这些logger实例,以name为key。

Configuration

第一步,从appconfig里面取。

lock (typeof(LogManager)) {  if (_configLoaded)   return _config;  if (_config == null)  {   // try to load default configuration   _config = XmlLoggingConfiguration.AppConfig;  } 

第二步,从一些约定的位置去取,这里我把所有的nlog修改成了mlog是为了方便识别变化点。

private static IEnumerable<string> GetCandidateConfigFileNames() {  var currentAppDomain = AppDomain.CurrentDomain;  // mLog.config from application directory  yield return Path.Combine(currentAppDomain.BaseDirectory, "mLog.config");  // Current config file with .config renamed to .nlog  string cf = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;  if (cf != null)  {   yield return Path.ChangeExtension(cf, ".mlog");   // .nlog file based on the non-vshost version of the current config file   const string vshostSubStr = ".vshost.";   if (cf.Contains(vshostSubStr))   {    yield return Path.ChangeExtension(cf.Replace(vshostSubStr, "."), ".mlog");   }  } } 

顺序总结下来,如下图所示:

NLog详解(二)

拿到配置后,这里使用XmlLoggingConfiguration来读取xml格式的配置。

public class XmlLoggingConfiguration : LoggingConfiguration

最后,如果成功的取到了配置,将会实时监控改配置文件的变化

if (_config != null)     {         _watcher.Watch(_config.FileNamesToWatch);     }

当配置改变时候触发标志位的变化:

private static void ConfigFileChanged(object sender, EventArgs args) {     // Console.WriteLine("ConfigFileChanged!!!");     ReloadConfigOnNextLog = true; }

在每一次write之前,会依据该标志位的变化重载配置文件。

private void WriteToAppenders(LogLevel level, ArrayList appenders, IFormatProvider formatProvider, string message, object[] args) {         if (LogManager.ReloadConfigOnNextLog)             LogManager.ReloadConfig();

这个就是所谓的配置文件修改后立即热刷新的实现,我们在写自己的组件的时候可以参考下。

つづく

正文到此结束
Loading...