.NET NLog 详解(二)
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();
这个就是所谓的配置文件修改后立即热刷新的实现,我们在写自己的组件的时候可以参考下。
つづく
.NET NLog 详解(二)的更多相关文章
- .NET DLL 保护措施详解(二)关于性能的测试
先说结果: 加了缓存的结果与C#原生代码差异不大了 我对三种方式进行了测试: 第一种,每次调用均动态编译 第二种,缓存编译好的对象 第三种,直接调用原生C#代码 .net dll保护系列 ------ ...
- PopUpWindow使用详解(二)——进阶及答疑
相关文章:1.<PopUpWindow使用详解(一)——基本使用>2.<PopUpWindow使用详解(二)——进阶及答疑> 上篇为大家基本讲述了有关PopupWindow ...
- Android 布局学习之——Layout(布局)详解二(常见布局和布局参数)
[Android布局学习系列] 1.Android 布局学习之——Layout(布局)详解一 2.Android 布局学习之——Layout(布局)详解二(常见布局和布局参数) 3.And ...
- logback -- 配置详解 -- 二 -- <appender>
附: logback.xml实例 logback -- 配置详解 -- 一 -- <configuration>及子节点 logback -- 配置详解 -- 二 -- <appen ...
- 爬虫入门之urllib库详解(二)
爬虫入门之urllib库详解(二) 1 urllib模块 urllib模块是一个运用于URL的包 urllib.request用于访问和读取URLS urllib.error包括了所有urllib.r ...
- [转]文件IO详解(二)---文件描述符(fd)和inode号的关系
原文:https://www.cnblogs.com/frank-yxs/p/5925563.html 文件IO详解(二)---文件描述符(fd)和inode号的关系 ---------------- ...
- Android View 的绘制流程之 Layout 和 Draw 过程详解 (二)
View 的绘制系列文章: Android View 的绘制流程之 Measure 过程详解 (一) Android View 绘制流程之 DecorView 与 ViewRootImpl 在上一篇 ...
- HTTPS详解二:SSL / TLS 工作原理和详细握手过程
HTTPS 详解一:附带最精美详尽的 HTTPS 原理图 HTTPS详解二:SSL / TLS 工作原理和详细握手过程 在上篇文章HTTPS详解一中,我已经为大家介绍了 HTTPS 的详细原理和通信流 ...
- Linux dts 设备树详解(二) 动手编写设备树dts
Linux dts 设备树详解(一) 基础知识 Linux dts 设备树详解(二) 动手编写设备树dts 文章目录 前言 硬件结构 设备树dts文件 前言 在简单了解概念之后,我们可以开始尝试写一个 ...
随机推荐
- Navicat for MySQL的使用
一. 在Navicat for MySQL软件中,如何打开MySQL命令行界面: 图 (1) 如何调出MySQL命令行界面 如图(1)所示,在左侧空白处,右键单击即可调出“命令列介面” 注意,输入My ...
- Java总结(一):封装——Encapsulation
官方定义:一种将抽象性函式接口的实作细节部份包装.隐藏起来的方法.封装可以被认为是一个保护屏障,防止该类的代码和数 据被外部类定义的代码随机访问. 大白话定义:通过getter和setter方法访问私 ...
- wxPython中文教程入门实例
这篇文章主要为大家分享下python编程中有关wxPython的中文教程,分享一些wxPython入门实例,有需要的朋友参考下 wxPython中文教程入门实例 wx.Window 是一个基类 ...
- 使用Java中File类批量创建文件和批量修改文件名
批量创建文件 int cont = 1; String s = "E:\\学习资料\\Java笔记-"; while(cont<100){ File f = new File ...
- ios 获得设备型号方法
以前用UIScreen 的大小来判断设备类型,现在有了iphone6 和 iphone6 plus, 这种方法不能用了.因为当程序不提供相应的启动图片时,系统会把程序运行在320*568的size下, ...
- java Thread和Runnable区别
①Thread类实现了Runnable接口,主要构造方法为Thread(Runnable target).Thread(Runnable target,String name).Thread(Stri ...
- Java for LeetCode 206 Reverse Linked List
Reverse a singly linked list. 解题思路: 用Stack实现,JAVA实现如下: public ListNode reverseList(ListNode head) { ...
- Effective C++ -----条款23:宁以non-member、non-friend替换member函数
宁可拿non-member non-friend函数替换member函数.这样做可以增加封装性.包裹弹性(packaging flexibility)和机能扩充性.
- codeforces 495A. Digital Counter 解题报告
题目链接:http://codeforces.com/problemset/problem/495/A 这个题目意思好绕好绕~~好绕~~~~~,昨天早上做得 virtual 看不懂,晚上继续看还是,差 ...
- H5 前端页面适配响应式
辞职有半个月了,面试了几家公司,还在挣扎中.... 不废话,H5页面适配成响应式,可以用百分比或者rem. rem是相对于html根元素的单位,可以根据根元素的大小做出等比缩放, 通常,假如设置,ht ...