The c simple log class queue which can replace log4j logs implements class code sharing
using System;using System.Collections.Generic;using System.Globalization;using System.IO;using System.Linq;using System.Text;using System.Threading;namespace LogisTrac{ /// <summary> /// The log class /// The queue Can be in / month / weeks / day / The size of the segmentation /// Call method: /// Log.Instance.LogDirectory=@"C:\"; The default is to run the program directory /// Log.Instance.FileNamePrefix="cxd"; The default is log_ /// Log.Instance.CurrentMsgType = MsgLevel.Debug; The default is Error /// Log.Instance.logFileSplit = LogFileSplit.Daily; Log split type LogFileSplit.Sizely The size of the /// Log.Instance.MaxFileSize = 5; Default size is 2M , only LogFileSplit.Sizely The configuration is valid /// Log.Instance.LogWrite("aa"); /// Log.Instance.LogWrite("aa", MsgLevel.Debug); /// </summary> public class Log : IDisposable { private static Log _instance = null; private static readonly object _synObject = new object(); /// <summary> /// The singleton /// </summary> public static Log Instance { get { if (null == _instance) { lock (_synObject) { if (null == _instance) { _instance = new Log(); } } } return _instance; } } /// <summary> /// The cache queue for the log object /// </summary> private static Queue<Msg> _msgs; /// <summary> /// The control flag for the log writing thread ture In the writing |false Didn't write /// </summary> private bool _state; private string _logDirectory = AppDomain.CurrentDomain.BaseDirectory; /// <summary> /// Log files are stored in directories /// </summary> public string LogDirectory { get { return _logDirectory; } set { _logDirectory = value; } } private LogFileSplit _logFileSplit = LogFileSplit.Sizely; /// <summary> /// Log split type /// </summary> public LogFileSplit logFileSplit { get { return _logFileSplit; } set { _logFileSplit = value; } } private MsgLevel _currentLogLevel = MsgLevel.Error; /// <summary> /// Current logging level /// </summary> public MsgLevel CurrentMsgType { get { return _currentLogLevel; } set { _currentLogLevel = value; } } /// <summary> /// Currently responsible for logging the name of the log file /// </summary> private string _currentFileName="1.log"; private string _fileNamePrefix = "log_"; /// <summary> /// The prefix name of the log, by default log_ /// </summary> public string FileNamePrefix { get { return _fileNamePrefix; } set { _fileNamePrefix = value; } } /// <summary> /// A time marker for the log file lifecycle /// </summary> private DateTime _CurrentFileTimeSign = new DateTime(); private int _maxFileSize = 2; /// <summary> /// The default size for a single log file ( Unit: $ ) /// </summary> public int MaxFileSize { get { return _maxFileSize; } set { _maxFileSize = value; } } /// <summary> /// File suffix /// </summary> private int _fileSymbol = 0; /// <summary> /// Current file size ( Units: B) /// </summary> private long _fileSize = 0; /// <summary> /// Log files are written into the stream object /// </summary> private StreamWriter _writer; /// <summary> /// Create a new instance of the log object , Creates a type based on the specified log file path and the specified log file /// </summary> private Log() { if (_msgs == null) { GetCurrentFilename(); _state = true; _msgs = new Queue<Msg>(); Thread thread = new Thread(work); thread.Start(); } } // The method by which the log file is written to the thread execution private void work() { while (true) { // Determines if there is a log to write in the queue if (_msgs.Count > 0) { Msg msg = null; lock (_msgs) { msg = _msgs.Dequeue(); if (msg != null) { FileWrite(msg); } } } else { // Determines whether a message has been sent to terminate the log and close it if (_state) { Thread.Sleep(1); } else { FileClose(); } } } } /// <summary> /// Gets the log file name based on the log type , And at the same time create a time marker for the file to expire /// The decision to create a new file is made by determining the expiration date of the file. /// </summary> /// <returns></returns> private void GetCurrentFilename() { DateTime now = DateTime.Now; string format = ""; switch (_logFileSplit) { case LogFileSplit.Daily: _CurrentFileTimeSign = new DateTime(now.Year, now.Month, now.Day); _CurrentFileTimeSign = _CurrentFileTimeSign.AddDays(1); format = now.ToString("yyyyMMdd'.log'"); break; case LogFileSplit.Weekly: _CurrentFileTimeSign = new DateTime(now.Year, now.Month, now.Day); _CurrentFileTimeSign = _CurrentFileTimeSign.AddDays(7); format = now.ToString("yyyyMMdd'.log'"); break; case LogFileSplit.Monthly: _CurrentFileTimeSign = new DateTime(now.Year, now.Month, 1); _CurrentFileTimeSign = _CurrentFileTimeSign.AddMonths(1); format = now.ToString("yyyyMM'.log'"); break; case LogFileSplit.Annually: _CurrentFileTimeSign = new DateTime(now.Year, 1, 1); _CurrentFileTimeSign = _CurrentFileTimeSign.AddYears(1); format = now.ToString("yyyy'.log'"); break; default: _fileSymbol++; format = _fileSymbol.ToString() + ".log"; break; } if (File.Exists(Path.Combine(LogDirectory, _currentFileName))) { _fileSize = new FileInfo(Path.Combine(LogDirectory, _currentFileName)).Length; } else { _fileSize = 0; } _currentFileName=_fileNamePrefix + format.Trim(); } // Method to write log text to a file private void FileWrite(Msg msg) { try { if (_writer == null) { FileOpen(); } if (_writer != null) { // Determine the file expiration mark , If the current file expires, close the current file to create a new log file if ((_logFileSplit != LogFileSplit.Sizely && DateTime.Now >= _CurrentFileTimeSign)|| (_logFileSplit == LogFileSplit.Sizely && ((double)_fileSize / 1048576) > _maxFileSize)) { GetCurrentFilename(); FileClose(); FileOpen(); } _writer.Write(msg.datetime); _writer.Write('\t'); _writer.Write(msg.type); _writer.Write('\t'); _writer.WriteLine(msg.text); _fileSize+=System.Text.Encoding.UTF8.GetBytes(msg.ToString()).Length; _writer.Flush(); } } catch (Exception e) { Console.Out.Write(e); } } // Open file ready to write private void FileOpen() { _writer = new StreamWriter(LogDirectory + _currentFileName, true, Encoding.UTF8); } // Close the open log file private void FileClose() { if (_writer != null) { _writer.Flush(); _writer.Close(); _writer.Dispose(); _writer = null; } } /// <summary> /// Write to new log , According to the specified log object Msg /// </summary> /// <param name="msg"> Log content object </param> private void LogWrite(Msg msg) { if (msg.type < CurrentMsgType) return; if (_msgs != null) { lock (_msgs) { _msgs.Enqueue(msg); } } } /// <summary> /// Write to new log , According to the specified log content and information type , Write a new log using the current time for the log time /// </summary> /// <param name="text"> Log contents </param> /// <param name="type"> Information types </param> public void LogWrite(string text, MsgLevel type) { LogWrite(new Msg(text, type)); } /// <summary> /// Write to new log , According to the specified log content /// </summary> /// <param name="text"> Log contents </param> public void LogWrite(string text) { LogWrite(text, MsgLevel.Debug); } /// <summary> /// Write to new log , Writes a new log based on the specified log time, log content, and information type /// </summary> /// <param name="dt"> Log time </param> /// <param name="text"> Log contents </param> /// <param name="type"> Information types </param> public void LogWrite(DateTime dt, string text, MsgLevel type) { LogWrite(new Msg(dt, text, type)); } /// <summary> /// Write to new log , Writes the new log based on the specified exception class and information type /// </summary> /// <param name="e"> The exception object </param> /// <param name="type"> Information types </param> public void LogWrite(Exception e) { LogWrite(new Msg(e.Message, MsgLevel.Error)); } /// <summary> /// Destroy log object /// </summary> public void Dispose() { _state = false; } } /// <summary> /// 1 Two logged objects /// </summary> public class Msg { /// <summary> /// Create a new logging instance ; The contents of the log record are empty , The message type is MsgType.Unknown, The log time is the current time /// </summary> public Msg() : this("", MsgLevel.Debug) { } /// <summary> /// Create a new logging instance ; The log event is the current time /// </summary> /// <param name="t"> The textual content of the log </param> /// <param name="p"> The type of message logged </param> public Msg(string t, MsgLevel p) : this(DateTime.Now, t, p) { } /// <summary> /// Create a new logging instance ; /// </summary> /// <param name="dt"> Time logged </param> /// <param name="t"> The textual content of the log </param> /// <param name="p"> The type of message logged </param> public Msg(DateTime dt, string t, MsgLevel p) { datetime = dt; type = p; text = t; } /// <summary> /// Time logged /// </summary> public DateTime datetime { get; set; } /// <summary> /// The contents of the log /// </summary> public string text { get; set; } /// <summary> /// The log level /// </summary> public MsgLevel type { get; set; } public new string ToString() { return datetime.ToString(CultureInfo.InvariantCulture) + "\t" + text + "\n"; } } /// <summary> /// Enumeration of log file splitting /// </summary> /// <remarks> Log type enumeration indicates how log files are created , If you have more logs, consider creating them daily 1 Log files /// If the logs are small, consider creating them weekly, monthly, or annually 1 Log files </remarks> public enum LogFileSplit { /// <summary> /// This enumeration indicates daily creation 1 Two new log files /// </summary> Daily, /// <summary> /// This enumeration indicates weekly creation 1 Two new log files /// </summary> Weekly, /// <summary> /// This enumeration indicates monthly creation 1 Two new log files /// </summary> Monthly, /// <summary> /// This enumeration indicates annual creation 1 Two new log files /// </summary> Annually, /// <summary> /// The log file size exceeds the specified creation 1 Two new log files, MaxFileSize Specify the size /// </summary> Sizely } /// <summary> /// Log level type Debug=0 Infor Warn Error /// </summary> public enum MsgLevel { /// <summary> /// Debugging information /// </summary> Debug = 0, /// <summary> /// Logging that indicates a common information type /// </summary> Infor, /// <summary> /// Logging that indicates the type of warning message /// </summary> Warn, /// <summary> /// Logging that indicates the type of error message /// </summary> Error }}