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天,我发现这个东西简单粗暴 ...
随机推荐
- Redis系列---redis简介01
一. 本章我们将用简短的几句话来帮助你快速的了解什么是redis,初学者不必深究 1 Redis简介 Remote Dictionary Server(Redis)是一个开源的使用ANSI C语言编写 ...
- Python爬取知乎单个问题下的回答
前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: 努力学习的渣渣哦 PS:如有需要Python学习资料的小伙伴可以加 ...
- 解决mac睡眠唤醒/插拔之后,外接显示器无法点亮/无信号问题
问题现象 mac盖上盖子唤醒或者里临时拔出数据线,再重新连接之后,经常出现下面问题: [系统偏好设置]-[显示器]仍可以识别外接显示器: 外接显示器会提示无信号输入 解决方法 方法一 通过[系统偏好设 ...
- webpack代码分离CommonsChunkPlugin插件的使用(防止重复)
1.webpack.config.js中添加: const path = require('path'); + const webpack = require('webpack'); const HT ...
- JS实现深浅拷贝
1.实现浅拷贝 // 1. ...实现 let copy1 = {...{x:1}} // 2. Object.assign实现 let copy2 = Object.assign({}, {x:1} ...
- Xcode 11新建工程.--iOS 13 SceneDelegate适配
收录文章::::::::::::::: iOS 13 适配要点总结 在Xcode 11 创建的工程,运行设备选择 iOS 13.0 以下的设备,运行应用时会出现黑屏现象.原因: Xcode 11 默认 ...
- 深入理解JVM虚拟机(二):JDK 内存类的异常分析
JVM数据存储 堆存储(Heap):对象存储,实际上就是JAVA的数据存储 方法堆栈(Method Stack):存储方法调用的关系. 永久代(Perm):在JDK1.6及之前,常量数据存储于此区域 ...
- BayaiM__SQLLDR_linux_shell高级版
BayaiM__SQLLDR_linux_shell高级版 备注:1.因公司在职,商业机密,顾IP地方加了"*"号,你可以任意写一个数字做IP做就好.2.不要瞎BB,哥自己写的 ...
- 1.Java基础_Java核心机制简介
Java的两种核心机制 Java虚拟机机制 Java垃圾回收机制 解释名词 J2SDK&JRE: J2SDK=JDK=Software Development Kit(软件开发包) JRE=J ...
- SpringCloud学习笔记(十、SpringCloud Sleuth)
目录: 什么是SpringCloud Sleuth 为什么使用SpringCloud Sleuth 如何使用SpringCloud Sleuth 什么是SpringCloud Sleuth: Spri ...