C#自定义log机制
2015-07-31 09:18
411 查看
在写一些后台处理的时候,通常出现一些异常问题我们都是通过输出一些log来提示用户,这样可以大大方便程序的调试和维护,
本例采用的是队列(Queue)来推送log,在一个单独的线程里面执行log输出,具体代码如下:
通过这种方式可以防止程序阻塞,也不会过多的影响处理线程的执行效率。
欢迎指正。
本例采用的是队列(Queue)来推送log,在一个单独的线程里面执行log输出,具体代码如下:
/// <summary> /// 程序日志输出工具类 /// </summary> class Logger { /// <summary> /// log所在目录 /// </summary> private const String LOG_DIR = "D:\\log"; /// <summary> /// log全路径 /// </summary> private const String LOG_PATH = "D:\\log\\{0}.log"; /// <summary> /// log队列 /// </summary> private static Queue<Log> logs = new Queue<Log>(); /// <summary> /// 线程启停标示 /// </summary> private static Boolean isSaving = false; /// <summary> /// 输出log的线程 /// </summary> private static Thread saveThread; /// <summary> /// log线程触发器 /// </summary> public static EventWaitHandle _wh = new AutoResetEvent(false); /// <summary> /// 日志类型 /// </summary> public struct LogType { public static String ERROR { get { return "错误"; } } public static String WARnING { get { return "警告"; } } public static String INFO { get { return "信息"; } } } /// <summary> /// 启动log输出 /// </summary> public static void Start() { try { isSaving = true; saveThread = new Thread(save); saveThread.IsBackground = true; saveThread.Start(); } catch (Exception e) { } } /// <summary> /// 停止log输出 /// </summary> public void Stop() { try { _wh.Close(); } catch (Exception e) { } } /// <summary> /// 输出LOG /// </summary> private static void save() { while (true) { if (!isSaving) break; try { Log log = null; lock (logs.GetType()) if (logs.Count > 0) { //移除并返回队列的第一个对象 log = logs.Dequeue(); if (log == null) return; } if (log != null) { StreamWriter sw = null; String logStr; String today = log.now.ToString("yyyy-MM-dd"); try { if (!Directory.Exists(LOG_DIR)) { Directory.CreateDirectory(LOG_DIR); } //创建输出流 if (!File.Exists(String.Format(LOG_PATH, today))) { File.Create(String.Format(LOG_PATH, today)).Close(); } sw = new StreamWriter(String.Format(LOG_PATH, today), true); //输出log日期 logStr = "时间:" + DateTime.Now.ToLocalTime().ToString(); sw.WriteLine(logStr); //输出log日期 logStr = "区域:" + log.logPlace; sw.WriteLine(logStr); //输出log类型 logStr = "类型:" + log.logType; sw.WriteLine(logStr); if (log.ex != null) { //输出log日期 logStr = "信息:" + log.ex.Message; logStr += Environment.NewLine + log.ex.StackTrace; } else { //输出log日期 logStr = "信息:" + log.message; } sw.WriteLine(logStr); //输出log结束标记 logStr = "------------------------------------------------------------------------------------------------------------------"; sw.WriteLine(logStr); } catch { //do nothing } finally { if (sw != null) { sw.Close(); } } } else { //当队列里面没有需要保存到数据库里面的内容时,线程进入等待状态 //直到_wh调用set(),线程才继续执行 _wh.WaitOne(); } } catch (Exception e) { //do nothing } } } /// <summary> /// 推送log /// </summary> /// <param name="log"></param> public static void push(Log log) { logs.Enqueue(log); _wh.Set(); } } /// <summary> /// log实体类 /// </summary> class Log { /// <summary> /// log类型 /// </summary> public String logType; /// <summary> /// log发生位置 /// </summary> public String logPlace; /// <summary> /// log信息 /// </summary> public String message; /// <summary> /// log发生时间 /// </summary> public DateTime now; /// <summary> /// log发生时间 /// </summary> public Exception ex; /// <summary> /// log构造函数 /// </summary> /// <param name="logType"></param> /// <param name="logPlace"></param> /// <param name="message"></param> public Log(String logType, String logPlace, String message) { this.logType = logType; this.logPlace = logPlace; this.message = message; this.now = DateTime.Now; } public Log(String logType, String logPlace, Exception ex) { this.logType = logType; this.logPlace = logPlace; this.ex = ex; this.now = DateTime.Now; } }
通过这种方式可以防止程序阻塞,也不会过多的影响处理线程的执行效率。
欢迎指正。
相关文章推荐
- C# 装箱与拆箱
- C#中的字符编码问题
- 动态地生成用户输入的函数表达式(C#)
- 走进,C#,消化第一章--->C#概述
- csharp: Export or Import excel using NPOI
- csharp: Export or Import excel using NPOI
- csharp: Export or Import excel using MyXls
- csharp: Export or Import excel using MyXls
- C#的继承特性
- csharp: Export or Import excel using MyXls,Spire.Xls
- c#代码01--控制台的简单输入与输出及日期的格式输出
- C# 中的用户自定义控件和WPF的配合使用
- 检索01-c#中基本数据类型和引用类型的区别
- 关于c# lambda的一些认知
- C# delegate
- C#引用类型和值类型的区别
- C# Enum,Int,String的互相转换
- 【加密与解密】Openssl 生成的RSA秘钥如被C#使用解密
- C# 引用类型作为函数参数时
- c#实现KTV点歌系统