using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace itsvse.demo
{
/// <summary>
/// 日誌類
/// </summary>
/// <remarks>
/// 當呼叫Write方法時不會造成執行緒阻塞,而是立即完成方法呼叫,因此呼叫執行緒不用等待日誌寫入檔案之後才返回。
/// </remarks>
public class Logger
public static void Write(string msgText)
Write(DateTime.Now, MsgType.Information, "", msgText);
}
/// 寫日誌基礎方法
/// <param name="msgDataTime"></param>
/// <param name="msgType"></param>
/// <param name="msglocatio{過濾}n"></param>
/// <param name="msgText"></param>
private static void Write(DateTime msgDataTime, MsgType msgType, string msglocatio{過濾}n, string msgText)
QueueManager qm = new QueueManager();
qm.WriteToQueue(msgDataTime, msgType, msglocatio{過濾}n, msgText);
#region QueueManager
/// 企業應用框架的日誌類
private class QueueManager : IDisposable
/// 日誌物件的快取佇列
private static Queue<Msg> _msgsQueue;
/// 日誌檔案儲存的路徑
private static readonly string Path = BasePath + "\\AppLogs\";
/// Web和WinForm通用的取當前根目錄的方法
private static string BasePath
get
if (System.Web.HttpContext.Current != null)
return System.Web.HttpContext.Current.Server.MapPath("~/").TrimEnd(new char[] { "\\" });
else //當控制元件在定時器的觸發程式中使用時就為空
return AppDomain.CurrentDomain.BaseDirectory.TrimEnd(new char[] { "\\" });
//return AppDomain.CurrentDomain.BaseDirectory.TrimEnd(new char[] { "\\" });
/// 日誌寫入檔案執行緒的控制標記,true為正在寫入
private static bool _state = false;
/// 日誌檔案生命週期的時間標記
private static DateTime _timeSign;
/// 日誌檔案寫入流物件
private static StreamWriter _writer;
private delegate void WorkDelegate();
private static WorkDelegate _workDg;
/// 初始化
public QueueManager()
if (_msgsQueue == null)
if (!Directory.Exists(Path))
Directory.CreateDirectory(Path);
_msgsQueue = new Queue<Msg>();
_workDg = new WorkDelegate(Work);
/// 寫入新日誌,根據指定的日誌物件Msg
/// <param name="msg">日誌內容物件</param>
private void WriteToQueue(Msg msg)
if (msg != null)
lock (_msgsQueue)
_msgsQueue.Enqueue(msg);
if (_msgsQueue.Count > 0 && !_state)
_state = true;
_workDg.BeginInvoke(null, null);
/// 日誌寫入檔案執行緒執行的方法,消費者
private void Work()
//判斷佇列中是否存在待寫入的日誌
while (_msgsQueue.Count > 0)
Msg msg = null;
msg = _msgsQueue.Dequeue();
WriteToFile(msg);
_state = false;
FileClose();
/// 透過判斷檔案的到期時間標記將決定是否建立新檔案。
/// <returns></returns>
private static string GetFilename()
DateTime now = DateTime.Now;
string format = "yyyy-MM-dd".log"";
_timeSign = new DateTime(now.Year, now.Month, now.Day);
_timeSign = _timeSign.AddDays(1);
return now.ToString(format);
/// 寫入日誌文字到檔案的方法
/// <param name="msg"></param>
private void WriteToFile(Msg msg)
try
if (_writer == null)
FileOpen();
//判斷檔案到期標誌,如果當前檔案到期則關閉當前檔案建立新的日誌檔案
if (DateTime.Now >= _timeSign)
if (_writer != null)
_writer.WriteLine(string.Format("{0}", msg.Datetime) + "\t" + msg.Type + "\t" + msg.locatio{過濾}n + "\t" + msg.Text);
_writer.Flush();
catch (Exception e)
Console.Out.Write(e);
//開啟檔案準備寫入
private void FileOpen()
_writer = new StreamWriter(Path + GetFilename(), true, Encoding.UTF8);
//關閉開啟的日誌檔案
private void FileClose()
_writer.Close();
_writer.Dispose();
_writer = null;
/// 寫入新日誌,根據指定的日誌時間、日誌內容和資訊型別寫入新日誌
public void WriteToQueue(DateTime msgDataTime, MsgType msgType, string msglocatio{過濾}n, string msgText)
WriteToQueue(new Msg(msgDataTime, msgType, msglocatio{過濾}n, msgText));
#region IDisposable 成員
/// 銷燬日誌物件
public void Dispose()
#endregion
#region Msg
/// 表示一個日誌記錄的物件
private class Msg
//日誌記錄的時間
//日誌記錄的型別
//日誌記錄的內容
/// 建立新的日誌記錄例項;
public Msg(DateTime msgDataTime, MsgType msgType, string msglocatio{過濾}n, string msgText)
Datetime = msgDataTime;
Type = msgType;
locatio{過濾}n = msglocatio{過濾}n;
Text = msgText;
/// 獲取或設定日誌記錄的時間
public DateTime Datetime { get; private set; }
public string locatio{過濾}n { get; private set; }
/// 獲取或設定日誌記錄的訊息型別
public MsgType Type { get; private set; }
/// 獲取或設定日誌記錄的文字內容
public string Text { get; private set; }
#region MsgType
/// 日誌訊息型別的列舉
public enum MsgType
/// 普通訊息型別的日誌記錄
Information,
/// 警告資訊型別的日誌記錄
Warning,
/// 錯誤資訊型別的日誌記錄
Error,
/// 成功資訊型別的日誌記錄
Success,
/// 致命型別的日誌記錄
Fatal
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace itsvse.demo
{
/// <summary>
/// 日誌類
/// </summary>
/// <remarks>
/// 當呼叫Write方法時不會造成執行緒阻塞,而是立即完成方法呼叫,因此呼叫執行緒不用等待日誌寫入檔案之後才返回。
/// </remarks>
public class Logger
{
public static void Write(string msgText)
{
Write(DateTime.Now, MsgType.Information, "", msgText);
}
/// <summary>
/// 寫日誌基礎方法
/// </summary>
/// <param name="msgDataTime"></param>
/// <param name="msgType"></param>
/// <param name="msglocatio{過濾}n"></param>
/// <param name="msgText"></param>
private static void Write(DateTime msgDataTime, MsgType msgType, string msglocatio{過濾}n, string msgText)
{
QueueManager qm = new QueueManager();
qm.WriteToQueue(msgDataTime, msgType, msglocatio{過濾}n, msgText);
}
#region QueueManager
/// <summary>
/// 企業應用框架的日誌類
/// </summary>
private class QueueManager : IDisposable
{
/// <summary>
/// 日誌物件的快取佇列
/// </summary>
private static Queue<Msg> _msgsQueue;
/// <summary>
/// 日誌檔案儲存的路徑
/// </summary>
private static readonly string Path = BasePath + "\\AppLogs\";
/// <summary>
/// Web和WinForm通用的取當前根目錄的方法
/// </summary>
private static string BasePath
{
get
{
if (System.Web.HttpContext.Current != null)
return System.Web.HttpContext.Current.Server.MapPath("~/").TrimEnd(new char[] { "\\" });
else //當控制元件在定時器的觸發程式中使用時就為空
{
return AppDomain.CurrentDomain.BaseDirectory.TrimEnd(new char[] { "\\" });
}
//return AppDomain.CurrentDomain.BaseDirectory.TrimEnd(new char[] { "\\" });
}
}
/// <summary>
/// 日誌寫入檔案執行緒的控制標記,true為正在寫入
/// </summary>
private static bool _state = false;
/// <summary>
/// 日誌檔案生命週期的時間標記
/// </summary>
private static DateTime _timeSign;
/// <summary>
/// 日誌檔案寫入流物件
/// </summary>
private static StreamWriter _writer;
private delegate void WorkDelegate();
private static WorkDelegate _workDg;
/// <summary>
/// 初始化
/// </summary>
public QueueManager()
{
if (_msgsQueue == null)
{
if (!Directory.Exists(Path))
Directory.CreateDirectory(Path);
_msgsQueue = new Queue<Msg>();
_workDg = new WorkDelegate(Work);
}
}
/// <summary>
/// 寫入新日誌,根據指定的日誌物件Msg
/// </summary>
/// <param name="msg">日誌內容物件</param>
private void WriteToQueue(Msg msg)
{
if (msg != null)
{
lock (_msgsQueue)
{
_msgsQueue.Enqueue(msg);
}
}
if (_msgsQueue.Count > 0 && !_state)
{
_state = true;
_workDg.BeginInvoke(null, null);
}
}
/// <summary>
/// 日誌寫入檔案執行緒執行的方法,消費者
/// </summary>
private void Work()
{
//判斷佇列中是否存在待寫入的日誌
while (_msgsQueue.Count > 0)
{
Msg msg = null;
lock (_msgsQueue)
{
msg = _msgsQueue.Dequeue();
}
if (msg != null)
{
WriteToFile(msg);
}
}
_state = false;
FileClose();
}
/// <summary>
/// 透過判斷檔案的到期時間標記將決定是否建立新檔案。
/// </summary>
/// <returns></returns>
private static string GetFilename()
{
DateTime now = DateTime.Now;
string format = "yyyy-MM-dd".log"";
_timeSign = new DateTime(now.Year, now.Month, now.Day);
_timeSign = _timeSign.AddDays(1);
return now.ToString(format);
}
/// <summary>
/// 寫入日誌文字到檔案的方法
/// </summary>
/// <param name="msg"></param>
private void WriteToFile(Msg msg)
{
try
{
if (_writer == null)
{
FileOpen();
}
//判斷檔案到期標誌,如果當前檔案到期則關閉當前檔案建立新的日誌檔案
if (DateTime.Now >= _timeSign)
{
FileClose();
FileOpen();
}
if (_writer != null)
{
_writer.WriteLine(string.Format("{0}", msg.Datetime) + "\t" + msg.Type + "\t" + msg.locatio{過濾}n + "\t" + msg.Text);
_writer.Flush();
}
}
catch (Exception e)
{
Console.Out.Write(e);
}
}
//開啟檔案準備寫入
private void FileOpen()
{
_writer = new StreamWriter(Path + GetFilename(), true, Encoding.UTF8);
}
//關閉開啟的日誌檔案
private void FileClose()
{
if (_writer != null)
{
_writer.Flush();
_writer.Close();
_writer.Dispose();
_writer = null;
}
}
/// <summary>
/// 寫入新日誌,根據指定的日誌時間、日誌內容和資訊型別寫入新日誌
/// </summary>
/// <param name="msgDataTime"></param>
/// <param name="msgType"></param>
/// <param name="msglocatio{過濾}n"></param>
/// <param name="msgText"></param>
public void WriteToQueue(DateTime msgDataTime, MsgType msgType, string msglocatio{過濾}n, string msgText)
{
WriteToQueue(new Msg(msgDataTime, msgType, msglocatio{過濾}n, msgText));
}
#region IDisposable 成員
/// <summary>
/// 銷燬日誌物件
/// </summary>
public void Dispose()
{
_state = false;
}
#endregion
#endregion
#region Msg
/// <summary>
/// 表示一個日誌記錄的物件
/// </summary>
private class Msg
{
//日誌記錄的時間
//日誌記錄的型別
//日誌記錄的內容
/// <summary>
/// 建立新的日誌記錄例項;
/// </summary>
/// <param name="msgDataTime"></param>
/// <param name="msgType"></param>
/// <param name="msglocatio{過濾}n"></param>
/// <param name="msgText"></param>
public Msg(DateTime msgDataTime, MsgType msgType, string msglocatio{過濾}n, string msgText)
{
Datetime = msgDataTime;
Type = msgType;
locatio{過濾}n = msglocatio{過濾}n;
Text = msgText;
}
/// <summary>
/// 獲取或設定日誌記錄的時間
/// </summary>
public DateTime Datetime { get; private set; }
public string locatio{過濾}n { get; private set; }
/// <summary>
/// 獲取或設定日誌記錄的訊息型別
/// </summary>
public MsgType Type { get; private set; }
/// <summary>
/// 獲取或設定日誌記錄的文字內容
/// </summary>
public string Text { get; private set; }
}
}
#endregion
#region MsgType
/// <summary>
/// 日誌訊息型別的列舉
/// </summary>
public enum MsgType
{
/// <summary>
/// 普通訊息型別的日誌記錄
/// </summary>
Information,
/// <summary>
/// 警告資訊型別的日誌記錄
/// </summary>
Warning,
/// <summary>
/// 錯誤資訊型別的日誌記錄
/// </summary>
Error,
/// <summary>
/// 成功資訊型別的日誌記錄
/// </summary>
Success,
/// <summary>
/// 致命型別的日誌記錄
/// </summary>
Fatal
}
#endregion
}
}