ASP.NET - 记录错误日志

  1. 不需要像log4net/Nlog/Common Logging配置,简单好用。 
  2. 不用增加声明logger对象,可记录当前执行状况。
  3. 可以定义 维护功能模板的开发人员,以便用功能模块对于开发人员。
  4. 出处:https://git.oschina.net/lztkdr/Log_Solution
  5. 最后建议,如果要开发成网站页面来浏览日志内容的场景,推荐使用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  阅读(256)  评论(0编辑  收藏  举报