博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C#开发高性能Log Help 类设计开发
阅读量:6941 次
发布时间:2019-06-27

本文共 11257 字,大约阅读时间需要 37 分钟。

概述

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

设计思想

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

 

简单的实现方式

//        //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;            }        }

我们的设计图

而后我们在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);        }

 

 

运行结果:

 

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

Mainz:

 

欢迎各位参与讨论,如果觉得对你有帮助,请点击    推荐下,万分谢谢.

作者:

出处:

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

转载于:https://www.cnblogs.com/springyangwc/archive/2012/03/30/2425822.html

你可能感兴趣的文章
问题 F: 背包问题
查看>>
又爱又恨的eval
查看>>
“pip failed to create process”的问题
查看>>
搞个Windows服务程序
查看>>
PAT1010 Radix (25)(模拟)
查看>>
ELK安装配置步骤(实战三)
查看>>
windows 2008 "运行安装程序时发生 -5006 0x80070002"解决
查看>>
CF940A Points on the line 思维
查看>>
ISE综合工具XST综合约束相关
查看>>
linux daemon(2)
查看>>
前馈神经网络练习:使用tensorflow进行葡萄酒种类识别
查看>>
C++11 多线程编程 使用lambda创建std::thread (生产/消费者模式)
查看>>
UVA 610 Street Directions 双连通分量
查看>>
比尔盖茨的都市传说
查看>>
ss-R:// 链接的含义
查看>>
Caliburn.Micro 关闭父窗体打开子窗体
查看>>
powershell实现离线ip扫描
查看>>
Fragment使用findFragmentById返回null
查看>>
Logger日志级别说明及设置方法、说明
查看>>
SPOJ PGCD(莫比乌斯反演)
查看>>