使用AOP的方式监测方法执行耗时

时间:2023-01-18 17:13:06

  在一些对系统中,往往可能需要对一些核心业务做相应的监测。如:记录调用参数,返回值,方法执行耗时等等。如果直接在方法的前后加入代码,如下: 

  public int F(int a, string s)
{
var now = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff");
var sw = Stopwatch.StartNew(); int ret = ; long second = sw.ElapsedMilliseconds;
var end = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff");
log.Write(now, end, second, a, s, ret);
}

这样有以下几点问题:

  1.将业务逻辑和方法执行监测混在一起。

  2.会有大量重复代码,哪怕你做了一层封装,也依然不够优雅。

由于有了以上的问题,我们会思考,如果可以将方法的调用过程抽象出来,在方法开始调用和方法调用结束时,植入代码,这样就可以很好的解决我们的问题。

  .NET中,我们可以通过RealProxy来实现我们想要的功能。RealProxy(https://msdn.microsoft.com/zh-cn/library/vstudio/system.runtime.remoting.proxies.proxyattribute(v=vs.100).aspx)MSDN的定义。在Invoke方法中,可以拦截方法的执行,那么我们就可以在方法的执行前后做一些事情啦。

  那么怎么更优雅的应用在方法上呢,我们可以用ProxyAttribute使用Attribute的方式。可以在对象初始化的时候(new关键字)创建相应的代理类。具体代码如下:

    /// <summary>
/// 标记要性能监测的类
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public class MonitorServiceAttribute : ProxyAttribute
{
public override MarshalByRefObject CreateInstance(Type serverType)
{
var instance = base.CreateInstance(serverType);
var proxy = new InjectProxy(serverType, instance).GetTransparentProxy();
return proxy as MarshalByRefObject;
} }

InjectProxy代码如下:

 public override IMessage Invoke(IMessage msg)
{
var call = (IMethodCallMessage) msg;
var ctr = call as IConstructionCallMessage; IMethodReturnMessage back;
if (ctr != null)
{
RealProxy defaultProxy = RemotingServices.GetRealProxy(_instance);
defaultProxy.InitializeServerObject(ctr);
back = EnterpriseServicesHelper.CreateConstructionReturnMessage(ctr,
(MarshalByRefObject) GetTransparentProxy());
}
else
{
var now = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff");
var sw = Stopwatch.StartNew();
back = RemotingServices.ExecuteMessage(_instance, call);
long second = sw.ElapsedMilliseconds;
var attr = MethodAttributeCache.GetAttribute<MonitorMethodAttribute>(_instance.GetType().TypeHandle,
call.MethodBase); if (attr != null)
{
attr.Value = second.ToString();
attr.ExecuteTime = now;
Queue.Enqueue(Mapper(attr));
}
}
return back;
}

我在这里只记录了方法执行耗时,可以从call里拿到参数,从back里获取到返回值。

具体调用地方如下,注意类需要继承ContextBoundObject:

  internal class Program
{
private static void Main(string[] args)
{
var t = new Test();
t.F(,"aaa");
}
} [MonitorService]
internal class Test : ContextBoundObject
{
[MonitorMethod("A")]
public int F(int a,string s)
{
return ;
} }

使用AOP的方式监测方法执行耗时的更多相关文章

  1. &period;Net中的AOP系列之《方法执行前后——边界切面》

    返回<.Net中的AOP>系列学习总目录 本篇目录 边界切面 PostSharp方法边界 方法边界 VS 方法拦截 ASP.NET HttpModule边界 真实案例--检查是否为移动端用 ...

  2. C&num;监测方法执行效率

    System.Diagnostics.Stopwatch watch = new Stopwatch(); watch.Start(); // 开始监视代码运行时间 //需要监测的代码 dothing ...

  3. &period;NET&sol;C&num; 在代码中测量代码执行耗时的建议(比较系统性能计数器和系统时间)

    我们有很多种方法评估一个方法的执行耗时,比如使用性能分析工具,使用基准性能测试.不过传统的在代码中编写计时的方式依然有效,因为它可以生产环境或用户端得到真实环境下的执行耗时. 如果你希望在 .NET/ ...

  4. 基于Java Agent的premain方式实现方法耗时监控(转),为了找到结论执行:premain在jvm启动的时候执行,所有方法前,会执行MyAgent的premain方法

    Java Agent是依附于java应用程序并能对其字节码做相关更改的一项技术,它也是一个Jar包,但并不能独立运行,有点像寄生虫的感觉.当今的许多开源工具尤其是监控和诊断工具,很多都是基于Java ...

  5. C&num;代码执行耗时计算,此处是监测的mvc控制器方法

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u011511086/article/details/78710980using System;usi ...

  6. 使用spring声明式事务,spring使用AOP来支持声明式事务,会根据事务属性,自动在方法调用之前决定是否开启一个事务,并在方法执行之后决定事务提交或回滚事务。

    使用spring声明式事务,spring使用AOP来支持声明式事务,会根据事务属性,自动在方法调用之前决定是否开启一个事务,并在方法执行之后决定事务提交或回滚事务.

  7. SpringBoot 中aop整合方法执行日志

    今天事情不多, 处理完手中的事边想着捣鼓一下AOP, 着手开始写才发现, 多久不用, 自己已经忘得差不多了, 捣鼓半天之后, 慢慢整出这个小demo,以便于以后查阅回顾 1 .先创建一个注解, 用来作 ...

  8. Golang记录、计算函数执行耗时、运行时间的一个简单方法

    // 写超时警告日志 通用方法   func TimeoutWarning(tag, detailed string, start time.Time, timeLimit float64) {    ...

  9. golang 记录函数执行耗时的一个简单方法。

    先写一个公共函数, 比如在 common 包下有这么一个方法: // 写超时警告日志 通用方法 func TimeoutWarning(tag, detailed string, start time ...

随机推荐

  1. Python基础:元类

    一.概述 二.经典阐述 三.核心总结 1.类的创建过程 2.元类的使用惯例 四.简单案例 1.默认行为 2.使用元类 五.实践为王 一.概述 Python虽然是多范式的编程语言,但它的数据模型却是 纯 ...

  2. tortoisegit教程

    tortoisegit教程: http://www.mamicode.com/info-detail-311565.html https://my.oschina.net/longxuu/blog/1 ...

  3. Entity Framework中的多个库操作批量提交、事务处理

    在Entity Framework 中使用SaveChanges()是很频繁的,单次修改或删除数据后调用SaveChanges()返回影响记录数. 要使用批量修改或者批量删除数据,就需要SaveCha ...

  4. php编程冒泡排序

    <?//冒泡排序法 function bubble_sore($array) { $count = count($array); if ($count < 0) { return fals ...

  5. crtmpserver 基本流程分析

    近期在研究crtmpserver,这里记录下学习过程,首先我们先分析下基本流程. 1.初始化流程 InitNetworking---初始化网络 Initialize Logger::Init()--- ...

  6. 结构体中使用&num;define定义宏

    struct  hostent {   char    *h_name;        /* official name of host */   char    **h_aliases;    /* ...

  7. win10环境下tensorflow-gpu安装

    踩了很多坑,浪费了一下午时间,在此记录一下. pip install tensorflow-gpu 然后下载安装cuda8.0 https://developer.nvidia.com/cuda-do ...

  8. Zabbix Agent端配置文件说明

    Zabbix Agent端配置文件说明 由于工作中经常接触到zabbix,所以将agent配置整理一下,方便日常查看. # This is a config file for the Zabbix a ...

  9. java时间操作

    这篇讲的也很专业:http://soft.zdnet.com.cn/software_zone/2007/1129/660028.shtml java中的时间操作不外乎这四种情况: 1.获取当前时间 ...

  10. Unity --- 如何简单的判断图片是否含有 alpha channel

    var texImporter = AssetImporter.GetAtPath(assetPath) as TextureImporter; if (texImporter.DoesSourceT ...