技术库 > C#

C#开发高性能Log Help类设计开发

技术库:tec.5lulu.com

1 概述

from:tec.5lulu.com

       项目中要在操作数据库异常处理中加入写Log日志,对于商业上有要求,写log时对其它操作尽可能影响小,不能因为加入log导致耗时太多。

2 设计思想

       在写入日志时利用Queue来管理,写日志有一个专门的backgroud线程来处理,如果没有日志要写,这个线程处于wait状态,这就有了线程的异步处理。

3 简单的实现方式

//  
//Write Log   
//  
public static void WriteLog(string logFile, string msg)  
{  
 try  
 {  
 System.IO.StreamWriter sw = System.IO.File.AppendText(  
 logPath + LogFilePrefix +" "+ logFile + " " +  
 DateTime.Now.ToString("yyyyMMdd") + ".Log"  
 );  
 sw.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:  ") + msg);  
 sw.Close();  
 }  
 catch (Exception)  
 {  
  
 throw;  
 }  
}

4 我们的设计图

C#开发高性能Log Help类设计开发,by 5lulu.com

       而后我们在AddLogMessage时semaphore.Release()就能唤醒wait中的log 线程。

       代码设计

///  
/// Author: spring yang   
/// Create time:2012/3/30   
/// Log Help class   
///  
///High performance log class  
public class Log : IDisposable  
{  
 //Log Message queue   
 private static Queue_logMessages;  
  
 //log save directory   
 private static string _logDirectory;  
  
 //log write file state   
 private static bool _state;  
  
 //log type   
 private static LogType _logType;  
  
 //log life time sign   
 private static DateTime _timeSign;  
  
 //log file stream writer   
 private static StreamWriter _writer;  
  
 ///  
 /// Wait enqueue wirte log message semaphore will release   
 ///  
 private Semaphore _semaphore;  
  
 ///  
 /// Single instance   
 ///  
 private static Log _log;  
  
 ///  
 /// Gets a single instance   
 ///  
 public static Log LogInstance  
 {  
 get { return _log ?? (_log = new Log()); }  
 }  
  
 private object _lockObjeck;  
  
 ///  
 /// Initialize Log instance   
 ///  
 private void Initialize()  
 {  
 if (_logMessages == null)  
 {   _state = true;  
 string logPath = System.Configuration.ConfigurationManager.AppSettings["LogDirectory"];  
 _logDirectory = string.IsNullOrEmpty(logPath) ? ".\log\" : logPath;  
 if (!Directory.Exists(_logDirectory)) Directory.CreateDirectory(_logDirectory);  
 _logType = LogType.Daily;  
 _lockObjeck=new object();  
 _semaphore = new Semaphore(0, int.MaxValue, Constants.LogSemaphoreName);  
 _logMessages = new Queue();  
 var thread = new Thread(Work) {IsBackground = true};  
 thread.Start();  
 }  
 }  
  
 ///  
 /// Create a log instance   
 ///  
 private Log()  
 {  
 Initialize();  
 }  
  
 ///  
 /// Log save name type,default is daily   
 ///  
 public LogType LogType  
 {  
 get { return _logType; }  
 set { _logType = value; }  
 }  
  
 ///  
 /// Write Log file  work method   
 ///  
 private void Work()  
 {  
 while (true)  
 {  
 //Determine log queue have record need wirte   
 if (_logMessages.Count > 0)  
 {  
 FileWriteMessage();  
 }  
 else  
 if (WaitLogMessage()) break;  
 }  
 }  
  
 ///  
 /// Write message to log file   
 ///  
 private void FileWriteMessage()  
 {  
 LogMessage logMessage=null;  
 lock (_lockObjeck)  
 {  
 if(_logMessages.Count>0)  
 logMessage = _logMessages.Dequeue();  
 }  
 if (logMessage != null)  
 {  
 FileWrite(logMessage);  
 }  
 }  
  
 ///  
 /// The thread wait a log message   
 ///  
 ///is close or not  
 private bool WaitLogMessage()  
 {  
 //determine log life time is true or false   
 if (_state)  
 {  
 WaitHandle.WaitAny(new WaitHandle[] { _semaphore }, -1, false);  
 return false;  
 }  
 FileClose();  
 return true;  
 }  
  
 ///  
 /// Gets file name by log type   
 ///  
 ///log file name  
 private string GetFilename()  
 {  
 DateTime now = DateTime.Now;  
 string format = "";  
 switch (_logType)  
 {  
 case LogType.Daily:  
 _timeSign = new DateTime(now.Year, now.Month, now.Day);  
 _timeSign = _timeSign.AddDays(1);  
 format = "yyyyMMdd'.log'";  
 break;  
 case LogType.Weekly:  
 _timeSign = new DateTime(now.Year, now.Month, now.Day);  
 _timeSign = _timeSign.AddDays(7);  
 format = "yyyyMMdd'.log'";  
 break;  
 case LogType.Monthly:  
 _timeSign = new DateTime(now.Year, now.Month, 1);  
 _timeSign = _timeSign.AddMonths(1);  
 format = "yyyyMM'.log'";  
 break;  
 case LogType.Annually:  
 _timeSign = new DateTime(now.Year, 1, 1);  
 _timeSign = _timeSign.AddYears(1);  
 format = "yyyy'.log'";  
 break;  
 }  
 return now.ToString(format);  
 }  
  
 ///  
 /// Write log file message   
 ///  
 ///  
 private void FileWrite(LogMessage msg)  
 {  
 try  
 {  
 if (_writer == null)  
 {  
 FileOpen();  
 }  
 else  
 {  
 //determine the log file is time sign   
 if (DateTime.Now >= _timeSign)  
 {  
 FileClose();  
 FileOpen();  
 }  
 _writer.WriteLine(Constants.LogMessageTime+msg.Datetime);  
 _writer.WriteLine(Constants.LogMessageType+msg.Type);  
 _writer.WriteLine(Constants.LogMessageContent+msg.Text);  
 _writer.Flush();  
 }  
 }  
 catch (Exception e)  
 {  
 Console.Out.Write(e);  
 }  
 }  
  
 ///  
 /// Open log file write log message   
 ///  
 private void FileOpen()  
 {  
 _writer = new StreamWriter(Path.Combine(_logDirectory, GetFilename()), true, Encoding.UTF8);  
 }  
  
 ///  
 /// Close log file   
 ///  
 private void FileClose()  
 {  
 if (_writer != null)  
 {  
 _writer.Flush();  
 _writer.Close();  
 _writer.Dispose();  
 _writer = null;  
 }  
 }  
  
 ///  
 /// Enqueue a new log message and release a semaphore   
 ///  
 ///Log message  
 public void Write(LogMessage msg)  
 {  
 if (msg != null)  
 {  
 lock (_lockObjeck)  
 {  
 _logMessages.Enqueue(msg);  
 _semaphore.Release();  
 }  
 }  
 }  
  
 ///  
 /// Write message by message content and type   
 ///  
 ///log message  
 ///message type  
 public void Write(string text, MessageType type)  
 {  
 Write(new LogMessage(text, type));  
 }  
  
 ///  
 /// Write Message by datetime and message content and type   
 ///  
 ///datetime  
 ///message content  
 ///message type  
 public void Write(DateTime dateTime, string text, MessageType type)  
 {  
 Write(new LogMessage(dateTime, text, type));  
 }  
  
 ///  
 /// Write message ty exception and message type   
 ///  
 ///exception  
 ///message type  
 public void Write(Exception e, MessageType type)  
 {  
 Write(new LogMessage(e.Message, type));  
 }  
  
 #region IDisposable member   
  
 ///  
 /// Dispose log   
 ///  
 public void Dispose()  
 {  
 _state = false;  
 }  
  
 #endregion   
}  
  
///  
/// Log Type   
///  
///Create log by daily or weekly or monthly or annually  
public enum LogType  
{  
 ///  
 /// Create log by daily   
 ///  
 Daily,  
  
 ///  
 /// Create log by weekly   
 ///  
 Weekly,  
  
 ///  
 /// Create log by monthly   
 ///  
 Monthly,  
  
 ///  
 /// Create log by annually   
 ///  
 Annually  
}  
  
///  
/// Log Message Class   
///  
public class LogMessage  
{  
  
 ///  
 /// Create Log message instance   
 ///  
 public LogMessage()  
 : this("", MessageType.Unknown)  
 {  
 }  
  
 ///  
 /// Crete log message by message content and message type   
 ///  
 ///message content  
 ///message type  
 public LogMessage(string text, MessageType messageType)  
 : this(DateTime.Now, text, messageType)  
 {  
 }  
  
 ///  
 /// Create log message by datetime and message content and message type   
 ///  
 ///date time  
 ///message content  
 ///message type  
 public LogMessage(DateTime dateTime, string text, MessageType messageType)  
 {  
 Datetime = dateTime;  
 Type = messageType;  
 Text = text;  
 }  
  
 ///  
 /// Gets or sets datetime   
 ///  
 public DateTime Datetime { get; set; }  
  
 ///  
 /// Gets or sets message content   
 ///  
 public string Text { get; set; }  
  
 ///  
 /// Gets or sets message type   
 ///  
 public MessageType Type { get; set; }  
  
 ///  
 /// Get Message to string   
 ///  
 ///  
 public new string ToString()  
 {  
 return Datetime.ToString(CultureInfo.InvariantCulture) + "t" + Text + "n";  
 }  
}  
  
///  
/// Log Message Type enum   
///  
public enum MessageType  
{  
 ///  
 /// unknown type   
 ///  
 Unknown,  
  
 ///  
 /// information type   
 ///  
 Information,  
  
 ///  
 /// warning type   
 ///  
 Warning,  
  
 ///  
 /// error type   
 ///  
 Error,  
  
 ///  
 /// success type   
 ///  
 Success  
}  

       Test Case:

public static void TestLog()  
{  
 Log.LogInstance.Write( "Test Message",MessageType.Information);  
 Log.LogInstance.Write("one",MessageType.Error);  
 Log.LogInstance.Write("two", MessageType.Success);  
 Log.LogInstance.Write("three", MessageType.Warning);  
} 

       运行结果:

C#开发高性能Log Help类设计开发,by 5lulu.com

C#开发高性能Log Help类设计开发


标签: log本文链接 http://tec.5lulu.com/detail/111ptn2e7zn78838f.html

我来评分 :6.1
0

转载注明:转自5lulu技术库

本站遵循:署名-非商业性使用-禁止演绎 3.0 共享协议

www.5lulu.com