我们将版本向前切换到20051025,这期的关注点是filter。我们在使用日志的时候可能希望加上一些过滤器,在满足某些特定条件的时候才输出。举个简单的使用方式如下:

<nlog>
<targets><target name='debug' type='Debug' layout='${basedir} ${message}' /></targets>
<rules>
<logger name='*' minlevel='Debug' appendTo='debug'>
<filters>
<whenContains layout='${message}' substring='zzz' action='Ignore' />
</filters>
</logger>
</rules>
</nlog>

初始化

FilterFactory负责初始化程序集中的Filter

public sealed class FilterFactory
{
private static TypeDictionary _filters = new TypeDictionary(); static FilterFactory()
{
foreach (Assembly a in ExtensionUtils.GetExtensionAssemblies())
{
AddFiltersFromAssembly(a, "");
}
}

反射初始化的方式和上篇的LayoutRender没有差别

    public static void AddFiltersFromAssembly(Assembly theAssembly, string prefix)
{
try
{
InternalLogger.Debug("AddFiltersFromAssembly('{0}')", theAssembly.FullName);
foreach (Type t in theAssembly.GetTypes())
{
FilterAttribute[]attributes = (FilterAttribute[])t.GetCustomAttributes(typeof(FilterAttribute), false);
if (attributes != null)
{
foreach (FilterAttribute attr in attributes)
{
AddFilter(prefix + attr.Name, t);
}
}
}
}
catch (Exception ex)
{
InternalLogger.Error("Failed to add filters from '" + theAssembly.FullName + "': {0}", ex);
} }

加载配置文件中的Filter

只是简单的从初始化好的_filters字典里面取出即可,如果发现没有,就会尝试反射创建

执行

还是在LoggerImplWrite方法中以链式的方式嵌入

for (TargetWithFilterChain awf = targets; awf != null; awf = awf.Next)
{
Target app = awf.Target; try
{
FilterCollection filterChain = awf.FilterChain;
FilterResult result = FilterResult.Neutral; for (int i = 0; i < filterChain.Count; ++i)
{
Filter f = filterChain[i];
result = f.Check(logMessage);
if (result != FilterResult.Neutral)
break;
}
if (result == FilterResult.Ignore)
{
if (InternalLogger.IsDebugEnabled)
{
InternalLogger.Debug("{0}.{1} Rejecting message because of a filter.", logger.Name, level);
}
continue;
}
}

这里可以看到,如果filter 的result 是Ignore,该Message的Target就不需要再输出了。

TargetWithFilterChain 是包装Target的关键类型:

internal class TargetWithFilterChain
{
private Target _target;
private FilterCollection _filterChain;
private TargetWithFilterChain _next; public TargetWithFilterChain(Target a, FilterCollection filterChain)
{
_target = a;
_filterChain = filterChain;
}

这个类型的实现很简单,就是将Target和FilterChain打包放在一起。

InternalLogger

这里值得注意的细节是InternalLogger记录了内部一些详情,当我们需要的时候直接开启InternalLogger调试日志组件的工作过程。

我们对于InternalLogger的要求是不要影响正常程序的运行过程,仅仅在调试日志组件功能的时候使用,因此里面的代码牺牲异常也保证安全。

static InternalLogger()
{
try
{
switch (ConfigurationSettings.AppSettings["nlog.internalLogToConsole"].ToLower())
{
case "false":
LogToConsole = false;
break; case "true":
LogToConsole = true;
break; default:
if (EnvironmentHelper.GetSafeEnvironmentVariable("NLOG_INTERNAL_LOG_TO_CONSOLE") != null)
{
LogToConsole = true;
}
break;
}
string levelString = ConfigurationSettings.AppSettings["nlog.internalLogLevel"];
if (levelString == null || levelString.Length == 0)
levelString = EnvironmentHelper.GetSafeEnvironmentVariable("NLOG_INTERNAL_LOG_LEVEL");
if (levelString != null && levelString.Length > 0)
LogLevel = LogLevel.FromString(EnvironmentHelper.GetSafeEnvironmentVariable("NLOG_INTERNAL_LOG_LEVEL")); LogFile = ConfigurationSettings.AppSettings["nlog.internalLogFile"];
if (LogFile == null)
LogFile = EnvironmentHelper.GetSafeEnvironmentVariable("NLOG_INTERNAL_LOG_FILE");
Info("NLog internal logger initialized.");
}
catch {}
}

可以看到InternalLogger的开启不依赖于原来的配置文件结构,默认不输出,以及取环境变量处理的也非常小心。

public static string GetSafeEnvironmentVariable(string name)
{
try
{
string s = Environment.GetEnvironmentVariable(name);
if (s == "")
return null;
else
return s;
}
catch (SecurityException)
{
return "";
}
}

.NET NLog 详解(四) - filter的更多相关文章

  1. logback -- 配置详解 -- 四 -- <filter>

    附: logback.xml实例 logback -- 配置详解 -- 一 -- <configuration>及子节点 logback -- 配置详解 -- 二 -- <appen ...

  2. iptables详解之filter

    iptables详解之filter iptables令很多小伙伴脑阔疼,下面我们来说说如何使用iptables. 一.iptables格式 1.1.iptables 帮助 通过iptables --h ...

  3. .NET DLL 保护措施详解(四)各操作系统运行情况

    我准备了WEB应用程序及WinForm应用程序,分别在WIN SERVER 2012/2008/2003.Win7/10上实测,以下为实测结果截图: 2012 2008 2003 WIN7 WIN10 ...

  4. pika详解(四) channel 通道

    pika详解(四) channel 通道   本文链接:https://blog.csdn.net/comprel/article/details/94662394 版权 ​ channel通道 通道 ...

  5. logback配置详解3<filter>

    logback 常用配置详解(三) <filter> <filter>: 过滤器,执行一个过滤器会有返回个枚举值,即DENY,NEUTRAL,ACCEPT其中之一.返回DENY ...

  6. View绘制详解(四),谝一谝layout过程

    上篇博客我们介绍了View的测量过程,这只是View显示过程的第一步,第二步就是layout了,这个我们一般译作布局,其实就是在View测量完成之后根据View的大小,将其一个一个摆放在ViewGro ...

  7. Servlet和Filter的url匹配以及url-pattern详解 及 filter 循环问题的解决

    Servlet和filter是J2EE开发中常用的技术,使用方便,配置简单,老少皆宜.估计大多数朋友都是直接配置用,也没有关心过具体的细节,今天遇到一个问题,上网查了servlet的规范才发现,ser ...

  8. 详解Kalman Filter

    中心思想 现有: 已知上一刻状态,预测下一刻状态的方法,能得到一个"预测值".(当然这个估计值是有误差的) 某种测量方法,可以测量出系统状态的"测量值".(当然 ...

  9. C++11 并发指南六(atomic 类型详解四 C 风格原子操作介绍)

    前面三篇文章<C++11 并发指南六(atomic 类型详解一 atomic_flag 介绍)>.<C++11 并发指南六( <atomic> 类型详解二 std::at ...

随机推荐

  1. JVM(java 虚拟机)内存设置

    一.设置JVM内存设置 1. 设置JVM内存的参数有四个: -Xmx   Java Heap最大值,默认值为物理内存的1/4,最佳设值应该视物理内存大小及计算机内其他内存开销而定: -Xms   Ja ...

  2. spring和hibernate整合时无法自动建表

    在使用spring整合hibernate时候代码如下: <property name="dataSource" ref="dataSource" /> ...

  3. centos 6.5 u盘 安装问题 :vesamenu.c32: Not a COM32R image

    大致可以参考这里:http://www.computerandyou.net/2012/03/how-to-solve-vesamenu-c32-not-a-com32r-image-error-in ...

  4. 查看Android应用包名package和入口activity名称

    使用android自动化测试工具启动应用时,需要填写被测程序的包名和启动的Activity,以下有两种查看应用包名package和入口activity名称的方法: 方法一:使用aapt    //aa ...

  5. ACM/ICPC 之 昂贵的聘礼-最短路解法(POJ1062)

    //转移为最短路问题,枚举必经每一个不小于酋长等级的人的最短路 //Time:16Ms Memory:208K #include<iostream> #include<cstring ...

  6. Java for LeetCode 219 Contains Duplicate II

    Given an array of integers and an integer k, find out whether there there are two distinct indices i ...

  7. hiho一下第一周 最长回文子串

    题目链接:http://hihocoder.com/contest/hiho1/problem/1 #include <iostream> #include <cstdio> ...

  8. C#字符串的四舍五入

    Round(Decimal) Round(Double) Round(Decimal, Int32) Round(Decimal, MidpointRounding) Round(Double, In ...

  9. Hadoop 分布式文件系统:架构和设计

    引言 Hadoop分布式文件系统(HDFS)被设计成适合运行在通用硬件(commodity hardware)上的分布式文件系统.它和现有的分布式文件系统有很多共同点.但同时,它和其他的分布式文件系统 ...

  10. 【编程题目】一个整数数组,长度为 n,将其分为 m 份,使各份的和相等,求 m 的最大值★★ (自己没有做出来!!)

    45.雅虎(运算.矩阵): 2.一个整数数组,长度为 n,将其分为 m 份,使各份的和相等,求 m 的最大值 比如{3,2,4,3,6} 可以分成 {3,2,4,3,6} m=1; {3,6}{2,4 ...