审计跟踪(也称为审核日志)是一个安全相关的时间顺序记录,记录这些记录的目的是为已经影响在任何时候的详细操作,提供程序运行的证明文件记录、源或事件
MVC自定义一个过滤器
public class AuditFilter : IActionFilter { /// <summary> /// 在执行操作方法后调用。 /// </summary> /// <param></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></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></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></param> /// <param></param> /// <param></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