C# 日誌類
本文代碼來自:https://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 { /// <summary> /// 日誌類 /// 隊列 可年/月/周/日/大小分割 /// 調用方法: /// 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); /// </summary> public class Log : IDisposable { private static Log _instance = null; private static readonly object _synObject = new object(); /// <summary> ///單例 /// </summary> public static Log Instance { get { if (null == _instance) { lock (_synObject) { if (null == _instance) { _instance = new Log(); } } } return _instance; } } /// <summary> /// 日誌對象的緩存隊列 /// </summary> private static Queue<Msg> _msgs; /// <summary> /// 日誌寫入線程的控製標記 ture寫中|false沒有寫 /// </summary> private bool _state; private string _logDirectory = AppDomain.CurrentDomain.BaseDirectory; /// <summary> /// 日誌文件存放目錄 /// </summary> public string LogDirectory { get { return _logDirectory; } set { _logDirectory = value; } } private LogFileSplit _logFileSplit = LogFileSplit.Sizely; /// <summary> /// 日誌拆分類型 /// </summary> public LogFileSplit logFileSplit { get { return _logFileSplit; } set { _logFileSplit = value; } } private MsgLevel _currentLogLevel = MsgLevel.Error; /// <summary> /// 當前日誌記錄等級 /// </summary> public MsgLevel CurrentMsgType { get { return _currentLogLevel; } set { _currentLogLevel = value; } } /// <summary> /// 當前負責記錄日誌文件的名稱 /// </summary> private string _currentFileName = "1.log"; private string _fileNamePrefix = "log_"; /// <summary> /// 日誌的前綴名稱,默認為log_ /// </summary> public string FileNamePrefix { get { return _fileNamePrefix; } set { _fileNamePrefix = value; } } /// <summary> /// 日誌文件生命周期的時間標記 /// </summary> private DateTime _CurrentFileTimeSign = new DateTime(); private int _maxFileSize = 2; /// <summary> /// 單個日誌文件默認大小(單位:兆) /// </summary> public int MaxFileSize { get { return _maxFileSize; } set { _maxFileSize = value; } } /// <summary> /// 文件後綴號 /// </summary> private int _fileSymbol = 0; /// <summary> /// 當前文件大小(單位:B) /// </summary> private long _fileSize = 0; /// <summary> /// 日誌文件寫入流對象 /// </summary> private StreamWriter _writer; /// <summary> /// 創建日誌對象的新實例,根據指定的日誌文件路徑和指定的日誌文件創建類型 /// </summary> private Log() { if (_msgs == null) { GetCurrentFilename(); _state = true; _msgs = new Queue<Msg>(); 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(); } } } } /// <summary> /// 根據日誌類型獲取日誌文件名,並同時創建文件到期的時間標記 /// 通過判斷文件的到期時間標記將決定是否創建新文件。 /// </summary> /// <returns></returns> 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; } } /// <summary> /// 寫入新日誌,根據指定的日誌對象Msg /// </summary> /// <param name="msg">日誌內容對象</param> private void LogWrite(Msg msg) { //enum 類型 等同 (int)msg.type < (int)CurrentMsgType if (msg.type < CurrentMsgType) return; if (_msgs != null) { lock (_msgs) { _msgs.Enqueue(msg); } } } /// <summary> /// 寫入新日誌,根據指定的日誌內容和信息類型,采用當前時間為日誌時間寫入新日誌 /// </summary> /// <param name="text">日誌內容</param> /// <param name="type">信息類型</param> public void LogWrite(string text, MsgLevel type) { LogWrite(new Msg(text, type)); } /// <summary> /// 寫入新日誌,根據指定的日誌內容 /// </summary> /// <param name="text">日誌內容</param> public void LogWrite(string text) { LogWrite(text, MsgLevel.Debug); } /// <summary> /// 寫入新日誌,根據指定的日誌時間、日誌內容和信息類型寫入新日誌 /// </summary> /// <param name="dt">日誌時間</param> /// <param name="text">日誌內容</param> /// <param name="type">信息類型</param> public void LogWrite(DateTime dt, string text, MsgLevel type) { LogWrite(new Msg(dt, text, type)); } /// <summary> /// 寫入新日誌,根據指定的異常類和信息類型寫入新日誌 /// </summary> /// <param name="e">異常對象</param> /// <param name="type">信息類型</param> public void LogWrite(Exception e) { LogWrite(new Msg(e.Message, MsgLevel.Error)); } /// <summary> /// 銷毀日誌對象 /// </summary> public void Dispose() { _state = false; } } /// <summary> /// 一個日誌記錄的對象 /// </summary> public class Msg { /// <summary> /// 創建新的日誌記錄實例;日誌記錄的內容為空,消息類型為MsgType.Unknown,日誌時間為當前時間 /// </summary> public Msg() : this("", MsgLevel.Debug) { } /// <summary> /// 創建新的日誌記錄實例;日誌事件為當前時間 /// </summary> /// <param name="t">日誌記錄的文本內容</param> /// <param name="p">日誌記錄的消息類型</param> public Msg(string t, MsgLevel 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, MsgLevel p) { datetime = dt; type = p; text = t; } /// <summary> /// 日誌記錄的時間 /// </summary> public DateTime datetime { get; set; } /// <summary> ///日誌記錄的內容 /// </summary> public string text { get; set; } /// <summary> /// 日誌等級 /// </summary> public MsgLevel type { get; set; } public new string ToString() { return datetime.ToString(CultureInfo.InvariantCulture) + "\t" + text + "\n"; } } /// <summary> /// 日誌文件拆分的枚舉 /// </summary> /// <remarks>日誌類型枚舉指示日誌文件創建的方式,如果日誌比較多可考慮每天創建一個日誌文件 /// 如果日誌量比較小可考慮每周、每月或每年創建一個日誌文件</remarks> public enum LogFileSplit { /// <summary> /// 此枚舉指示每天創建一個新的日誌文件 /// </summary> Daily, /// <summary> /// 此枚舉指示每周創建一個新的日誌文件 /// </summary> Weekly, /// <summary> /// 此枚舉指示每月創建一個新的日誌文件 /// </summary> Monthly, /// <summary> /// 此枚舉指示每年創建一個新的日誌文件 /// </summary> Annually, /// <summary> /// 日誌文件大小超過指定的創建一個新的日誌文件,MaxFileSize指定大小 /// </summary> Sizely } /// <summary> /// 日誌等級類型 Debug=0 Infor Warn Error /// </summary> public enum MsgLevel { /// <summary> /// 調試信息 /// </summary> Debug = 0, /// <summary> /// 指示普通信息類型的日誌記錄 /// </summary> Infor, /// <summary> /// 指示警告信息類型的日誌記錄 /// </summary> Warn, /// <summary> /// 指示錯誤信息類型的日誌記錄 /// </summary> Error } }
最後更新:2017-04-03 12:54:23