背景:现在公司整体在做监控平台,要求把各个部分的细节都记录下来,在前台页面上有所显示,所以现在需要做的就是一个监控日志的记录工作,今天讲的就是渲染监控日志的例子。

现状:当前的渲染程序没有为监控日志记录预留代码接入口,因此要新增加监控日志势必要增加新的代码。但是如果只是单单在已有逻辑中新增日志记录的代码似乎不太合理:因为记录日志的代码很多都是一样的,直接插入代码有很多重复代码;原有代码已经上线并且运行良好,新增代码会破坏原有封装,甚至增加出错的可能;再者从设计的角度来说,记录日志不属于任何一个功能的,新增日志和每个方法的执行意图格格不入,因此需要一种新的记录日志方式。

解决方案:

数据结构:设计一个通用的方法日志记录类,包含ID,方法名,执行时间长度,日志结果(正常记录正常信息,异常记录错误信息),日志结果是否为异常标志位等等,还有List<string>包含方法中用到的参变量名称,List<object>方法中的参变量的值(实现序列化接口或特性),从而实现可以记录方法上下文信息并帮助排错。所有方法执行情况日志都用这个类,形成一个统一通用的方法执行状态信息记录的类。

记录方式:对于所有需要进行日志记录的方法的采用对该方法所在的类进行动态代理的方式处理。在代理方法中的在原有方法的前后新增日志记录,动态代理采用装饰器模式实现通常称为AOP,AOP方面的内容请参阅: https://msdn.microsoft.com/zh-cn/library/dn574804.aspx 。以上是对已经存在的类的方法进行日志记录采用动态代理该类,对于方法内部的某个地方进行日志记录的,采用动态代理Stopwatch来实现。因为方法内部的日志一般都要统计时间长度,动态代理Stopwatch的Start方法和Stop方法,在Start和Stop调用的时后记录出方法的执行时间和中间参变量的值。

获取参变量:对于方法的参数获取比较容易,动态代理时会把参数传递到代理方法中,可以用对象池将该参数的句柄获取并保存,为防止对象池持有参变量使其不能在退出方法时被垃圾回收器回收,采用弱引用的方式持有所有参变量。对于方法内部的局部变量,采用代理方法中提前实例化保存到对象池方式。对象池采用字典实现,对象池的key用字符串表示,记录的是方法名称+变量名+线程上下文哈希值的方式,实现多线程中记录同一参数不同参数key的后缀(线程上下文哈希值)和不同参数值的记录,这样就可以在方法的外部提前获取局部变量的值并输出到日志。

对象池实现:上文提到对象池采用字典存储,但是对象池何时进行垃圾回收、清理垃圾数据呢?这时我们要自己定义一个添加对象到对象池的方法,在这个方法的第一部分就是清理垃圾数据,这样每新增一笔数据就删除旧数据,从而保证对象池的数据有效性。设置局部变量时要在方法执行前的代理方法中就添加,在原有代码中再添加的时候先从对象池中去取,如果有就用已经用原代码前添加进去的值,没有或者已经被垃圾回收了则重新生成新的数据。

源代码:

https://download.csdn.net/download/hirisw/10486250

C# 面向切面编程--监控日志记录方案的更多相关文章

  1. 从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】框架之十 || AOP面向切面编程浅解析:简单日志记录 + 服务切面缓存

    代码已上传Github+Gitee,文末有地址 上回<从壹开始前后端分离[ .NET Core2.0 Api + Vue 2.0 + AOP + 分布式]框架之九 || 依赖注入IoC学习 + ...

  2. Z从壹开始前后端分离【 .NET Core2.0/3.0 +Vue2.0 】框架之十 || AOP面向切面编程浅解析:简单日志记录 + 服务切面缓存

    本文梯子 本文3.0版本文章 代码已上传Github+Gitee,文末有地址 大神反馈: 零.今天完成的深红色部分 一.AOP 之 实现日志记录(服务层) 1.定义服务接口与实现类 2.在API层中添 ...

  3. 面向切面编程AOP

    本文的主要内容(AOP): 1.AOP面向切面编程的相关概念(思想.原理.相关术语) 2.AOP编程底层实现机制(动态代理机制:JDK代理.Cglib代理) 3.Spring的传统AOP编程的案例(计 ...

  4. 依赖注入(DI)有助于应用对象之间的解耦,而面向切面编程(AOP)有助于横切关注点与所影响的对象之间的解耦(转good)

    依赖注入(DI)有助于应用对象之间的解耦,而面向切面编程(AOP)有助于横切关注点与所影响的对象之间的解耦.所谓横切关注点,即影响应用多处的功能,这些功能各个应用模块都需要,但又不是其主要关注点,常见 ...

  5. 关于面向切面编程Aspect Oriented Programming(AOP)

    最近学到spring ,出来了一个新概念,面向切面编程,下面做个笔记,引自百度百科. Aspect Oriented Programming(AOP),面向切面编程,是一个比较热门的话题.AOP主要实 ...

  6. Spring实战4:面向切面编程

    主要内容 面向切面编程的基本知识 为POJO创建切面 使用@AspectJ注解 为AspectJ的aspects注入依赖关系 在南方没有暖气的冬天,太冷了,非常想念北方有暖气的冬天.为了取暖,很多朋友 ...

  7. PHP 面向切面编程

    面向切面编程介绍: 介绍: AOP(Aspect-Oriented Programming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和 ...

  8. 杂项-编程:AOP(面向切面编程)

    ylbtech-杂项-编程:AOP(面向切面编程) 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一 ...

  9. 面向切面编程AOP——加锁、cache、logging、trace、同步等这些较通用的操作,如果都写一个类,则每个用到这些功能的类使用多继承非常难看,AOP就是解决这个问题的,python AOP就是装饰器

    面向切面编程(AOP)是一种编程思想,与OOP并不矛盾,只是它们的关注点相同.面向对象的目的在于抽象和管理,而面向切面的目的在于解耦和复用. 举两个大家都接触过的AOP的例子: 1)java中myba ...

随机推荐

  1. python学习笔记(接口自动化框架 V2.0)

    这个是根据上次框架版本进行的优化 用python获取excel文件中测试用例数据 通过requets测试接口.并使用正则表达式验证响应信息内容 生成xml文件测试报告 版本更新内容: 1. 整理了Cr ...

  2. .Net Core使用jexus配置https

    今天搞了一下怎么从http换成https,写一篇博客记录该过程.关于jexus的安装和使用请看我之前的一篇博客<Jexus部署Asp.Net Core项目>,唯一的不同是,将jexus升级 ...

  3. vue-cli 脚手架项目简介(一) - package.json

    vue-cli是用来生成 vue项目的命令行工具,它的使用方法是这样的: vue init <template-name> <project-name>第二个参数 templa ...

  4. MASM 16位汇编程序几种典型的格式

    1.有名段 data segment output db 'Hello world!$' data ends code segment start: assume ds:data,cs:code mo ...

  5. python学习之基本类型

    #我的第一个python程序 print("hello world"); #多行字符串 print("""\ Usage: thingy [OPTIO ...

  6. PS基础教程:[8]蒙版使用实例

    蒙版是PS中我们最常使用的工具,使用蒙版合成图片可以制作出非常绚丽的效果,并且看上去感觉很真,下面就以一个实例为大家分享一下蒙版的基本使用. 方法 1.在PS中打开准备好的素材,这里主要介绍蒙版的使用 ...

  7. hadoop1.x和2.x的一些主要区别

    当我们安装完毕hadoop2的时候,我们看到为啥没有jobtracker,这是因为hadoop2中已经没有jobtracer了,而是产生了yarn,yarn是什么那,可以看yarn详解,我们为什么已经 ...

  8. Bellman-Ford算法——解决负权边

    Dijkstra算法虽然好,但是它不能解决带有负权边(边的权值为负数)的图. 接下来学习一种无论在思想上还是在代码实现上都可以称为完美的最短路径算法:Bellman-Ford算法. Bellman-F ...

  9. Winform、WPF、Silverlight、MFC区别与联系

    WinForm 在Windows中,诸如窗体绘制等功能由GDI(图形设备接口)实现,放在操作系统内核中.Windows Forms在底层使用的是GDI+.GDI+是GDI的“面向对象包装”,使用C++ ...

  10. C# 方法、类等的默认访问修饰符

    C# 方法默认访问级别 : private C# 类默认访问级别 : internal 1.命名空间下的元素的默认访问修饰符 public : 同一程序集的其他任何代码或引用该程序集的其他程序集都可以 ...