The c simple log class queue which can replace log4j logs implements class code sharing

  • 2020-05-27 06:59:53
  • OfStack


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


Related articles: