本文代码来自:http://www.oschina.net/code/snippet_1181744_27513
作者:ebola
该类的作用:
简单日志类,队列实现。可按天 周 月 年 大小分割文件。
代码如下:
using System; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; using System.Text; using System.Threading; namespace LogisTrac { /// /// 日志类 /// 队列 可年/月/周/日/大小分割 /// 调用方法: /// Log.Instance.LogDirectory=@"C:\"; 默认为程序运行目录 /// Log.Instance.FileNamePrefix="cxd";默认为log_ /// Log.Instance.CurrentMsgType = MsgLevel.Debug;默认为Error /// Log.Instance.logFileSplit = LogFileSplit.Daily; 日志拆分类型LogFileSplit.Sizely 大小 /// Log.Instance.MaxFileSize = 5; 默认大小为2M,只有LogFileSplit.Sizely的时候配置有效 /// Log.Instance.LogWrite("aa"); /// Log.Instance.LogWrite("aa", MsgLevel.Debug); /// public class Log : IDisposable { private static Log _instance = null; private static readonly object _synObject = new object(); /// ///单例 /// public static Log Instance { get { if (null == _instance) { lock (_synObject) { if (null == _instance) { _instance = new Log(); } } } return _instance; } } /// /// 日志对象的缓存队列 /// private static Queue _msgs; /// /// 日志写入线程的控制标记 ture写中|false没有写 /// private bool _state; private string _logDirectory = AppDomain.CurrentDomain.BaseDirectory; /// /// 日志文件存放目录 /// public string LogDirectory { get { return _logDirectory; } set { _logDirectory = value; } } private LogFileSplit _logFileSplit = LogFileSplit.Sizely; /// /// 日志拆分类型 /// public LogFileSplit logFileSplit { get { return _logFileSplit; } set { _logFileSplit = value; } } private MsgLevel _currentLogLevel = MsgLevel.Error; /// /// 当前日志记录等级 /// public MsgLevel CurrentMsgType { get { return _currentLogLevel; } set { _currentLogLevel = value; } } /// /// 当前负责记录日志文件的名称 /// private string _currentFileName = "1.log"; private string _fileNamePrefix = "log_"; /// /// 日志的前缀名称,默认为log_ /// public string FileNamePrefix { get { return _fileNamePrefix; } set { _fileNamePrefix = value; } } /// /// 日志文件生命周期的时间标记 /// private DateTime _CurrentFileTimeSign = new DateTime(); private int _maxFileSize = 2; /// /// 单个日志文件默认大小(单位:兆) /// public int MaxFileSize { get { return _maxFileSize; } set { _maxFileSize = value; } } /// /// 文件后缀号 /// private int _fileSymbol = 0; /// /// 当前文件大小(单位:B) /// private long _fileSize = 0; /// /// 日志文件写入流对象 /// private StreamWriter _writer; /// /// 创建日志对象的新实例,根据指定的日志文件路径和指定的日志文件创建类型 /// private Log() { if (_msgs == null) { GetCurrentFilename(); _state = true; _msgs = new Queue(); Thread thread = new Thread(work); thread.Start(); } } //日志文件写入线程执行的方法 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(); } } } } /// /// 根据日志类型获取日志文件名,并同时创建文件到期的时间标记 /// 通过判断文件的到期时间标记将决定是否创建新文件。 /// /// private void GetCurrentFilename() { DateTime now = DateTime.Now; string format = ""; switch (_logFileSplit) { case LogFileSplit.Daily: _CurrentFileTimeSign = new DateTime(now.Year, now.Month, now.Day); _CurrentFileTimeSign = _CurrentFileTimeSign.AddDays(1); format = now.ToString("yyyyMMdd'.log'"); break; case LogFileSplit.Weekly: _CurrentFileTimeSign = new DateTime(now.Year, now.Month, now.Day); _CurrentFileTimeSign = _CurrentFileTimeSign.AddDays(7); format = now.ToString("yyyyMMdd'.log'"); break; case LogFileSplit.Monthly: _CurrentFileTimeSign = new DateTime(now.Year, now.Month, 1); _CurrentFileTimeSign = _CurrentFileTimeSign.AddMonths(1); format = now.ToString("yyyyMM'.log'"); break; case LogFileSplit.Annually: _CurrentFileTimeSign = new DateTime(now.Year, 1, 1); _CurrentFileTimeSign = _CurrentFileTimeSign.AddYears(1); format = now.ToString("yyyy'.log'"); break; default: _fileSymbol++; format = _fileSymbol.ToString() + ".log"; break; } if (File.Exists(Path.Combine(LogDirectory, _currentFileName))) { _fileSize = new FileInfo(Path.Combine(LogDirectory, _currentFileName)).Length; } else { _fileSize = 0; } _currentFileName = _fileNamePrefix + format.Trim(); } //写入日志文本到文件的方法 private void FileWrite(Msg msg) { try { if (_writer == null) { FileOpen(); } if (_writer != null) { //判断文件到期标志,如果当前文件到期则关闭当前文件创建新的日志文件 if ((_logFileSplit != LogFileSplit.Sizely && DateTime.Now >= _CurrentFileTimeSign) || (_logFileSplit == LogFileSplit.Sizely && ((double)_fileSize / 1048576) > _maxFileSize)) { GetCurrentFilename(); FileClose(); FileOpen(); } _writer.Write(msg.datetime); _writer.Write('\t'); _writer.Write(msg.type); _writer.Write('\t'); _writer.WriteLine(msg.text); _fileSize += System.Text.Encoding.UTF8.GetBytes(msg.ToString()).Length; _writer.Flush(); } } catch (Exception e) { Console.Out.Write(e); } } //打开文件准备写入 private void FileOpen() { _writer = new StreamWriter(LogDirectory + _currentFileName, true, Encoding.UTF8); } //关闭打开的日志文件 private void FileClose() { if (_writer != null) { _writer.Flush(); _writer.Close(); _writer.Dispose(); _writer = null; } } /// /// 写入新日志,根据指定的日志对象Msg /// /// 日志内容对象 private void LogWrite(Msg msg) { //enum 类型 等同 (int)msg.type < (int)CurrentMsgType if (msg.type < CurrentMsgType) return; if (_msgs != null) { lock (_msgs) { _msgs.Enqueue(msg); } } } /// /// 写入新日志,根据指定的日志内容和信息类型,采用当前时间为日志时间写入新日志 /// /// 日志内容 /// 信息类型 public void LogWrite(string text, MsgLevel type) { LogWrite(new Msg(text, type)); } /// /// 写入新日志,根据指定的日志内容 /// /// 日志内容 public void LogWrite(string text) { LogWrite(text, MsgLevel.Debug); } /// /// 写入新日志,根据指定的日志时间、日志内容和信息类型写入新日志 /// /// 日志时间 /// 日志内容 /// 信息类型 public void LogWrite(DateTime dt, string text, MsgLevel type) { LogWrite(new Msg(dt, text, type)); } /// /// 写入新日志,根据指定的异常类和信息类型写入新日志 /// /// 异常对象 /// 信息类型 public void LogWrite(Exception e) { LogWrite(new Msg(e.Message, MsgLevel.Error)); } /// /// 销毁日志对象 /// public void Dispose() { _state = false; } } /// /// 一个日志记录的对象 /// public class Msg { /// /// 创建新的日志记录实例;日志记录的内容为空,消息类型为MsgType.Unknown,日志时间为当前时间 /// public Msg() : this("", MsgLevel.Debug) { } /// /// 创建新的日志记录实例;日志事件为当前时间 /// /// 日志记录的文本内容 /// 日志记录的消息类型 public Msg(string t, MsgLevel p) : this(DateTime.Now, t, p) { } /// /// 创建新的日志记录实例; /// /// 日志记录的时间 /// 日志记录的文本内容 /// 日志记录的消息类型 public Msg(DateTime dt, string t, MsgLevel p) { datetime = dt; type = p; text = t; } /// /// 日志记录的时间 /// public DateTime datetime { get; set; } /// ///日志记录的内容 /// public string text { get; set; } /// /// 日志等级 /// public MsgLevel type { get; set; } public new string ToString() { return datetime.ToString(CultureInfo.InvariantCulture) + "\t" + text + "\n"; } } /// /// 日志文件拆分的枚举 /// /// 日志类型枚举指示日志文件创建的方式,如果日志比较多可考虑每天创建一个日志文件 /// 如果日志量比较小可考虑每周、每月或每年创建一个日志文件 public enum LogFileSplit { /// /// 此枚举指示每天创建一个新的日志文件 /// Daily, /// /// 此枚举指示每周创建一个新的日志文件 /// Weekly, /// /// 此枚举指示每月创建一个新的日志文件 /// Monthly, /// /// 此枚举指示每年创建一个新的日志文件 /// Annually, /// /// 日志文件大小超过指定的创建一个新的日志文件,MaxFileSize指定大小 /// Sizely } /// /// 日志等级类型 Debug=0 Infor Warn Error /// public enum MsgLevel { /// /// 调试信息 /// Debug = 0, /// /// 指示普通信息类型的日志记录 /// Infor, /// /// 指示警告信息类型的日志记录 /// Warn, /// /// 指示错误信息类型的日志记录 /// Error } }