asp.net mvc实现 错误异常记录功能
来源:互联网 发布:宜家值得的买 知乎 编辑:程序博客网 时间:2024/05/17 12:05
创建LogExceptionAttribute 类,继承HandleErrorAttribute 错误异常过滤器
using System;using System.Web.Mvc;namespace SXF.Utils.MVC{ /// <summary> /// 错误日志记录 /// </summary> [AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = false)] public class LogExceptionAttribute : HandleErrorAttribute { public override void OnException(ExceptionContext filterContext) { if (!filterContext.ExceptionHandled) { #region 记录错误日志 string controllerName = (string)filterContext.RouteData.Values["controller"]; string actionName = (string)filterContext.RouteData.Values["action"]; string msgTemplate = string.Format("在执行 controller[{0}] 的 action[{1}] 时产生异常", controllerName, actionName); EventLog.LogItem item = new EventLog.LogItem(); item.Title = msgTemplate; LogManage.WriteException(filterContext.Exception, item); #endregion } base.OnException(filterContext); } }}
此方法中用到了EventLog类中的方法,代码如下:
using System;using System.Collections.Generic;using System.Collections.Specialized;using System.Configuration;using System.IO;using System.Text;using System.Web;namespace SXF.Utils{ /// <summary> /// 写日志 /// 不想自动记录Context信息请调用Log(string message, string typeName, false) /// </summary> public class EventLog { /// <summary> /// 是否使用上下文信息写日志 /// </summary> static bool UseContext = true; static string _thisDomain = ""; #region LogItem [Serializable] public class LogItem { public DateTime Time { get; set; } public string Title { get; set; } public string Detail { get; set; } public string RequestUrl { get; set; } public string UrlReferrer { get; set; } public string HostIP { get; set; } public string UserAgent { get; set; } public override string ToString() { string s = Time.ToString("yyyy-MM-dd HH:mm:ss"); if (string.IsNullOrEmpty(Title)) { Title = Detail; Detail = ""; } if (!string.IsNullOrEmpty(Title)) { s += " " + Title; } if (!string.IsNullOrEmpty(RequestUrl)) { s += "\r\nUrl:" + RequestUrl; } if (!string.IsNullOrEmpty(UrlReferrer)) { s += "\r\nUrlReferrer:" + UrlReferrer; } if (!string.IsNullOrEmpty(HostIP)) { s += "\r\nHostIP:" + HostIP; } if (!string.IsNullOrEmpty(UserAgent)) { s += "\r\n" + UserAgent; } if (!string.IsNullOrEmpty(Detail)) { s += "\r\n" + Detail; } s += "\r\n"; return s; } } #endregion static object lockObj = new object(); /// <summary> /// 检查目录并建立 /// </summary> /// <param name="path"></param> public static void CreateFolder(string path) { if (path.IsNullOrEmpty()) { return; } string folder = ""; string[] arry = path.Split('\\'); for (int i = 0; i < arry.Length; i++) { folder += arry[i] + "\\"; if (!Directory.Exists(folder)) Directory.CreateDirectory(folder); } } /// <summary> /// 自定义文件名前辍写入日志 /// </summary> /// <param name="message"></param> /// <param name="typeName"></param> /// <param name="useContext"></param> /// <returns></returns> public static bool Log(string message, string typeName, bool useContext) { LogItem logItem = new LogItem(); logItem.Detail = message; return Log(logItem, typeName, useContext); } public static bool Log(string message, string typeName) { return Log(message, typeName, true); } /// <summary> /// 指定日志类型名生成日志 /// </summary> /// <param name="logItem"></param> /// <param name="typeName"></param> /// <returns></returns> public static bool Log(LogItem logItem, string typeName) { return Log(logItem, typeName, true); } /// <summary> /// 指定日志类型名生成日志 /// </summary> /// <param name="logItem"></param> /// <param name="typeName"></param> /// <param name="useContext">是否使用当前上下文信息</param> /// <returns></returns> public static bool Log(LogItem logItem, string typeName, bool useContext) { string fileName = DateTime.Now.ToString("yyyy-MM-dd"); if (!string.IsNullOrEmpty(typeName)) { fileName += "." + typeName; } HttpContext context = HttpContext.Current; logItem.Time = DateTime.Now; if (context != null) { try { if (string.IsNullOrEmpty(_thisDomain)) { _thisDomain = context.Request.Url.Host; } if (UseContext) { if (useContext) { logItem.HostIP = RequestHelper.GetCdnIP(); logItem.RequestUrl = context.Request.Url.ToString(); logItem.UserAgent = context.Request.UserAgent; logItem.UrlReferrer = context.Request.UrlReferrer + ""; } } } catch { } } return WriteLog(GetLogFolder(), logItem, fileName); } /// <summary> /// 生成日志,默认文件名 /// </summary> /// <param name="message"></param> /// <param name="sendToServer">是否发送到服务器</param> /// <returns></returns> public static bool Log(string message, bool sendToServer) { //if (sendToServer) //{ // SendToServer(message, ""); //} return WriteLog(message); } /// <summary> /// 生成日志,默认文件名 /// </summary> /// <param name="message"></param> /// <returns></returns> public static bool Log(string message) { return WriteLog(message); } /// <summary> /// 生成日志,文件名以Error开头 /// </summary> /// <param name="message"></param> /// <returns></returns> public static bool Error(string message) { return Log(message, "Error"); } /// <summary> /// 生成日志,文件名以Info开头 /// </summary> /// <param name="message"></param> /// <returns></returns> public static bool Info(string message) { return Log(message, "Info"); } /// <summary> /// 生成日志,文件名以Debug开头 /// </summary> /// <param name="message"></param> /// <returns></returns> public static bool Debug(string message) { return Log(message, "Debug"); } /// <summary> /// 在当前网站目录生成日志 /// </summary> /// <param name="message"></param> public static bool WriteLog(string message) { return Log(message, ""); } static bool Writing = false; //static DateTime lastWriteTime = DateTime.Now; static Dictionary<string, LogItemArry> logCaches = new Dictionary<string, LogItemArry>(); static System.Timers.Timer timer; private static void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { if (!Writing) { WriteLogFromCache(); } } /// <summary> /// 指定路径,文件名,写入日志 /// </summary> /// <param name="path"></param> /// <param name="logItem"></param> /// <param name="fileName"></param> /// <returns></returns> public static bool WriteLog(string path, LogItem logItem, string fileName)//建立日志 { try { if (timer == null) { timer = new System.Timers.Timer(); timer.Interval = 2000; timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed); timer.Start(); } if (!System.IO.Directory.Exists(path)) CreateFolder(path); string filePath = ""; filePath = path + fileName + ".txt"; if (!logCaches.ContainsKey(filePath)) logCaches.Add(filePath, new LogItemArry() { savePath = filePath }); logCaches[filePath].Add(logItem); return true; } catch { return false; } } public static string LastError; public static void WriteLogFromCache() { lock (lockObj) { Writing = true; //累加上次记录的日志 if (logCaches.Count > 0) { Dictionary<string, LogItemArry> list = new Dictionary<string, LogItemArry>(logCaches); foreach (KeyValuePair<string, LogItemArry> entry in list) { LogItemArry logitemArry = entry.Value; LastError = null; try { WriteLine(logitemArry.ToString(), entry.Key); } catch (Exception ero) { LastError = ero.ToString(); } logCaches.Remove(entry.Key); } } //System.Threading.Thread.Sleep(6000); Writing = false; } } /// <summary> /// 写信息到指定文件 /// </summary> /// <param name="message"></param> /// <param name="filePath"></param> private static void WriteLine(string message, string filePath) { using (FileStream fs = File.OpenWrite(filePath)) { //根据上面创建的文件流创建写数据流 StreamWriter w = new StreamWriter(fs, System.Text.Encoding.Default); //设置写数据流的起始位置为文件流的末尾 w.BaseStream.Seek(0, SeekOrigin.End); //w.Write(DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")); w.Write(message); w.Flush(); w.Close(); } Console.WriteLine(message); } static string secondFolder = null; /// <summary> /// 获取日志二级目录 /// </summary> /// <returns></returns> public static string GetSecondFolder() { if (secondFolder == null) { string address = RequestHelper.GetServerIp(); string[] arry = address.Split('.'); secondFolder = arry[arry.Length - 1]; } return secondFolder; } static string rootPath = null; /// <summary> /// 获取日志绝对目录 /// </summary> /// <returns></returns> public static string GetLogFolder() { if (rootPath == null) { rootPath = System.Web.Hosting.HostingEnvironment.MapPath(@"\log\"); if (string.IsNullOrEmpty(rootPath)) { rootPath = AppDomain.CurrentDomain.BaseDirectory + @"\log\"; } rootPath += GetSecondFolder() + @"\"; //如果节点有设置,则按节点设置读取 NameValueCollection appSettings = ConfigurationManager.AppSettings; string settingPath = appSettings["EventLogFolder"]; if (!string.IsNullOrEmpty(settingPath)) { rootPath = settingPath + @"\"; } } return rootPath; } /// <summary> /// 项集合 /// </summary> public class LogItemArry { public string savePath; List<LogItem> logs = new List<LogItem>(); public void Add(LogItem log) { logs.Add(log); } public override string ToString() { StringBuilder sb = new StringBuilder(); foreach (LogItem item in logs) { sb.Append(item.ToString()); } return sb.ToString() + "\r\n"; } } }}
用到了LogManage 类的方法,代码如下:
using System;using System.Text;using System.Web;namespace SXF.Utils.MVC{ /// <summary> /// mvc日志管理 /// </summary> public class LogManage { public static Exception GetInnerException(Exception exp) { if (exp.InnerException != null) { exp = exp.InnerException; return GetInnerException(exp); } return exp; } static long exceptionId = 0; static object lockObj = new object(); /// <summary> /// 内部记录日志 /// </summary> /// <param name="ero"></param> /// <returns></returns> static string InnerLogException(Exception ero, EventLog.LogItem item) { string host = HttpContext.Current.Request.Url.Host.ToUpper(); string errorCode = host.Replace(".", "_"); lock (lockObj) { exceptionId += 1; errorCode += ":" + EventLog.GetSecondFolder() + ":" + exceptionId; } ero = GetInnerException(ero); item.Title = item.Title + ",错误代码:" + errorCode; if (ero != null) { item.Detail = ero.Message + "\r\n" + ero.StackTrace + "\r\n"; } EventLog.Log(item, "Error"); if (host == "LOCALHOST") { return errorCode; } return errorCode; } /// <summary> /// 页面输出并写入错误日志 /// </summary> /// <param name="ero"></param> public static void WriteException(Exception ero, EventLog.LogItem item) { //EventLog.Log("start1", "error"); bool logError = true; if (ero is HttpException) { HttpException he = ero as HttpException; int code = he.GetHttpCode(); if (code == 404) { logError = false; } } if (ero is HttpRequestValidationException) { logError = false; } //EventLog.Log("start2", "error"); string errorCode = string.Empty; if (logError) { //EventLog.Log("start6", "error"); errorCode = InnerLogException(ero, item); } } }}
写好后需要在FilterConfig 中注册:
public static class FilterConfig { public static void RegisterGlobalFilters(GlobalFilterCollection filters) { //错误处理 filters.Add(new HandleErrorAttribute()); //日志记录 filters.Add(new SXF.Utils.MVC.LogExceptionAttribute()); } }
global.asax.cs中已经在application_start中默认有调用代码:
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
另外 web.config 中设置:
<customErrors mode="Off" />
阅读全文
0 0
- asp.net mvc实现 错误异常记录功能
- ASP.NET MVC实现验证码功能
- ASP.NET MVC实现验证码功能
- WinForm、ASP.NET、MVC记录全局错误日志
- asp.net mvc中加入log4net记录错误日志
- ASP.NET/MVC 配置log4net启用写错误日志功能
- ASP.NET MVC 异常处理
- ASP.NET MVC捕获异常
- ASP.NET MVC实现网站验证码功能(上)
- ASP.NET MVC实现网站验证码功能(中)
- ASP.NET MVC实现网站验证码功能(下)
- 在 Asp.NET MVC 中使用 SignalR 实现推送功能
- 在 Asp.NET MVC 中使用 SignalR 实现推送功能
- 在 Asp.NET MVC 中使用 SignalR 实现推送功能
- 在 Asp.NET MVC 中使用 SignalR 实现推送功能
- 在 Asp.NET MVC 中使用 SignalR 实现推送功能
- 在 Asp.NET MVC 中使用 SignalR 实现推送功能
- ASP.NET MVC验证码功能实现代码
- HTTP Keep-Alive是什么?如何工作?(理解TCP生命周期)
- 让用户满意的UI背后有怎样的秘密
- Git之关闭右键菜单-yellowcong
- 安全
- 导入导出数据库
- asp.net mvc实现 错误异常记录功能
- 最简单的判断回文数的方式
- effective C++条款四十一解读
- node.js学习mongoDB驱动——查询数据
- Error Curves UVA
- Notepad++设置用4个空格取代TAB键
- HTTP 中 GET 与 POST 的区别
- Android tools 的使用
- python Matplotlib 学习笔记(1)