关键词搜索

源码搜索 ×
×

C# 日志类

发布2014-01-08浏览1969次

详情内容

本文代码来自:http://www.oschina.net/code/snippet_1181744_27513
作者:ebola
该类的作用: 简单日志类,队列实现。可按天 周 月 年 大小分割文件。
代码如下:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Globalization;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Threading;
  8. namespace LogisTrac
  9. {
  10. /// <summary>
  11. /// 日志类
  12. /// 队列 可年/月/周/日/大小分割
  13. /// 调用方法:
  14. /// Log.Instance.LogDirectory=@"C:\"; 默认为程序运行目录
  15. /// Log.Instance.FileNamePrefix="cxd";默认为log_
  16. /// Log.Instance.CurrentMsgType = MsgLevel.Debug;默认为Error
  17. /// Log.Instance.logFileSplit = LogFileSplit.Daily; 日志拆分类型LogFileSplit.Sizely 大小
  18. /// Log.Instance.MaxFileSize = 5; 默认大小为2M,只有LogFileSplit.Sizely的时候配置有效
  19. /// Log.Instance.LogWrite("aa");
  20. /// Log.Instance.LogWrite("aa", MsgLevel.Debug);
  21. /// </summary>
  22. public class Log : IDisposable
  23. {
  24. private static Log _instance = null;
  25. private static readonly object _synObject = new object();
  26. /// <summary>
  27. ///单例
  28. /// </summary>
  29. public static Log Instance
  30. {
  31. get
  32. {
  33. if (null == _instance)
  34. {
  35. lock (_synObject)
  36. {
  37. if (null == _instance)
  38. {
  39. _instance = new Log();
  40. }
  41. }
  42. }
  43. return _instance;
  44. }
  45. }
  46. /// <summary>
  47. /// 日志对象的缓存队列
  48. /// </summary>
  49. private static Queue<Msg> _msgs;
  50. /// <summary>
  51. /// 日志写入线程的控制标记 ture写中|false没有写
  52. /// </summary>
  53. private bool _state;
  54. private string _logDirectory = AppDomain.CurrentDomain.BaseDirectory;
  55. /// <summary>
  56. /// 日志文件存放目录
  57. /// </summary>
  58. public string LogDirectory
  59. {
  60. get { return _logDirectory; }
  61. set { _logDirectory = value; }
  62. }
  63. private LogFileSplit _logFileSplit = LogFileSplit.Sizely;
  64. /// <summary>
  65. /// 日志拆分类型
  66. /// </summary>
  67. public LogFileSplit logFileSplit
  68. {
  69. get { return _logFileSplit; }
  70. set { _logFileSplit = value; }
  71. }
  72. private MsgLevel _currentLogLevel = MsgLevel.Error;
  73. /// <summary>
  74. /// 当前日志记录等级
  75. /// </summary>
  76. public MsgLevel CurrentMsgType
  77. {
  78. get { return _currentLogLevel; }
  79. set { _currentLogLevel = value; }
  80. }
  81. /// <summary>
  82. /// 当前负责记录日志文件的名称
  83. /// </summary>
  84. private string _currentFileName = "1.log";
  85. private string _fileNamePrefix = "log_";
  86. /// <summary>
  87. /// 日志的前缀名称,默认为log_
  88. /// </summary>
  89. public string FileNamePrefix
  90. {
  91. get { return _fileNamePrefix; }
  92. set { _fileNamePrefix = value; }
  93. }
  94. /// <summary>
  95. /// 日志文件生命周期的时间标记
  96. /// </summary>
  97. private DateTime _CurrentFileTimeSign = new DateTime();
  98. private int _maxFileSize = 2;
  99. /// <summary>
  100. /// 单个日志文件默认大小(单位:兆)
  101. /// </summary>
  102. public int MaxFileSize
  103. {
  104. get { return _maxFileSize; }
  105. set { _maxFileSize = value; }
  106. }
  107. /// <summary>
  108. /// 文件后缀号
  109. /// </summary>
  110. private int _fileSymbol = 0;
  111. /// <summary>
  112. /// 当前文件大小(单位:B)
  113. /// </summary>
  114. private long _fileSize = 0;
  115. /// <summary>
  116. /// 日志文件写入流对象
  117. /// </summary>
  118. private StreamWriter _writer;
  119. /// <summary>
  120. /// 创建日志对象的新实例,根据指定的日志文件路径和指定的日志文件创建类型
  121. /// </summary>
  122. private Log()
  123. {
  124. if (_msgs == null)
  125. {
  126. GetCurrentFilename();
  127. _state = true;
  128. _msgs = new Queue<Msg>();
  129. Thread thread = new Thread(work);
  130. thread.Start();
  131. }
  132. }
  133. //日志文件写入线程执行的方法
  134. private void work()
  135. {
  136. while (true)
  137. {
  138. //判断队列中是否存在待写入的日志
  139. if (_msgs.Count > 0)
  140. {
  141. Msg msg = null;
  142. lock (_msgs)
  143. {
  144. msg = _msgs.Dequeue();
  145. if (msg != null)
  146. {
  147. FileWrite(msg);
  148. }
  149. }
  150. }
  151. else
  152. {
  153. //判断是否已经发出终止日志并关闭的消息
  154. if (_state)
  155. {
  156. Thread.Sleep(1);
  157. }
  158. else
  159. {
  160. FileClose();
  161. }
  162. }
  163. }
  164. }
  165. /// <summary>
  166. /// 根据日志类型获取日志文件名,并同时创建文件到期的时间标记
  167. /// 通过判断文件的到期时间标记将决定是否创建新文件。
  168. /// </summary>
  169. /// <returns></returns>
  170. private void GetCurrentFilename()
  171. {
  172. DateTime now = DateTime.Now;
  173. string format = "";
  174. switch (_logFileSplit)
  175. {
  176. case LogFileSplit.Daily:
  177. _CurrentFileTimeSign = new DateTime(now.Year, now.Month, now.Day);
  178. _CurrentFileTimeSign = _CurrentFileTimeSign.AddDays(1);
  179. format = now.ToString("yyyyMMdd'.log'");
  180. break;
  181. case LogFileSplit.Weekly:
  182. _CurrentFileTimeSign = new DateTime(now.Year, now.Month, now.Day);
  183. _CurrentFileTimeSign = _CurrentFileTimeSign.AddDays(7);
  184. format = now.ToString("yyyyMMdd'.log'");
  185. break;
  186. case LogFileSplit.Monthly:
  187. _CurrentFileTimeSign = new DateTime(now.Year, now.Month, 1);
  188. _CurrentFileTimeSign = _CurrentFileTimeSign.AddMonths(1);
  189. format = now.ToString("yyyyMM'.log'");
  190. break;
  191. case LogFileSplit.Annually:
  192. _CurrentFileTimeSign = new DateTime(now.Year, 1, 1);
  193. _CurrentFileTimeSign = _CurrentFileTimeSign.AddYears(1);
  194. format = now.ToString("yyyy'.log'");
  195. break;
  196. default:
  197. _fileSymbol++;
  198. format = _fileSymbol.ToString() + ".log";
  199. break;
  200. }
  201. if (File.Exists(Path.Combine(LogDirectory, _currentFileName)))
  202. {
  203. _fileSize = new FileInfo(Path.Combine(LogDirectory, _currentFileName)).Length;
  204. }
  205. else
  206. {
  207. _fileSize = 0;
  208. }
  209. _currentFileName = _fileNamePrefix + format.Trim();
  210. }
  211. //写入日志文本到文件的方法
  212. private void FileWrite(Msg msg)
  213. {
  214. try
  215. {
  216. if (_writer == null)
  217. {
  218. FileOpen();
  219. }
  220. if (_writer != null)
  221. {
  222. //判断文件到期标志,如果当前文件到期则关闭当前文件创建新的日志文件
  223. if ((_logFileSplit != LogFileSplit.Sizely && DateTime.Now >= _CurrentFileTimeSign) ||
  224. (_logFileSplit == LogFileSplit.Sizely && ((double)_fileSize / 1048576) > _maxFileSize))
  225. {
  226. GetCurrentFilename();
  227. FileClose();
  228. FileOpen();
  229. }
  230. _writer.Write(msg.datetime);
  231. _writer.Write('\t');
  232. _writer.Write(msg.type);
  233. _writer.Write('\t');
  234. _writer.WriteLine(msg.text);
  235. _fileSize += System.Text.Encoding.UTF8.GetBytes(msg.ToString()).Length;
  236. _writer.Flush();
  237. }
  238. }
  239. catch (Exception e)
  240. {
  241. Console.Out.Write(e);
  242. }
  243. }
  244. //打开文件准备写入
  245. private void FileOpen()
  246. {
  247. _writer = new StreamWriter(LogDirectory + _currentFileName, true, Encoding.UTF8);
  248. }
  249. //关闭打开的日志文件
  250. private void FileClose()
  251. {
  252. if (_writer != null)
  253. {
  254. _writer.Flush();
  255. _writer.Close();
  256. _writer.Dispose();
  257. _writer = null;
  258. }
  259. }
  260. /// <summary>
  261. /// 写入新日志,根据指定的日志对象Msg
  262. /// </summary>
  263. /// <param name="msg">日志内容对象</param>
  264. private void LogWrite(Msg msg)
  265. {
  266. //enum 类型 等同 (int)msg.type < (int)CurrentMsgType
  267. if (msg.type < CurrentMsgType)
  268. return;
  269. if (_msgs != null)
  270. {
  271. lock (_msgs)
  272. {
  273. _msgs.Enqueue(msg);
  274. }
  275. }
  276. }
  277. /// <summary>
  278. /// 写入新日志,根据指定的日志内容和信息类型,采用当前时间为日志时间写入新日志
  279. /// </summary>
  280. /// <param name="text">日志内容</param>
  281. /// <param name="type">信息类型</param>
  282. public void LogWrite(string text, MsgLevel type)
  283. {
  284. LogWrite(new Msg(text, type));
  285. }
  286. /// <summary>
  287. /// 写入新日志,根据指定的日志内容
  288. /// </summary>
  289. /// <param name="text">日志内容</param>
  290. public void LogWrite(string text)
  291. {
  292. LogWrite(text, MsgLevel.Debug);
  293. }
  294. /// <summary>
  295. /// 写入新日志,根据指定的日志时间、日志内容和信息类型写入新日志
  296. /// </summary>
  297. /// <param name="dt">日志时间</param>
  298. /// <param name="text">日志内容</param>
  299. /// <param name="type">信息类型</param>
  300. public void LogWrite(DateTime dt, string text, MsgLevel type)
  301. {
  302. LogWrite(new Msg(dt, text, type));
  303. }
  304. /// <summary>
  305. /// 写入新日志,根据指定的异常类和信息类型写入新日志
  306. /// </summary>
  307. /// <param name="e">异常对象</param>
  308. /// <param name="type">信息类型</param>
  309. public void LogWrite(Exception e)
  310. {
  311. LogWrite(new Msg(e.Message, MsgLevel.Error));
  312. }
  313. /// <summary>
  314. /// 销毁日志对象
  315. /// </summary>
  316. public void Dispose()
  317. {
  318. _state = false;
  319. }
  320. }
  321. /// <summary>
  322. /// 一个日志记录的对象
  323. /// </summary>
  324. public class Msg
  325. {
  326. /// <summary>
  327. /// 创建新的日志记录实例;日志记录的内容为空,消息类型为MsgType.Unknown,日志时间为当前时间
  328. /// </summary>
  329. public Msg()
  330. : this("", MsgLevel.Debug)
  331. {
  332. }
  333. /// <summary>
  334. /// 创建新的日志记录实例;日志事件为当前时间
  335. /// </summary>
  336. /// <param name="t">日志记录的文本内容</param>
  337. /// <param name="p">日志记录的消息类型</param>
  338. public Msg(string t, MsgLevel p)
  339. : this(DateTime.Now, t, p)
  340. {
  341. }
  342. /// <summary>
  343. /// 创建新的日志记录实例;
  344. /// </summary>
  345. /// <param name="dt">日志记录的时间</param>
  346. /// <param name="t">日志记录的文本内容</param>
  347. /// <param name="p">日志记录的消息类型</param>
  348. public Msg(DateTime dt, string t, MsgLevel p)
  349. {
  350. datetime = dt;
  351. type = p;
  352. text = t;
  353. }
  354. /// <summary>
  355. /// 日志记录的时间
  356. /// </summary>
  357. public DateTime datetime { get; set; }
  358. /// <summary>
  359. ///日志记录的内容
  360. /// </summary>
  361. public string text { get; set; }
  362. /// <summary>
  363. /// 日志等级
  364. /// </summary>
  365. public MsgLevel type { get; set; }
  366. public new string ToString()
  367. {
  368. return datetime.ToString(CultureInfo.InvariantCulture) + "\t" + text + "\n";
  369. }
  370. }
  371. /// <summary>
  372. /// 日志文件拆分的枚举
  373. /// </summary>
  374. /// <remarks>日志类型枚举指示日志文件创建的方式,如果日志比较多可考虑每天创建一个日志文件
  375. /// 如果日志量比较小可考虑每周、每月或每年创建一个日志文件</remarks>
  376. public enum LogFileSplit
  377. {
  378. /// <summary>
  379. /// 此枚举指示每天创建一个新的日志文件
  380. /// </summary>
  381. Daily,
  382. /// <summary>
  383. /// 此枚举指示每周创建一个新的日志文件
  384. /// </summary>
  385. Weekly,
  386. /// <summary>
  387. /// 此枚举指示每月创建一个新的日志文件
  388. /// </summary>
  389. Monthly,
  390. /// <summary>
  391. /// 此枚举指示每年创建一个新的日志文件
  392. /// </summary>
  393. Annually,
  394. /// <summary>
  395. /// 日志文件大小超过指定的创建一个新的日志文件,MaxFileSize指定大小
  396. /// </summary>
  397. Sizely
  398. }
  399. /// <summary>
  400. /// 日志等级类型 Debug=0 Infor Warn Error
  401. /// </summary>
  402. public enum MsgLevel
  403. {
  404. /// <summary>
  405. /// 调试信息
  406. /// </summary>
  407. Debug = 0,
  408. /// <summary>
  409. /// 指示普通信息类型的日志记录
  410. /// </summary>
  411. Infor,
  412. /// <summary>
  413. /// 指示警告信息类型的日志记录
  414. /// </summary>
  415. Warn,
  416. /// <summary>
  417. /// 指示错误信息类型的日志记录
  418. /// </summary>
  419. Error
  420. }
  421. }


相关技术文章

最新源码

下载排行榜

点击QQ咨询
开通会员
返回顶部
×
微信扫码支付
微信扫码支付
确定支付下载
请使用微信描二维码支付
×

提示信息

×

选择支付方式

  • 微信支付
  • 支付宝付款
确定支付下载