标签:
分享自己写的一个日志处理库,如果你需要更重,可以进一步扩展,如果你需要更轻,只需要使用Logger类中的方法就可以了。
之所以使用Timer+队列而不是使用ThreadPool来写入日志,主要是考虑到可以进行更大程度的控制。
主要代码:
Logger
1 using System; 2 using System.Collections.Generic; 3 using System.Text; 4 5 using System.IO; 6 using System.Threading; 7 8 namespace DeftLog 9 { 10 public class Logger : IDisposable 11 { 12 LogController logController; 13 Queue<ILog> queueLog = new Queue<ILog>(); 14 System.Timers.Timer timer = new System.Timers.Timer(); 15 bool timerFinishFlag = true; 16 string logDirectory = AppDomain.CurrentDomain.BaseDirectory; 17 string logName = "Log.txt"; 18 Encoding encoding = Encoding.UTF8; 19 bool throwException = false; 20 object lockObject = new object(); 21 22 #region 属性 23 /// <summary> 24 /// 日志控制器 25 /// </summary> 26 public LogController LogController 27 { 28 get { return logController; } 29 set { logController = value; } 30 } 31 32 /// <summary> 33 /// 正在排队日志数量 34 /// </summary> 35 public int QueuingCount 36 { 37 get { return queueLog.Count; } 38 } 39 40 /// <summary> 41 /// 日志文件目录,默认为程序集根目录 42 /// </summary> 43 public string LogDirectory 44 { 45 get { return logDirectory; } 46 set { logDirectory = value; } 47 } 48 49 /// <summary> 50 /// 日志文件名称,默认值为Log.txt 51 /// </summary> 52 public string LogName 53 { 54 get { return logName; } 55 set { logName = value; } 56 } 57 58 /// <summary> 59 /// 日志文件路径 60 /// [注:该路径是默认路径,不受临时日志文件路径的影响] 61 /// </summary> 62 public string LogPath 63 { 64 get { return Path.Combine(logDirectory, logName); } 65 } 66 67 /// <summary> 68 /// 字符编码,默认值为UTF8 69 /// </summary> 70 public Encoding Encoding 71 { 72 get { return encoding; } 73 set { encoding = value; } 74 } 75 76 /// <summary> 77 /// 是否抛出在写入日志时发生的异常,默认值为false 78 /// </summary> 79 public bool ThrowException 80 { 81 get { return throwException; } 82 set { throwException = value; } 83 } 84 #endregion 85 86 public Logger() 87 { 88 timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed); 89 timer.Interval = 10; 90 91 if (this.LogController != null) 92 { 93 this.LogController.Add(this); 94 } 95 } 96 97 public Logger(LogController logController, string logDirectory, string logName) 98 : this() 99 { 100 this.logController = logController; 101 this.logDirectory = logDirectory; 102 this.logName = logName; 103 } 104 105 public void Dispose() 106 { 107 timerFinishFlag = false; 108 timer.Enabled = false; 109 timer.Dispose(); 110 if (this.LogController != null) 111 { 112 this.LogController.Remove(this); 113 } 114 } 115 116 private void Add(ILog log) 117 { 118 lock (lockObject) 119 { 120 queueLog.Enqueue(log); 121 122 if (timer.Enabled == false) 123 { 124 timer.Enabled = true; //启动定时器,以处理日志写入操作 125 } 126 } 127 } 128 129 public void Write(ILog log) 130 { 131 Add(log); 132 } 133 134 public void Write(string content) 135 { 136 ILog log = new Log(this.LogPath, content); 137 Add(log); 138 } 139 140 public void Write(string logPath, string content) 141 { 142 ILog log = new Log(logPath, content); 143 Add(log); 144 } 145 146 public void Write(Exception exception) 147 { 148 ILog log = new ExceptionLog(exception); 149 Add(log); 150 } 151 152 private void WriteToFile(ILog log) 153 { 154 string logFile; 155 if (log.FilePath != null) 156 { 157 logFile = log.FilePath; 158 } 159 else 160 { 161 logFile = this.LogPath; 162 } 163 164 try 165 { 166 using (FileStream fs = new FileStream(logFile, FileMode.Append, FileAccess.Write, FileShare.Read)) 167 { 168 using (StreamWriter sw = new StreamWriter(fs, encoding)) 169 { 170 sw.WriteLine(log.Content); 171 } 172 } 173 } 174 catch 175 { 176 if (throwException) 177 { 178 throw; 179 } 180 } 181 finally 182 { 183 } 184 } 185 186 private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) 187 { 188 if (timerFinishFlag == false) 189 { 190 return; 191 } 192 193 try 194 { 195 timerFinishFlag = false; 196 197 //lock (lockObject) //定时器已经进行了避免重入处理,因此可以不加锁 198 //{ 199 ILog log; 200 while (queueLog.Count > 0) 201 { 202 log = queueLog.Dequeue(); 203 WriteToFile(log); 204 } 205 206 timer.Enabled = false; //当处理完队列中的元素时,停止定时器,向队列中添加元素时再重新启动,避免不必要的性能开销 207 //} 208 } 209 catch 210 { 211 if (throwException) 212 { 213 throw; 214 } 215 } 216 finally 217 { 218 timerFinishFlag = true; 219 } 220 } 221 } 222 }
LogController
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace DeftLog 7 { 8 public class LogController 9 { 10 private List<Logger> loggerList; 11 12 #region 属性 13 /// <summary> 14 /// Logger列表 15 /// </summary> 16 public List<Logger> LoggerList 17 { 18 get { return loggerList; } 19 set { loggerList = value; } 20 } 21 #endregion 22 23 private static class SingletonConstructor 24 { 25 private static LogController logger = new LogController(); 26 27 public static LogController Logger 28 { 29 get { return SingletonConstructor.logger; } 30 } 31 } 32 33 public static LogController GetInstance() 34 { 35 return SingletonConstructor.Logger; 36 } 37 38 private LogController() 39 { 40 41 } 42 43 public void Add(Logger logger) 44 { 45 if (loggerList.Contains(logger) == false) 46 { 47 loggerList.Add(logger); 48 } 49 } 50 51 public void Remove(Logger logger) 52 { 53 loggerList.Remove(logger); 54 } 55 } 56 }
使用:
//DeftLog.LogController logController = DeftLog.LogController.GetInstance();
DeftLog.Logger logger = new DeftLog.Logger(...);
//...
logger.Write(...);
下载:https://github.com/iiksde/DeftLog
最后,说点题外话,本人最近遭遇客户违约和拖欠项目费的事情,已经破产(本来也没什么财产),砸锅卖铁了,最不舍的是把跟了我多年,辗转千里都不曾丢弃的书也当废纸卖了,如果过愿意帮助的,请捐助1元(支付宝:athwind@163.com),再撑一下就行了,我会尽快把这段信息删除掉的,谢了。
标签:
原文地址:http://www.cnblogs.com/shizhi-service/p/4905576.html