您的位置:首页 > 其它

.NET NLog 详解(二)

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

架构

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



逻辑上是这个样子的:



测试

这个时候,代码还没有很多的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");
}
}
}

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



拿到配置后,这里使用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();

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

つづく
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: