审计日志中的AOP
审计跟踪(也称为审核日志)是一个安全相关的时间顺序记录,记录这些记录的目的是为已经影响在任何时候的详细操作,提供程序运行的证明文件记录、源或事件
MVC
自定义一个过滤器
public class AuditFilter : IActionFilter
{
/// <summary>
/// 在执行操作方法后调用。
/// </summary>
/// <param name="filterContext"></param>
public void OnActionExecuted(ActionExecutedContext filterContext)
{
var auditData = AbpAuditFilterData.GetOrNull(filterContext.HttpContext);
if (auditData == null)
return;
auditData.Stopwatch.Stop();
var path = AppDomain.CurrentDomain.BaseDirectory + "log.txt";
if (filterContext.Exception != null)
File.AppendAllText(path,
DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "异常:" + filterContext.Exception + "\r\n");
else
File.AppendAllText(path,
DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "耗时:" +
Convert.ToInt32(auditData.Stopwatch.Elapsed.TotalMilliseconds) + "\r\n");
}
/// <summary>
/// 在执行操作方法之前调用。
/// </summary>
/// <param name="filterContext"></param>
public void OnActionExecuting(ActionExecutingContext filterContext)
{
var actionStopwatch = Stopwatch.StartNew();
AbpAuditFilterData.Set(
filterContext.HttpContext,
new AbpAuditFilterData(actionStopwatch)
);
}
}
定义一个数据存储
public class AbpAuditFilterData
{
private const string AbpAuditFilterDataHttpContextKey = "__AbpAuditFilterData";
public AbpAuditFilterData(
Stopwatch stopwatch)
{
Stopwatch = stopwatch;
}
public Stopwatch Stopwatch { get; }
public static void Set(HttpContextBase httpContext, AbpAuditFilterData auditFilterData)
{
GetAuditDataStack(httpContext).Push(auditFilterData);
}
public static AbpAuditFilterData GetOrNull(HttpContextBase httpContext)
{
var stack = GetAuditDataStack(httpContext);
return stack.Count <= 0
? null
: stack.Pop();
}
/// <summary>
/// 获取一个可变大小的后进先出 (LIFO) 集合
/// </summary>
/// <param name="httpContext"></param>
/// <returns></returns>
private static Stack<AbpAuditFilterData> GetAuditDataStack(HttpContextBase httpContext)
{
if (httpContext.Items[AbpAuditFilterDataHttpContextKey] is Stack<AbpAuditFilterData> stack)
return stack;
stack = new Stack<AbpAuditFilterData>();
httpContext.Items[AbpAuditFilterDataHttpContextKey] = stack;
return stack;
}
}
HomeController 如下
public class HomeController : Controller
{
public ActionResult Index()
{
var a = 0;
for (var i = 0; i < 10000; i++)
for (var j = 0; j < 10000; j++)
a = i - j;
ViewBag.A = a;
return View();
}
public ActionResult About()
{
var a = Convert.ToInt32("a");
ViewBag.Message = "Your application description page.";
return View();
}
}
访问home/index 日志记录如下:
2018-01-22 19:11:09耗时:342
访问home/about 日志记录如下:

Web Api
自定义过滤器
public class AuditFilter : IActionFilter
{
//
// 摘要:
// 获取或设置一个值,该值指示是否可以为单个程序元素指定多个已指示特性的实例。
//
// 返回结果:
// 如果可以指定多个实例,则为 true;否则为 false。默认值为 false。
public bool AllowMultiple => false;
/// <summary>
/// 异步执行筛选器操作
/// </summary>
/// <param name="actionContext"></param>
/// <param name="cancellationToken"></param>
/// <param name="continuation"></param>
/// <returns></returns>
public async Task<HttpResponseMessage> ExecuteActionFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
{
var method = actionContext.ActionDescriptor is ReflectedHttpActionDescriptor descriptor ? descriptor.MethodInfo : null;
var str = $"{actionContext.ActionDescriptor.ControllerDescriptor.ControllerType.Name}/{method?.Name}/{JsonConvert.SerializeObject(actionContext.ActionArguments)}";
var stopwatch = Stopwatch.StartNew();
var path = AppDomain.CurrentDomain.BaseDirectory + "log.txt";
try
{
return await continuation();
}
catch (Exception ex)
{
File.AppendAllText(path,
DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " " + str + "异常:" + ex + "\r\n");
throw;
}
finally
{
stopwatch.Stop();
File.AppendAllText(path,
DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " " + str + "耗时:" +
Convert.ToInt32(stopwatch.Elapsed.TotalMilliseconds) + "\r\n");
}
}
}
ValuesController代码如下
public class ValuesController : ApiController
{
// GET api/values
public IEnumerable<string> Get()
{
Thread.Sleep(new Random().Next(500, 1000));
return new[] { "Get" };
}
// GET api/values/5
public string Get(int id)
{
Thread.Sleep(new Random().Next(500, 1000));
return id + "";
}
[Route("api/values/GetError")]
public void GetError()
{
var a = Convert.ToInt32("a");
}
}
访问api/values 日志记录如下
2018-01-22 19:23:27 ValuesController/Get/{}耗时:978
访问api/values/1 日志记录如下
2018-01-22 19:24:21 ValuesController/Get/{"id":1}耗时:727
访问api/values/GetError 日志记录如下

Unity
自定义一个拦截器
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Interface)]
public class UnityAopAttribute : HandlerAttribute, ICallHandler
{
public override ICallHandler CreateHandler(IUnityContainer container)
{
return this;
}
public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
var s = new Stopwatch();
s.Start();
var result = getNext()(input, getNext);
if (result.Exception != null)
{
WriteLog(result.Exception.ToString());
//表示处理异常 Unity就不会抛出
result.Exception = null;
}
s.Stop();
WriteLog("方法:{0},参数:{1},耗时:{2}",
input.MethodBase.Name, JsonConvert.SerializeObject(input.Arguments), s.Elapsed.TotalMilliseconds);
return result;
}
private void WriteLog(string format, params object[] arg)
{
var path = AppDomain.CurrentDomain.BaseDirectory + "log.txt";
File.AppendAllText(path, string.Format(format, arg) + "\r\n");
}
public IEnumerable<Type> GetRequiredInterfaces()
{
return Type.EmptyTypes;
}
public bool WillExecute => false;
}
接口定义如下
public interface IOrderService
{
string GetOrder();
string GetOrderDetail();
}
实现如下
加上UnityAop标记
[UnityAop]
public class OrderService : IOrderService
{
public string GetOrder()
{
Thread.Sleep(new Random().Next(500, 1000));
return "GetOrder";
}
public string GetOrderDetail()
{
var i = Convert.ToInt32("a");
return i + "GetOrder";
}
}
注入及调用如下

示例代码:https://github.com/sunven/Abp1
Reference
审计日志中的AOP的更多相关文章
- Springboot中使用AOP统一处理Web请求日志
title: Springboot中使用AOP统一处理Web请求日志 date: 2017-04-26 16:30:48 tags: ['Spring Boot','AOP'] categories: ...
- Spring Boot中使用AOP统一处理Web请求日志
AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是Spring框架中的一个重要内容,它通 ...
- (转)Spring Boot中使用AOP统一处理Web请求日志
AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是Spring框架中的一个重要内容,它通 ...
- 在Delphi中应用AOP实现日志功能
AOP现在很火,网上有这许多支持AOP的框架,对于Delphi来说同样也有MeAOP.不过觉得这些框架太复杂了. 现在有一个系统,基本上都快结束了,整体上当然是没有采用什么AOP的框架.对于这样的系统 ...
- Spring Boot中使用AOP记录请求日志
这周看别人写的springboot后端代码中有使用AOP记录请求日志,以前没接触过,因此学习下. 一.AOP简介 AOP为Aspect Oriented Programming的缩写,意为:面向切面编 ...
- 46. Spring Boot中使用AOP统一处理Web请求日志
在之前一系列的文章中都是提供了全部的代码,在之后的文章中就提供核心的代码进行讲解.有什么问题大家可以给我留言或者加我QQ,进行咨询. AOP为Aspect Oriented Programming的缩 ...
- 转:Spring Boot中使用AOP统一处理Web请求日志
在spring boot中,简单几步,使用spring AOP实现一个拦截器: 1.引入依赖: <dependency> <groupId>org.springframewor ...
- Spring MVC 中使用AOP 进行统一日志管理--注解实现
1.AOP简介 AOP称为面向切面编程 AOP的基本概念 (1)Aspect(切面):通常是一个类,里面可以定义切入点和通知 (2)JointPoint(连接点):程序执行过程中明确的点,一般是方法的 ...
- SpringBoot中使用AOP打印接口日志的方法(转载)
前言 AOP 是 Aspect Oriented Program (面向切面)的编程的缩写.他是和面向对象编程相对的一个概念.在面向对象的编程中,我们倾向于采用封装.继承.多态等概念,将一个个的功能在 ...
随机推荐
- java 分解质因数
算法目的:对一个正整数分解质因数 一.算法分析: 1.建立整数列表,保存求到的因数. 2.声明整数i=2,用以递增取模:整数m,用于临时保存n 3.建立while循环,i小于等于整数m时,判断m%i, ...
- python (5分钟实现一个游戏的屏蔽敏感字系统,)
import datetime time=datetime.datetime.now() dirty= ['fuck','狗日的','犊子','麻批','仙人板板','R你妈','操你','草你',' ...
- java inputstream to string
https://stackoverflow.com/questions/309424/read-convert-an-inputstream-to-a-string 过千赞的答案
- 程序猿的日常——Java中的集合列表
列表对于日常开发来说实在是太常见了,以至于很多开发者习惯性的用到数组,就来一个ArrayList,根本不做过多的思考.其实列表里面还是有很多玩法的,有时候玩不好,搞出来bug还得定位半天.所以这里就再 ...
- Django_调查问卷
1.问卷的保存按钮 前端通过ajax把数据发过来后端处理数据,然后返回给前端2.对问卷做答 首先用户进行登录,验证 条件:1.只有本班的学生才能对问卷做答 2.已经参加过的不能再次访问 ...
- PHP生成验证码
<?php check_code(); function check_code($width = 100, $height = 50, $num = 4, $type = 'jpeg') { $ ...
- ${param.name}和${name}的区别
${param.name} == request.getParam("name") ${name} == request.getAttribute("name" ...
- Python的__getattr__和__getattribute__
__getattr____getattr__在当前主流的Python版本中都可用,重载__getattr__方法对类及其实例未定义的属性有效.也就属性是说,如果访问的属性存在,就不会调用__getat ...
- 微信小程序入门
自己看了一下微信小程序 其实 还是很简单的 官方有现成的api 跟 组件给你用 我的感觉就像是一个 前端框架 类似于 ionic 这种 感觉比ionic还要简单 里面的wxml ...
- Windows上最大传输单元MTU值的查看和设置
最近使用ssh工具在VPN环境下连接一个生产环境的Linux主机的时候,发现经常出现输入命令后卡死的情况.最开始以为是Linux主机的问题,问了一些老同事之后发现原来是我自己电脑的最大传输单元MTU和 ...