using System; using System.Diagnostics; using System.IO; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Xml; using log4net; using log4net.Appender; using log4net.Config; namespace JY.Utility { /// /// LogHelper 用来记录系统的日志,包括异常等. /// public static class LogHelper { private static readonly ILog log; /// /// public static bool DebugMode = false; #region 构造函数 /// /// 构造函数 /// static LogHelper() { var log4netConfigPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Log4net.config"); if (!File.Exists(log4netConfigPath)) { log4netConfigPath = Path.Combine(Environment.CurrentDirectory, "Log4net.config"); } var repository = LogManager.CreateRepository("NETCoreRepository"); var configFile = new FileInfo(log4netConfigPath); if (configFile.Exists) { XmlConfigurator.Configure(repository, configFile); } else { Console.WriteLine("Log4net.config 文件未找到,日志将无法正常写入"); } log = LogManager.GetLogger(repository.Name, "Test"); RunClearJob(); } #endregion #region 清除过期日志 /// /// 启动清除过期日志线程 /// private static void RunClearJob() { Task.Run(() => { try { while (true) { ClearOverdue(); WriteLine("清除log4net过期日志"); //24小时清一次 Thread.Sleep(1000 * 60 * 60 * 24); } } catch (Exception e) { WriteException(e); } }); } /// /// 定期清除过期日志 /// private static void ClearOverdue() { var days = 7; if (File.Exists("Log4net.config")) { try { XmlDocument doc = new XmlDocument(); doc.Load(@"Log4net.config"); var node = doc.SelectSingleNode("/configuration/log4net"); days = Convert.ToInt32(node.Attributes["OverdueDays"].Value); } catch { // ignored } } var apps = log.Logger.Repository.GetAppenders(); if (apps.Length <= 0) { return; } var now = DateTime.UtcNow.AddDays(-days); foreach (var item in apps) { if (item is RollingFileAppender roll) { var dir = Path.GetDirectoryName(roll.File); var files = Directory.GetFiles(dir, "*.log.*"); //var sample = "log.txt2017-10-23.txt"; foreach (var filePath in files) { var file = new FileInfo(filePath); if (file.CreationTime < now || file.LastWriteTime < now) { try { file.Delete(); } catch (Exception) { } } } } } } #endregion #region 公布的写日志函数 /// /// 记录一条日志信息。注意:在记录时该程序会自动在左侧增加一格日期。 /// /// 字符串的组成格式 /// 参数 public static void WriteLine(string strFormat, params object[] args) { try { log.Info($"{string.Format(strFormat, args)}"); } catch (Exception exp) { Trace.WriteLine("LOG ERROR: " + exp.Message); } } /// /// 记录一条日志信息。注意:在记录时该程序会自动在左侧增加一格日期。 /// /// 字符串的组成格式 public static void WriteLine(string strLog) { try { Debug.Assert(strLog != null); log.Info($"{strLog}"); } catch (Exception exp) { Trace.WriteLine("LOG ERROR: " + exp.Message); } } /// /// 记录一条错误日志信息。注意:在记录时该程序会自动在左侧增加一格日期。 /// /// public static void WriteErrorLine(string strLog) { try { Debug.Assert(strLog != null); log.Error($"{strLog}"); } catch (Exception exp) { Trace.WriteLine("LOG ERROR: " + exp.Message); } } /// /// 记录一条日志信息。注意:在记录时该程序会自动在左侧增加一格日期。 /// /// 字符串的组成格式 public static void WriteDebugLine(string strLog) { try { Debug.Assert(strLog != null); log.Debug($"{strLog}"); } catch (Exception exp) { Trace.WriteLine("LOG ERROR: " + exp.Message); } } /// /// 记录异常(在调试模式) /// /// public static void WriteDebugException(Exception exp) { WriteDebugException(exp, null); } /// /// 记录异常(在调试模式) /// /// /// /// public static void WriteDebugException(Exception exp, string strFormat, params object[] args) { try { Debug.Assert(exp != null); var sb = new StringBuilder(); sb.AppendFormat("[{0}] DEBUG 找到 [{1}] 异常: {2}\r\n", DateTime.Now.ToString("HH:mm:ss"), exp.GetType().Name, exp.Message); // 附加信息 if (strFormat != null) sb.AppendFormat(" Annex : {0}\r\n", string.Format(strFormat, args)); // 调试信息 sb.AppendFormat(" Source : {0}\r\n", exp.Source); sb.AppendFormat(" Time : {0}\r\n", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); sb.AppendFormat(" OS/VER : {0} {1}\r\n", Environment.OSVersion.Platform, Environment.OSVersion.Version); sb.AppendFormat(" Thread : {0}\r\n", Thread.CurrentThread.Name); // 栈信息 sb.AppendFormat(" Stack : {0}\r\n", exp.StackTrace); // 内部异常, 最多5级 var inner = exp.InnerException; for (var i = 0; i < 5 && inner != null; i++) { // 显示内部异常 sb.AppendFormat(" ----- InnerException ---------------------------\r\n"); sb.AppendFormat(" ExceptionType: {0}\r\n", inner.GetType().Name); sb.AppendFormat(" Message: {0}\r\n", inner.Message); sb.AppendFormat(" Stack : {0}\r\n", inner.StackTrace); // 获取异常的内部异常 inner = inner.InnerException; } log.Error(sb.ToString()); } catch (Exception ex) { Trace.WriteLine("LOG ERROR: " + ex.Message); } } /// /// 记录下该异常 /// /// 需要记录的异常对象 public static void WriteException(Exception exp) { WriteException(exp, null); } /// /// 记录下该异常 /// /// 异常对象 /// 附加信息格式字符串,如果不需要,则该参数为 null /// 参数 public static void WriteException(Exception exp, string strFormat, params object[] args) { try { Debug.Assert(exp != null); var sb = new StringBuilder(); { sb.AppendFormat("[{0}] 找到 [{1}] 异常: {2}\r\n", DateTime.Now.ToString("HH:mm:ss"), exp.GetType().Name, exp.Message); // 附加信息 if (strFormat != null) sb.AppendFormat(" Annex : {0}\r\n", string.Format(strFormat, args)); // 调试信息 sb.AppendFormat(" Source : {0}\r\n", exp.Source); sb.AppendFormat(" Time : {0}\r\n", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); sb.AppendFormat(" OS/VER : {0} {1}\r\n", Environment.OSVersion.Platform, Environment.OSVersion.Version); sb.AppendFormat(" Thread : {0}\r\n", Thread.CurrentThread.Name); // 栈信息 sb.AppendFormat(" Stack : {0}\r\n", exp.StackTrace); // 内部异常, 最多5级 var inner = exp.InnerException; for (var i = 0; i < 5 && inner != null; i++) { // 显示内部异常 sb.AppendFormat(" ----- InnerException ---------------------------\r\n"); sb.AppendFormat(" ExceptionType: {0}\r\n", inner.GetType().Name); sb.AppendFormat(" Message: {0}\r\n", inner.Message); sb.AppendFormat(" Stack : {0}\r\n", inner.StackTrace); // 获取异常的内部异常 inner = inner.InnerException; } log.Error(sb.ToString()); } } catch (Exception ex) { Trace.WriteLine("LOG ERROR: " + ex.Message); } } /// /// Dump 一个对象 /// /// public static void WriteObject(object obj) { try { var sb = new StringBuilder(); if (obj == null) { sb.AppendLine("-- The object is null\r\n"); } else { sb.AppendFormat("[{0}] {1} has {2} property\r\n", DateTime.Now, obj.GetType().Name, obj.GetType().GetProperties().Length); var pis = obj.GetType().GetProperties(); var iMaxLength = 0; foreach (var pi in pis) if (pi.CanRead && !pi.IsSpecialName) iMaxLength = Math.Max(pi.Name.Length, iMaxLength); foreach (var pi in pis) if (pi.CanRead && !pi.IsSpecialName) sb.AppendFormat(" {0} - {1}\r\n", pi.Name.PadRight(iMaxLength, ' '), pi.GetValue(obj, null)); } } catch (Exception exp) { Trace.WriteLine("LOG ERROR: " + exp.Message); } } #endregion /// /// 错误日志带异常 /// /// /// public static void Error(string message,Exception ex) { ILog log = LogManager.GetLogger("Error"); if (log.IsErrorEnabled) { log.Error(message,ex); } } // /// 错误日志不带异常 /// /// 错误日志 public static void Error(string message) { ILog log = LogManager.GetLogger("Error"); if (log.IsErrorEnabled) { log.Error(message); } } } }