< 返回技术文档列表

C#开发高性能Log Help类设计开发的示例分析

发布时间:2021-11-07 01:51:51⊙投诉举报

本篇文章给大家分享的是有关C#开发高性能Log Help类设计开发的示例分析,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

概述

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

设计思想

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

简单的实现方式

//<summary>  //Write Log  //<summary>  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;      }  }

我们的设计图

C#开发高性能Log Help类设计开发的示例分析

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

代码设计

/// <summary>  /// Author: spring yang  /// Create time:2012/3/30  /// Log Help class  /// </summary>  /// <remarks>High performance log class</remarks>  public class Log : IDisposable  {      //Log Message queue      private static Queue<LogMessage> _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;       /// <summary>      /// Wait enqueue wirte log message semaphore will release      /// </summary>      private Semaphore _semaphore;       /// <summary>      /// Single instance      /// </summary>      private static Log _log;       /// <summary>      /// Gets a single instance      /// </summary>      public static Log LogInstance      {          get { return _log ?? (_log = new Log()); }      }       private object _lockObjeck;       /// <summary>      /// Initialize Log instance      /// </summary>      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<LogMessage>();              var thread = new Thread(Work) {IsBackground = true};              thread.Start();          }      }       /// <summary>      /// Create a log instance      /// </summary>      private Log()      {          Initialize();      }       /// <summary>      /// Log save name type,default is daily      /// </summary>      public LogType LogType      {          get { return _logType; }          set { _logType = value; }      }       /// <summary>      /// Write Log file  work method      /// </summary>      private void Work()      {          while (true)          {              //Determine log queue have record need wirte              if (_logMessages.Count > 0)              {                  FileWriteMessage();              }              else                 if (WaitLogMessage()) break;          }      }       /// <summary>      /// Write message to log file      /// </summary>      private void FileWriteMessage()      {          LogMessage logMessage=null;          lock (_lockObjeck)          {              if(_logMessages.Count>0)              logMessage = _logMessages.Dequeue();          }          if (logMessage != null)          {              FileWrite(logMessage);          }      }       /// <summary>      /// The thread wait a log message      /// </summary>      /// <returns>is close or not</returns>      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;      }       /// <summary>      /// Gets file name by log type      /// </summary>      /// <returns>log file name</returns>      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);      }       /// <summary>      /// Write log file message      /// </summary>      /// <param name="msg"></param>      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);          }      }       /// <summary>      /// Open log file write log message      /// </summary>      private void FileOpen()      {          _writer = new StreamWriter(Path.Combine(_logDirectory, GetFilename()), true, Encoding.UTF8);      }       /// <summary>      /// Close log file      /// </summary>      private void FileClose()      {          if (_writer != null)          {              _writer.Flush();              _writer.Close();              _writer.Dispose();              _writer = null;          }      }       /// <summary>      /// Enqueue a new log message and release a semaphore      /// </summary>      /// <param name="msg">Log message</param>      public void Write(LogMessage msg)      {          if (msg != null)          {              lock (_lockObjeck)              {                  _logMessages.Enqueue(msg);                  _semaphore.Release();              }          }      }       /// <summary>      /// Write message by message content and type      /// </summary>      /// <param name="text">log message</param>      /// <param name="type">message type</param>      public void Write(string text, MessageType type)      {          Write(new LogMessage(text, type));      }       /// <summary>      /// Write Message by datetime and message content and type      /// </summary>      /// <param name="dateTime">datetime</param>      /// <param name="text">message content</param>      /// <param name="type">message type</param>      public void Write(DateTime dateTime, string text, MessageType type)      {          Write(new LogMessage(dateTime, text, type));      }       /// <summary>      /// Write message ty exception and message type      /// </summary>      /// <param name="e">exception</param>      /// <param name="type">message type</param>      public void Write(Exception e, MessageType type)      {          Write(new LogMessage(e.Message, type));      }       #region IDisposable member       /// <summary>      /// Dispose log      /// </summary>      public void Dispose()      {          _state = false;      }       #endregion  }   /// <summary>  /// Log Type  /// </summary>  /// <remarks>Create log by daily or weekly or monthly or annually</remarks>  public enum LogType  {      /// <summary>      /// Create log by daily      /// </summary>      Daily,       /// <summary>      /// Create log by weekly      /// </summary>      Weekly,       /// <summary>      /// Create log by monthly      /// </summary>      Monthly,       /// <summary>      /// Create log by annually      /// </summary>      Annually  }   /// <summary>  /// Log Message Class  /// </summary>  public class LogMessage  {       /// <summary>      /// Create Log message instance      /// </summary>      public LogMessage()          : this("", MessageType.Unknown)      {      }       /// <summary>      /// Crete log message by message content and message type      /// </summary>      /// <param name="text">message content</param>      /// <param name="messageType">message type</param>      public LogMessage(string text, MessageType messageType)          : this(DateTime.Now, text, messageType)      {      }       /// <summary>      /// Create log message by datetime and message content and message type      /// </summary>      /// <param name="dateTime">date time </param>      /// <param name="text">message content</param>      /// <param name="messageType">message type</param>      public LogMessage(DateTime dateTime, string text, MessageType messageType)      {          Datetime = dateTime;          Type = messageType;          Text = text;      }       /// <summary>      /// Gets or sets datetime      /// </summary>      public DateTime Datetime { get; set; }       /// <summary>      /// Gets or sets message content      /// </summary>      public string Text { get; set; }       /// <summary>      /// Gets or sets message type      /// </summary>      public MessageType Type { get; set; }       /// <summary>      /// Get Message to string      /// </summary>      /// <returns></returns>      public new string ToString()      {          return Datetime.ToString(CultureInfo.InvariantCulture) + "\t" + Text + "\n";      }  }   /// <summary>  /// Log Message Type enum  /// </summary>  public enum MessageType  {      /// <summary>      /// unknown type      /// </summary>      Unknown,       /// <summary>      /// information type      /// </summary>      Information,       /// <summary>      /// warning type      /// </summary>      Warning,       /// <summary>      /// error type      /// </summary>      Error,       /// <summary>      /// success type      /// </summary>      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类设计开发的示例分析

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

以上就是C#开发高性能Log Help类设计开发的示例分析,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注血鸟云行业资讯频道。


/template/Home/Zkeys/PC/Static