ASP.NET - 记录错误日志
- 不需要像log4net/Nlog/Common Logging配置,简单好用。
- 不用增加声明logger对象,可记录当前执行状况。
- 可以定义 维护功能模板的开发人员,以便用功能模块对于开发人员。
- 出处:https://git.oschina.net/lztkdr/Log_Solution
- 最后建议,如果要开发成网站页面来浏览日志内容的场景,推荐使用MngoDB、Sql Server 存储,做成页面的形式可以在线看到网站程序的日志内容。
public partial class _default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { int i = 0; int res = 10 / i; } }
protected void Application_Error(object sender, EventArgs e) { if (Server.GetLastError() != null) { LogUtils.LogError("网站错误日志", Developer.SysDefault, Server.GetLastError()); } }
日志类:
using System; using System.Collections.Generic; using System.Web; using System.Text; using System.Reflection; using System.Collections; using System.Collections.Specialized; using System.Text.RegularExpressions; using System.IO; namespace Utils { /// <summary> /// 日志操作类 /// </summary> public class LogUtils { private static object locker = new object(); /// <summary> /// 获取请求相关信息 /// </summary> /// <param name="level">日志级别</param> /// <returns></returns> private static List<string> GetRequestData(LogLevel level) { List<string> lstdata = new List<string>(); if (HttpContext.Current != null && HttpContext.Current.Request != null) { if (HttpContext.Current.Server != null) { lstdata.Add("Computer:" + HttpContext.Current.Server.MachineName); } HttpRequest Request = HttpContext.Current.Request; if (Request.Url != null) { lstdata.Add("URI:" + Request.Url.AbsoluteUri); } if (Request.UrlReferrer != null) { lstdata.Add("UrlReferrer:" + Request.UrlReferrer.AbsoluteUri); } if (Request.ServerVariables != null) { #region 获取IP地址 Regex regex = new Regex("([1-9]|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3}"); string str_Ip = string.Empty; if (!string.IsNullOrEmpty(Request.ServerVariables["REMOTE_ADDR"])) { str_Ip = Request.ServerVariables["REMOTE_ADDR"]; } else if (!string.IsNullOrEmpty(Request.ServerVariables["HTTP_CDN_SRC_IP"]) && regex.IsMatch(Request.ServerVariables["HTTP_CDN_SRC_IP"])) { str_Ip = Request.ServerVariables["HTTP_CDN_SRC_IP"]; } else if (!string.IsNullOrEmpty(Request.ServerVariables["HTTP_X_FORWARDED_FOR"]) && regex.IsMatch(Request.ServerVariables["HTTP_X_FORWARDED_FOR"])) { str_Ip = Request.ServerVariables["HTTP_X_FORWARDED_FOR"]; } string[] ip = str_Ip.Split(','); #endregion lstdata.Add("IP:" + ip[0]); } lstdata.Add("UserAgent:" + Request.UserAgent); if (level == LogLevel.Warn) { lstdata.Add("POST信息:" + Log.GetCollectionData(Request.Form)); } else if (level == LogLevel.Error) { lstdata.Add("POST信息:" + Log.GetCollectionData(Request.Form)); if (Request.Cookies != null && Request.Cookies.Count > 0) { List<string> lstCKInfo = new List<string>(); for (int j = 0; j < Request.Cookies.Count; j++) { HttpCookie item = Request.Cookies[j]; lstCKInfo.Add(item.Name + ":" + item.Value); } lstdata.Add("Cookie信息:" + string.Join(";", lstCKInfo.ToArray())); } } } return lstdata; } /// <summary> /// 写入日志 /// </summary> /// <param name="logName">日志名称</param> /// <param name="developer">开发记录者</param> /// <param name="level">日志级别</param> /// <param name="detail">日志详情</param> /// <param name="createtime">记录时间</param> public static void Write(string logName, Developer developer, LogLevel level, string detail, DateTime createtime) { Log log = new Log(); log.LogName = logName; log.Level = level; log.Developer = developer; log.CreateTime = createtime; List<string> lstDetails = GetRequestData(level); lstDetails.Add(detail); log.Detail = string.Join("\r\n\r\n", lstDetails.ToArray()); //todo :可以将日志写入 文件、数据库、MongoDB //这里写入根目录 log文件夹 string logText = Log.GetModelData(log); string fileName = DateTime.Now.ToString("yyyyMMdd") + ".log"; string dir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "log"); if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); } fileName = Path.Combine(dir, fileName); File.AppendAllText(fileName, logText, Encoding.UTF8); } /// <summary> /// 写入Info 日志 /// </summary> /// <param name="logName">日志名称</param> /// <param name="developer">开发记录者</param> /// <param name="Info_objs">日志内容</param> public static void LogInfo(string logName, Developer developer, params object[] Info_objs) { lock (locker) { List<string> lstDetails = new List<string>(); if (Info_objs != null && Info_objs.Length > 0) { List<string> lstInfo = new List<string>(); foreach (var item in Info_objs) { lstInfo.Add(Log.GetModelData(item)); } lstDetails.Add("标记信息:" + string.Join(";", lstInfo.ToArray())); } Write(logName, developer, LogLevel.Info, string.Join("\r\n", lstDetails.ToArray()), DateTime.Now); } } /// <summary>s /// 写入带 堆栈执行 的Info 日志 /// </summary> /// <param name="logName">日志名称</param> /// <param name="developer">开发记录者</param> /// <param name="Info_objs">日志内容</param> public static void LogWrite(string logName, Developer developer, params object[] Info_objs) { lock (locker) { List<string> lstDetails = new List<string>(); System.Diagnostics.StackTrace stack = new System.Diagnostics.StackTrace(1, true); System.Diagnostics.StackFrame frame = stack.GetFrame(0); string execFile = frame.GetFileName(); string fullName = frame.GetMethod().DeclaringType.FullName; string methodName = frame.GetMethod().Name; int execLine = frame.GetFileLineNumber(); lstDetails.Add("文件路径:" + execFile + "\r\n"); lstDetails.Add("类全命名:" + fullName + "\r\n"); lstDetails.Add("执行方法:" + methodName + "\r\n"); lstDetails.Add("当前行号:" + execLine + "\r\n"); if (Info_objs != null && Info_objs.Length > 0) { List<string> lstInfo = new List<string>(); foreach (var item in Info_objs) { lstInfo.Add(Log.GetModelData(item)); } lstDetails.Add("标记信息:" + string.Join(";", lstInfo.ToArray())); } Write(logName, developer, LogLevel.Info, string.Join("\r\n", lstDetails.ToArray()), DateTime.Now); } } /// <summary> /// 写入Warn 日志 /// </summary> /// <param name="logName">日志名称</param> /// <param name="developer">开发记录者</param> /// <param name="Info_objs">日志内容</param> public static void LogWarn(string logName, Developer developer, params object[] Info_objs) { lock (locker) { List<string> lstDetails = new List<string>(); System.Diagnostics.StackTrace stack = new System.Diagnostics.StackTrace(1, true); System.Diagnostics.StackFrame frame = stack.GetFrame(0); string execFile = frame.GetFileName(); string fullName = frame.GetMethod().DeclaringType.FullName; string methodName = frame.GetMethod().Name; int execLine = frame.GetFileLineNumber(); lstDetails.Add("文件路径:" + execFile + "\r\n"); lstDetails.Add("类全命名:" + fullName + "\r\n"); lstDetails.Add("执行方法:" + methodName + "\r\n"); lstDetails.Add("当前行号:" + execLine + "\r\n"); if (Info_objs != null && Info_objs.Length > 0) { List<string> lstInfo = new List<string>(); foreach (var item in Info_objs) { lstInfo.Add(Log.GetModelData(item)); } lstDetails.Add("标记信息:" + string.Join(";", lstInfo.ToArray())); } Write(logName, developer, LogLevel.Warn, string.Join("\r\n", lstDetails.ToArray()), DateTime.Now); } } /// <summary> /// 写入 Errorr日志 /// </summary> /// <param name="logName">日志名称</param> /// <param name="developer">开发记录者</param> /// <param name="ex">异常对象(可为null)</param> /// <param name="ext_InfoObjs">日志内容</param> public static void LogError(string logName, Developer developer, Exception ex, params object[] ext_InfoObjs) { lock (locker) { List<string> lstDetails = new List<string>(); Exception currentEX = ex; if (ex.InnerException != null) { currentEX = ex.InnerException; } lstDetails.Add("异常信息:" + Log.GetModelData(currentEX)); StringBuilder sb_extInfo = new StringBuilder(); if (ext_InfoObjs != null && ext_InfoObjs.Length > 0) { List<string> lst_ext_Inf = new List<string>(); foreach (var item in ext_InfoObjs) { lst_ext_Inf.Add(Log.GetModelData(item)); } lstDetails.Add("标记信息:" + string.Join(";", lst_ext_Inf.ToArray())); } string detail = string.Join("\r\n\r\n", lstDetails.ToArray()); Write(logName, developer, LogLevel.Error, detail, DateTime.Now); } } } /// <summary> /// 程序日志 /// </summary> public class Log { public Guid Id { get { return Guid.NewGuid(); } } /// <summary> /// 日志名称 /// </summary> public string LogName { get; set; } /// <summary> /// 日志级别 /// </summary> public LogLevel Level { get; set; } /// <summary> /// 当前记录日志者 /// </summary> public Developer Developer { get; set; } /// <summary> /// 日志详细内容 /// </summary> public string Detail { get; set; } /// <summary> /// 日志时间 /// </summary> public DateTime CreateTime { get; set; } #region private 反射 对象 /// <summary> /// 得到对象的所有属性值 /// </summary> /// <param name="obj">对象</param> /// <returns></returns> public static string GetModelData(object obj) { string valueParam = string.Empty; StringBuilder sb = new StringBuilder(); if (obj == null || string.IsNullOrEmpty(obj.ToString())) { return string.Empty; } Type objType = obj.GetType(); if (IsSimpleType(objType)) { valueParam = obj.ToString(); } else { PropertyInfo[] proInfos = objType.GetProperties(); foreach (PropertyInfo proInfo in proInfos) { string name = proInfo.Name; object objvalue = null; string value = string.Empty; try { objvalue = proInfo.GetValue(obj, null); } catch { } if (objvalue == null) { value = string.Empty; } else { value = objvalue.ToString(); } sb.AppendLine(name + ":" + value + "\r\n"); } valueParam = sb.ToString().TrimEnd(); } return valueParam; } /// <summary> /// 得到集合 数组中所有值 /// </summary> /// <param name="obj">集合对象</param> /// <returns></returns> public static string GetCollectionData(ICollection obj) { if (obj == null || string.IsNullOrEmpty(obj.ToString())) { return string.Empty; } string valueParam = string.Empty; Type objType = obj.GetType(); string typeName = objType.Name; Type[] argumentsTypes = objType.GetGenericArguments(); #region isLstMark isDictMark bool isLstMark = false; if (argumentsTypes.Length == 1) { if (IsSimpleType(argumentsTypes[0])) { isLstMark = true; } } else { isLstMark = (obj as IList) != null; } bool isDictMark = false; if (argumentsTypes.Length == 2) { if (IsSimpleType(argumentsTypes[0]) && IsSimpleType(argumentsTypes[1])) { isDictMark = true; } } else { isDictMark = ((obj as IDictionary) != null); } #endregion if (objType.IsArray) { #region 数组类型 int arrRank = objType.GetArrayRank(); if (arrRank == 1) { Array arr = (Array)obj; if (arr != null && arr.LongLength > 0) { List<string> lst = new List<string>(); foreach (var item in arr) { if (item != null) { lst.Add(item.ToString()); } } valueParam = string.Join(",", lst.ToArray()); } } #endregion } else if (isLstMark) { #region List IEnumerable enumlst = obj as IEnumerable; if (enumlst != null) { List<object> lsts = new List<object>(); foreach (var item in enumlst) { if (item != null) { lsts.Add(item.ToString()); } } if (lsts.Count > 0) { valueParam = string.Join(",", lsts.ToArray()); } } #endregion } else if (isDictMark) { #region Dictionary IDictionary dict = obj as IDictionary; if (dict != null && dict.Count > 0) { StringBuilder sb = new StringBuilder(); foreach (DictionaryEntry item in dict) { sb.AppendLine(item.Key + ":" + item.Value + "\r\n"); } valueParam = sb.ToString(); } #endregion } else if (obj is NameValueCollection) { #region NameValueCollection NameValueCollection nvc = (NameValueCollection)obj; if (nvc != null && nvc.Count > 0) { StringBuilder sb = new StringBuilder(); foreach (string key in nvc.AllKeys) { sb.AppendLine(key + ":" + nvc[key] + "\r\n"); } valueParam = sb.ToString(); } #endregion } else if (obj is ICollection) { #region ICollection ICollection coll = obj as ICollection; if (coll != null) { List<object> lstObjs = new List<object>(); foreach (var item in coll) { if (item != null) { lstObjs.Add(item.ToString()); } } if (lstObjs.Count > 0) { valueParam = string.Join(",", lstObjs.ToArray()); } } #endregion } return valueParam.TrimEnd(); } public static bool IsSimpleType(Type type) { //IsPrimitive 判断是否为基础类型。 //基元类型为 Boolean、 Byte、 SByte、 Int16、 UInt16、 Int32、 UInt32、 Int64、 UInt64、 IntPtr、 UIntPtr、 Char、 Double 和 Single。 Type t = Nullable.GetUnderlyingType(type) ?? type; if (t.IsPrimitive || t.IsEnum || t == typeof(string)) return true; return false; } #endregion #region 枚举 处理 /// <summary> /// 根据枚举对象得到 枚举键值对 /// </summary> /// <typeparam name="T">枚举</typeparam> /// <returns></returns> public static Dictionary<string, string> GetAllEnums<T>() { Dictionary<string, string> dict = null; Type type = typeof(T); string[] enums = Enum.GetNames(type); if (enums != null && enums.Length > 0) { dict = new Dictionary<string, string>(); foreach (string item in enums) { string str = Enum.Parse(typeof(T), item).ToString(); T deve = (T)Enum.Parse(typeof(T), item); string uid = Convert.ToInt32(deve).ToString(); dict.Add(str, uid); } } return dict; } /// <summary> /// 根据枚举val获取枚举name /// </summary> /// <typeparam name="T">枚举类型</typeparam> /// <param name="enumVal">枚举val</param> /// <returns>枚举name</returns> public static T GetEnumName<T>(int enumVal) { T t = (T)Enum.Parse(typeof(T), enumVal.ToString()); return t; } #endregion } /// <summary> /// 日志级别 /// </summary> public enum LogLevel { Info = 0, Warn = 1, Error = 2 } /// <summary> /// 日志记录开发者 /// </summary> public enum Developer { /// <summary> /// 系统默认 /// </summary> SysDefault = 0, /// <summary> /// 其他用户 小强 ^_^ /// </summary> XiaoQiang = 115 } }
效果:
posted on 2015-09-01 14:08 ultrastrong 阅读(255) 评论(0) 编辑 收藏 举报