C#开发高性能LogHelp类设计开发

概述

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

设计思想

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

简单的实现方式

 
 
 
 
  1. //  
  2. //Write Log  
  3. //  
  4. public static void WriteLog(string logFile, string msg)  
  5. {  
  6.     try 
  7.     {  
  8.         System.IO.StreamWriter sw = System.IO.File.AppendText(  
  9.                 logPath + LogFilePrefix +" "+ logFile + " " +  
  10.                 DateTime.Now.ToString("yyyyMMdd") + ".Log" 
  11.             );  
  12.         sw.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:  ") + msg);  
  13.         sw.Close();  
  14.     }  
  15.     catch (Exception)  
  16.     {  
  17.            
  18.         throw;  
  19.     }  

我们的设计图

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

代码设计

 
 
 
 
  1. ///   
  2. /// Author: spring yang  
  3. /// Create time:2012/3/30  
  4. /// Log Help class  
  5. ///   
  6. /// High performance log class  
  7. public class Log : IDisposable  
  8. {  
  9.     //Log Message queue  
  10.     private static Queue _logMessages;  
  11.  
  12.     //log save directory  
  13.     private static string _logDirectory;  
  14.  
  15.     //log write file state  
  16.     private static bool _state;  
  17.  
  18.     //log type  
  19.     private static LogType _logType;  
  20.  
  21.     //log life time sign  
  22.     private static DateTime _timeSign;  
  23.  
  24.     //log file stream writer  
  25.     private static StreamWriter _writer;  
  26.  
  27.     ///   
  28.     /// Wait enqueue wirte log message semaphore will release  
  29.     ///   
  30.     private Semaphore _semaphore;  
  31.  
  32.     ///   
  33.     /// Single instance  
  34.     ///   
  35.     private static Log _log;  
  36.  
  37.     ///   
  38.     /// Gets a single instance  
  39.     ///   
  40.     public static Log LogInstance  
  41.     {  
  42.         get { return _log ?? (_log = new Log()); }  
  43.     }  
  44.  
  45.     private object _lockObjeck;  
  46.  
  47.     ///   
  48.     /// Initialize Log instance  
  49.     ///   
  50.     private void Initialize()  
  51.     {  
  52.         if (_logMessages == null)  
  53.         {   _state = true;  
  54.             string logPath = System.Configuration.ConfigurationManager.AppSettings["LogDirectory"];  
  55.             _logDirectory = string.IsNullOrEmpty(logPath) ? ".\\log\\" : logPath;  
  56.             if (!Directory.Exists(_logDirectory)) Directory.CreateDirectory(_logDirectory);  
  57.             _logType = LogType.Daily;  
  58.             _lockObjeck=new object();  
  59.             _semaphore = new Semaphore(0, int.MaxValue, Constants.LogSemaphoreName);  
  60.             _logMessages = new Queue();  
  61.             var thread = new Thread(Work) {IsBackground = true};  
  62.             thread.Start();  
  63.         }  
  64.     }  
  65.  
  66.     ///   
  67.     /// Create a log instance  
  68.     ///   
  69.     private Log()  
  70.     {  
  71.         Initialize();  
  72.     }  
  73.  
  74.     ///   
  75.     /// Log save name type,default is daily  
  76.     ///   
  77.     public LogType LogType  
  78.     {  
  79.         get { return _logType; }  
  80.         set { _logType = value; }  
  81.     }  
  82.  
  83.     ///   
  84.     /// Write Log file  work method  
  85.     ///   
  86.     private void Work()  
  87.     {  
  88.         while (true)  
  89.         {  
  90.             //Determine log queue have record need wirte  
  91.             if (_logMessages.Count > 0)  
  92.             {  
  93.                 FileWriteMessage();  
  94.             }  
  95.             else 
  96.                 if (WaitLogMessage()) break;  
  97.         }  
  98.     }  
  99.  
  100.     ///   
  101.     /// Write message to log file  
  102.     ///   
  103.     private void FileWriteMessage()  
  104.     {  
  105.         LogMessage logMessage=null;  
  106.         lock (_lockObjeck)  
  107.         {  
  108.             if(_logMessages.Count>0)  
  109.             logMessage = _logMessages.Dequeue();  
  110.         }  
  111.         if (logMessage != null)  
  112.         {  
  113.             FileWrite(logMessage);  
  114.         }  
  115.     }  
  116.  
  117.     ///   
  118.     /// The thread wait a log message  
  119.     ///   
  120.     /// is close or not  
  121.     private bool WaitLogMessage()  
  122.     {  
  123.         //determine log life time is true or false  
  124.         if (_state)  
  125.         {  
  126.             WaitHandle.WaitAny(new WaitHandle[] { _semaphore }, -1, false);  
  127.             return false;  
  128.         }  
  129.         FileClose();  
  130.         return true;  
  131.     }  
  132.  
  133.     ///   
  134.     /// Gets file name by log type  
  135.     ///   
  136.     /// log file name  
  137.     private string GetFilename()  
  138.     {  
  139.         DateTime now = DateTime.Now;  
  140.         string format = "";  
  141.         switch (_logType)  
  142.         {  
  143.             case LogType.Daily:  
  144.                 _timeSign = new DateTime(now.Year, now.Month, now.Day);  
  145.                 _timeSign = _timeSign.AddDays(1);  
  146.                 format = "yyyyMMdd'.log'";  
  147.                 break;  
  148.             case LogType.Weekly:  
  149.                 _timeSign = new DateTime(now.Year, now.Month, now.Day);  
  150.                 _timeSign = _timeSign.AddDays(7);  
  151.                 format = "yyyyMMdd'.log'";  
  152.                 break;  
  153.             case LogType.Monthly:  
  154.                 _timeSign = new DateTime(now.Year, now.Month, 1);  
  155.                 _timeSign = _timeSign.AddMonths(1);  
  156.                 format = "yyyyMM'.log'";  
  157.                 break;  
  158.             case LogType.Annually:  
  159.                 _timeSign = new DateTime(now.Year, 1, 1);  
  160.                 _timeSign = _timeSign.AddYears(1);  
  161.                 format = "yyyy'.log'";  
  162.                 break;  
  163.         }  
  164.         return now.ToString(format);  
  165.     }  
  166.  
  167.     ///   
  168.     /// Write log file message  
  169.     ///   
  170.     ///   
  171.     private void FileWrite(LogMessage msg)  
  172.     {  
  173.         try 
  174.         {  
  175.             if (_writer == null)  
  176.             {  
  177.                 FileOpen();  
  178.             }  
  179.             else 
  180.             {  
  181.                 //determine the log file is time sign  
  182.                 if (DateTime.Now >= _timeSign)  
  183.                 {  
  184.                     FileClose();  
  185.                     FileOpen();  
  186.                 }  
  187.                 _writer.WriteLine(Constants.LogMessageTime+msg.Datetime);  
  188.                 _writer.WriteLine(Constants.LogMessageType+msg.Type);  
  189.                 _writer.WriteLine(Constants.LogMessageContent+msg.Text);  
  190.                 _writer.Flush();  
  191.             }  
  192.         }  
  193.         catch (Exception e)  
  194.         {  
  195.             Console.Out.Write(e);  
  196.         }  
  197.     }  
  198.  
  199.     ///   
  200.     /// Open log file write log message  
  201.     ///   
  202.     private void FileOpen()  
  203.     {  
  204.         _writer = new StreamWriter(Path.Combine(_logDirectory, GetFilename()), true, Encoding.UTF8);  
  205.     }  
  206.  
  207.     ///   
  208.     /// Close log file  
  209.     ///   
  210.     private void FileClose()  
  211.     {  
  212.         if (_writer != null)  
  213.         {  
  214.             _writer.Flush();  
  215.             _writer.Close();  
  216.             _writer.Dispose();  
  217.             _writer = null;  
  218.         }  
  219.     }  
  220.  
  221.     ///   
  222.     /// Enqueue a new log message and release a semaphore  
  223.     ///   
  224.     /// Log message  
  225.     public void Write(LogMessage msg)  
  226.     {  
  227.         if (msg != null)  
  228.         {  
  229.             lock (_lockObjeck)  
  230.             {  
  231.                 _logMessages.Enqueue(msg);  
  232.                 _semaphore.Release();  
  233.             }  
  234.         }  
  235.     }  
  236.  
  237.     ///   
  238.     /// Write message by message content and type  
  239.     ///   
  240.     /// log message  
  241.     /// message type  
  242.     public void Write(string text, MessageType type)  
  243.     {  
  244.         Write(new LogMessage(text, type));  
  245.     }  
  246.  
  247.     ///   
  248.     /// Write Message by datetime and message content and type  
  249.     ///   
  250.     /// datetime  
  251.     /// message content  
  252.     /// message type  
  253.     public void Write(DateTime dateTime, string text, MessageType type)  
  254.     {  
  255.         Write(new LogMessage(dateTime, text, type));  
  256.     }  
  257.  
  258.     ///   
  259.     /// Write message ty exception and message type  
  260.     ///   
  261.     /// exception  
  262.     /// message type  
  263.     public void Write(Exception e, MessageType type)  
  264.     {  
  265.         Write(new LogMessage(e.Message, type));  
  266.     }  
  267.  
  268.     #region IDisposable member  
  269.  
  270.     ///   
  271.     /// Dispose log  
  272.     ///   
  273.     public void Dispose()  
  274.     {  
  275.         _state = false;  
  276.     }  
  277.  
  278.     #endregion  
  279. }  
  280.  
  281. ///   
  282. /// Log Type  
  283. ///   
  284. /// Create log by daily or weekly or monthly or annually  
  285. public enum LogType  
  286. {  
  287.     ///   
  288.     /// Create log by daily  
  289.     ///   
  290.     Daily,  
  291.  
  292.     ///   
  293.     /// Create log by weekly  
  294.     ///   
  295.     Weekly,  
  296.  
  297.     ///   
  298.     /// Create log by monthly  
  299.     ///   
  300.     Monthly,  
  301.  
  302.     ///   
  303.     /// Create log by annually  
  304.     ///   
  305.     Annually  
  306. }  
  307.  
  308. ///   
  309. /// Log Message Class  
  310. ///   
  311. public class LogMessage  
  312. {  
  313.  
  314.     ///   
  315.     /// Create Log message instance  
  316.     ///   
  317.     public LogMessage()  
  318.         : this("", MessageType.Unknown)  
  319.     {  
  320.     }  
  321.  
  322.     ///   
  323.     /// Crete log message by message content and message type  
  324.     ///   
  325.     /// message content  
  326.     /// message type  
  327.     public LogMessage(string text, MessageType messageType)  
  328.         : this(DateTime.Now, text, messageType)  
  329.     {  
  330.     }  
  331.  
  332.     ///   
  333.     /// Create log message by datetime and message content and message type  
  334.     ///   
  335.     /// date time   
  336.     /// message content  
  337.     /// message type  
  338.     public LogMessage(DateTime dateTime, string text, MessageType messageType)  
  339.     {  
  340.         Datetime = dateTime;  
  341.         Type = messageType;  
  342.         Text = text;  
  343.     }  
  344.  
  345.     ///   
  346.     /// Gets or sets datetime  
  347.     ///   
  348.     public DateTime Datetime { get; set; }  
  349.  
  350.     ///   
  351.     /// Gets or sets message content  
  352.     ///   
  353.     public string Text { get; set; }  
  354.  
  355.     ///   
  356.     /// Gets or sets message type  
  357.     ///   
  358.     public MessageType Type { get; set; }  
  359.  
  360.     ///   
  361.     /// Get Message to string  
  362.     ///   
  363.     ///   
  364.     public new string ToString()  
  365.     {  
  366.         return Datetime.ToString(CultureInfo.InvariantCulture) + "\t" + Text + "\n";  
  367.     }  
  368. }  
  369.  
  370. ///   
  371. /// Log Message Type enum  
  372. ///   
  373. public enum MessageType  
  374. {  
  375.     ///   
  376.     /// unknown type  
  377.     ///   
  378.     Unknown,  
  379.  
  380.     ///   
  381.     /// information type  
  382.     ///   
  383.     Information,  
  384.  
  385.     ///   
  386.     /// warning type  
  387.     ///   
  388.     Warning,  
  389.  
  390.     ///   
  391.     /// error type  
  392.     ///   
  393.     Error,  
  394.  
  395.     ///   
  396.     /// success type  
  397.     ///   
  398.     Success  
  399. }  

Test Case:

 
 
 
 
  1. public static void TestLog()  
  2. {  
  3.     Log.LogInstance.Write(  "Test Message",MessageType.Information);  
  4.     Log.LogInstance.Write("one",MessageType.Error);  
  5.     Log.LogInstance.Write("two", MessageType.Success);  
  6.     Log.LogInstance.Write("three", MessageType.Warning);  

运行结果:

接受Mainz的建议,改了部分代码。

Mainz:http://www.cnblogs.com/Mainz/

当前名称:C#开发高性能LogHelp类设计开发
URL标题:http://www.shufengxianlan.com/qtweb/news49/433849.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联