通用类 Logger 日志类
/// <summary> /// 日志类 /// </summary> /// <remarks> /// 当调用Write方法时不会造成线程阻塞,而是立即完成方法调用,因此调用线程不用等待日志写入文件之后才返回。 /// </remarks> public class Logger { /// <summary> /// 写日志 /// </summary> /// <param name="text">错误描述</param> public static void Write(string text) { Log log = new Log(); log.Write(text, MsgType.Information); } /// <summary> /// 写日志 /// </summary> /// <param name="text">错误描述</param> /// <param name="type">日志类型</param> public static void Write(string text, MsgType type) { Log log = new Log(); log.Write(text, type); } /// <summary> /// 写日志 /// </summary> /// <param name="ex">异常对象</param> /// <param name="type">日志类型</param> public static void Write(Exception ex, MsgType type) { Log log = new Log(); log.Write(ex, type); } /// <summary> /// 企业应用框架的日志类 /// </summary> private class Log : IDisposable { /// <summary> /// 日志对象的缓存队列 /// </summary> private static Queue<Msg> msgs; /// <summary> /// 日志文件保存的路径 /// </summary> private static string path; /// <summary> /// 日志写入线程的控制标记 /// </summary> private static bool state; /// <summary> /// 日志文件生命周期的时间标记 /// </summary> private static DateTime TimeSign; /// <summary> /// 日志文件写入流对象 /// </summary> private static StreamWriter writer; /// <summary> /// 创建日志对象的新实例,根据指定的日志文件路径和指定的日志文件创建类型 /// </summary> /// <param name="p">日志文件保存路径</param> /// <param name="t">日志文件创建方式的枚举</param> public Log() { if(msgs == null) { state = true; path = string.Format(@"{0}logs\", System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase); msgs = new Queue<Msg>(); Thread thread = new Thread(work); thread.Start(); } } /// <summary> /// 日志文件写入线程执行的方法 /// </summary> private void work() { while(true) { //判断队列中是否存在待写入的日志 if(msgs.Count > 0) { Msg msg = null; lock(msgs) { msg = msgs.Dequeue(); } if(msg != null) { FileWrite(msg); } } else { //判断是否已经发出终止日志并关闭的消息 if(state) { Thread.Sleep(1); } else { FileClose(); } } } } /// <summary> /// 根据日志类型获取日志文件名,并同时创建文件到期的时间标记 /// 通过判断文件的到期时间标记将决定是否创建新文件。 /// </summary> /// <returns></returns> private string GetFilename() { DateTime now = DateTime.Now; string format = "yyyyMMdd'.log'"; TimeSign = new DateTime(now.Year, now.Month, now.Day); TimeSign = TimeSign.AddDays(1); return now.ToString(format); } /// <summary> /// 写入日志文本到文件的方法 /// </summary> /// <param name="msg"></param> private void FileWrite(Msg msg) { try { if(writer == null) { FileOpen(); } else { //判断文件到期标志,如果当前文件到期则关闭当前文件创建新的日志文件 if(DateTime.Now >= TimeSign) { FileClose(); FileOpen(); } writer.WriteLine(string.Format("[时间]:{0}", msg.Datetime)); writer.WriteLine(string.Format("[级别]:{0}", msg.Type.ToString().ToUpper())); writer.WriteLine(string.Format("[内容]:{0}", msg.Text)); writer.WriteLine(); writer.Flush(); } } catch(Exception e) { Console.Out.Write(e); } } //打开文件准备写入 private void FileOpen() { writer = new StreamWriter(path + GetFilename(), true, Encoding.UTF8); } //关闭打开的日志文件 private void FileClose() { if(writer != null) { writer.Flush(); writer.Close(); writer.Dispose(); writer = null; } } /// <summary> /// 写入新日志,根据指定的日志对象Msg /// </summary> /// <param name="msg">日志内容对象</param> private void Write(Msg msg) { if(msg != null) { lock(msgs) { msgs.Enqueue(msg); } } } /// <summary> /// 写入新日志,根据指定的日志内容和信息类型,采用当前时间为日志时间写入新日志 /// </summary> /// <param name="text">日志内容</param> /// <param name="type">信息类型</param> public void Write(string text, MsgType type) { Write(new Msg(text, type)); } /// <summary> /// 写入新日志,根据指定的日志时间、日志内容和信息类型写入新日志 /// </summary> /// <param name="dt">日志时间</param> /// <param name="text">日志内容</param> /// <param name="type">信息类型</param> public void Write(DateTime dt, string text, MsgType type) { Write(new Msg(dt, text, type)); } /// <summary> /// 写入新日志,根据指定的异常类和信息类型写入新日志 /// </summary> /// <param name="e">异常对象</param> /// <param name="type">信息类型</param> public void Write(Exception e, MsgType type) { Write(new Msg(e.Message, type)); } #region IDisposable 成员 /// <summary> /// 销毁日志对象 /// </summary> public void Dispose() { state = false; } #endregion /// <summary> /// 表示一个日志记录的对象 /// </summary> private class Msg { //日志记录的时间 private DateTime datetime; //日志记录的内容 private string text; //日志记录的类型 private MsgType type; /// <summary> /// 创建新的日志记录实例;日志记录的内容为空,消息类型为MsgType.Unknown,日志时间为当前时间 /// </summary> public Msg() : this("", MsgType.Unknown) { } /// <summary> /// 创建新的日志记录实例;日志事件为当前时间 /// </summary> /// <param name="t">日志记录的文本内容</param> /// <param name="p">日志记录的消息类型</param> public Msg(string t, MsgType p) : this(DateTime.Now, t, p) { } /// <summary> /// 创建新的日志记录实例; /// </summary> /// <param name="dt">日志记录的时间</param> /// <param name="t">日志记录的文本内容</param> /// <param name="p">日志记录的消息类型</param> public Msg(DateTime dt, string t, MsgType p) { datetime = dt; type = p; text = t; } /// <summary> /// 获取或设置日志记录的时间 /// </summary> public DateTime Datetime { get { return datetime; } set { datetime = value; } } /// <summary> /// 获取或设置日志记录的文本内容 /// </summary> public string Text { get { return text; } set { text = value; } } /// <summary> /// 获取或设置日志记录的消息类型 /// </summary> public MsgType Type { get { return type; } set { type = value; } } } } /// <summary> /// 日志消息类型的枚举 /// </summary> public enum MsgType { /// <summary> /// 指示未知信息类型的日志记录 /// </summary> Unknown, /// <summary> /// 指示普通信息类型的日志记录 /// </summary> Information, /// <summary> /// 指示警告信息类型的日志记录 /// </summary> Warning, /// <summary> /// 指示错误信息类型的日志记录 /// </summary> Error, /// <summary> /// 指示成功信息类型的日志记录 /// </summary> Success, /// <summary> /// 指示致命类型的日志记录 /// </summary> Fatal } }