LibLog 类库 分析
前期思考:
Microsoft.Logging 是否可用?
是否需要提供默认的 Logger 实现? 不需要。1,用户自己开启日志功能,设置开启属性,即可打印出相应的日志。
LibLog 类库分析:
类库设计方只需要安装好相应的包,然后在自己的日志类中 添加如下字段。
private static readonly ILog logger = LogProvider.GetCurrentClassLogger()
或者
private static readonly ILog Logger = LogProvider.For<YOUR_CLASS>()
无需安装其他第三方的类库,在记录日志时,只需调用 logger.Info 或者 logger.Error 这时类库的设计就算完成了。当然类库设计方可以提供给客户端一个接口假设为 EnableLogger()
客户端上,用户只需调用这个接口,即可实现类库日志的自动记录,而无需多余操作。
这里面实现的原理是什么,在客户端侧,除了调用类库的一个开启日志功能的接口,其他没有任何操作。
其实可以分析一下我们集成时的类库设计,首先是初始化 Logger 对象
// GetCurrentClassLogger
static ILog GetCurrentClassLogger()
{
var stackFrame = new StackFrame(1, false);
return GetLogger(stackFrame.GetMethod().DeclaringType);
}
获取当前类的日志, 初始化一个 StackFrame,这个应该是 Call Stack 中的Record Frame。下面给出官网上的描述:
A StackFrame is created and pushed on the call stack for every function call made during the execution of a thread.
然后进行 GetLogger()
static ILog GetLogger(string name)
{
var logProvider = CurrentLogProvider ?? ResolveLogProvider();
return logProvider == null
? NoOpLogger.Instance
: (ILog)new LoggerExecutionWrapper(logProvider.GetLogger(name), () => IsDisabled);
}
重点关注 ResolveLogProvider 的这个方法,首先是用到了 Lazy Initialization
private static readonly Lazy ResolvedLogProvider = new Lazy(ForceResolveLogProvider);
然后关注这个 ForceResolveLogProvider,Lazy 方法接收的参数类型为 Func 的委托类型,也就是说,接收一个返回值为 ILogProvider 的方法。
internal static ILogProvider ForceResolveLogProvider()
{
try
{
foreach (var providerResolver in LogProviderResolvers)
{
if (providerResolver.Item1())
{
return providerResolver.Item2();
}
}
}
catch (Exception ex)
{
Console.WriteLine(
"Exception occurred resolving a log provider. Logging for this assembly {0} is disabled. {1}",
typeof(LogProvider).Assembly.FullName,
ex);
}
return null;
}
该方法主要是查找当前进程中是否已经初始化某个日志类了,如果有,则放回这个类。若没有,则抛出异常。重点关注的是 LogProviderResolvers ,这是一个元祖类型 ,定义如下:
static readonly List<Tuple<IsLoggerAvailable, CreateLogProvider>> LogProviderResolvers =
new List<Tuple<IsLoggerAvailable, CreateLogProvider>>
{
new Tuple<IsLoggerAvailable, CreateLogProvider>(SerilogLogProvider.IsLoggerAvailable, () => new SerilogLogProvider()),
new Tuple<IsLoggerAvailable, CreateLogProvider>(NLogLogProvider.IsLoggerAvailable, () => new NLogLogProvider()),
new Tuple<IsLoggerAvailable, CreateLogProvider>(Log4NetLogProvider.IsLoggerAvailable, () => new Log4NetLogProvider()),
new Tuple<IsLoggerAvailable, CreateLogProvider>(LoupeLogProvider.IsLoggerAvailable, () => new LoupeLogProvider()),
};
配置完 Provider 之后,其实类库已经获取到你本地配置的日志类了,当类库中需要打印日志的需求的话,通过反射来找到项目中的日志类,然后初始化来执行相关的操作。
DEMO样例:
类库:https://github.com/doublnt/dotnetcore/blob/master/LibLogSample/CommonLibLog.cs
客户端:https://github.com/doublnt/dotnetcore/blob/master/CSharpFundamental/LibLog/ConsumerLibLog.cs
LibLog 类库 分析的更多相关文章
- WindowsPhone自定义控件详解(二) - 模板类库分析
转自:http://blog.csdn.net/mr_raptor/article/details/7251948 WindowsPhone自定义控件详解(一) - 控件类库分析 上一节主要分析了控件 ...
- 【Allwinner ClassA20类库分析】 2.free pascal语法及结构简析
上一节介绍了Lazarus一般的开发操作流程,对于不熟悉pascal语言的朋友可能看的还是不大明确.不知道pascal代码里都应该包括什么或起什么作用.这回就简单地介绍下语法及代码文件的结构. ...
- WindowsPhone自定义控件详解(一) - 控件类库分析
转自:http://blog.csdn.net/mr_raptor/article/details/7251942 为了让你的应用程序更有个性,我们通常会在WP7开发过程中会自定义自己风格的控件,自定 ...
- 【Allwinner ClassA20类库分析】4.GPIO类的使用
从本节起,開始使用ClassA20类库完毕操作外设的功能,请先在https://github.com/tjCFeng/ClassA20下载ClassA20类库. 封装的目的就是简化操作,试想一 ...
- android-plugmgr源代码分析
android-plugmgr是一个Android插件加载框架,它最大的特点就是对插件不需要进行任何约束.关于这个类库的介绍见作者博客,市面上也有一些插件加载框架,但是感觉没有这个好.在这篇文章中,我 ...
- BAT资深工程师 由浅入深分析 Tp5&Tp6底层源码 - 分享
BAT资深工程师由浅入深分析Tp5&Tp6底层源码 第1章 课程简介 本章主要让大家知道本套课程的主线, 导学内容,如何学习源码等,看完本章要让小伙伴觉得这个是必须要掌握的,并且对加薪有很大的 ...
- BAT资深工程师由浅入深分析Tp5&Tp6底层源码☆
第1章 课程简介 本章主要让大家知道本套课程的主线, 导学内容,如何学习源码等,看完本章要让小伙伴觉得这个是必须要掌握的,并且对加薪有很大的帮助. 第2章 [TP5灵魂]自动加载Loader 深度分析 ...
- fir.im Weekly - iOS/Android 应用程序架构解析
假如问你一个iOS or Android app的架构,你会从哪些方面来说呢? 本期 fir.im Weekly 收集了关于 iOS/Android 开发资源,也加入了一些关于 Web 前端方面的分 ...
- C# 爬虫 Jumony html解析
前言 前几天写了个爬虫,然后认识到了自己的不足.感谢 "倚天照海- -" ,我通过你推荐的文章,意外的发现了html解析的类库——Jumony. 研究了2天,我发现这个东西简单粗暴 ...
随机推荐
- PHP JWT token实现
原文链接:https://www.jb51.net/article/146790.htm 机制: 代码如下: <?php /** * PHP实现jwt */ class Jw ...
- js的promise
转载自: https://segmentfault.com/a/1190000007032448#articleHeader16 一 前言 本文主要对ES6的Promise进行一些入门级的介绍.要想学 ...
- 手写SpringMVC实现过程
1. Spring Boot,Spring MVC的底层实现都是Servlet的调用. 2. Servlet的生命周期里面首先是类的初始化,然后是类的方法的调用,再次是类的销毁. 3. 创建一个spr ...
- 在RPA中使用Python批量生成指定尺寸的缩略图!比Ps好用!
前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. PS:如有需要Python学习资料的小伙伴可以加点击下方链接自行获取 htt ...
- Java生鲜电商平台-App系统架构开发与设计
Java生鲜电商平台-App系统架构开发与设计 说明:阅读此文,你可以学习到以下的技术分享 1.Java生鲜电商平台-App架构设计经验谈:接口的设计2.Java生鲜电商平台-App架构设计经验谈:技 ...
- centos下搭建python双版本环境
目录 centos下搭建python双版本环境 一.安装python3 1.理清自带python位置 2.更新用于下载编译python3的相关包 3.安装pip 4.用pip安装wget 5.用wge ...
- 当cell中有UItextfiled或者UITextVIew时,弹出键盘把tableview往上,但是有的cell没有移动
cell中有UITextView时,输入文字是需要将tableView向上移,基本的做法是,注册键盘变化的通知在通知的方法中做tableVIew的位置调整, 一,一般做法 - (void)regist ...
- [转]JVM系列五:JVM监测&工具[整理中]
原文地址:http://www.cnblogs.com/redcreen/archive/2011/05/09/2040977.html 前几篇篇文章介绍了介绍了JVM的参数设置并给出了一些生产环境的 ...
- 使用vs code编写Markdown文档以及markdown语法详解
首先安装vscode工具,下载地址如下: https://code.visualstudio.com/ 在vs code的扩展中安装: Markdown Preview Enhanced 这款插件,安 ...
- bash 中 小括号的作用
单小括号 () ①命令组.括号中的命令将会新开一个子shell顺序执行,所以括号中的变量不能够被脚本余下的部分使用.括号中多个命令之间用分号隔开,最后一个命令可以没有分号,各命令和括号之间不必有空格. ...