unity 日志工具类

/// <summary>
    /// 日志文件模块,使用多线程来进行写日志文件
    /// </summary>
    public class LoggerTool
    {
        private static LoggerTool sLogFileModule;

        /// <summary>
        /// 开启写日志
        /// </summary>
        public static void Open()
        {
            if (sLogFileModule == null)
            {
                sLogFileModule = new LoggerTool();
            }
        }

        public static void Close()
        {
            if (sLogFileModule != null)
            {
                sLogFileModule.Dispose();
                sLogFileModule = null;
            }
        }

        #region 私有

        private class LogData
        {
            public string log { get; set; }
            public string trace { get; set; }
            public LogType level { get; set; }
        }

        private StreamWriter m_StreamWriter;
        private ManualResetEvent m_ManualResetEvent;
        private ConcurrentQueue<LogData> m_ConcurrentQueue; // 安全队列
        private bool m_ThreadRunning;

        private string logDirectoryPath = string.Empty;
        
        private string logFilePath = string.Empty;

        private const string LOG_FILE_NAME = "MyopiaCHomeEditionA_log.log";

        private readonly int MAX_FILE_SIZE = 1024 * 1024 * 5;

        private LoggerTool()
        {
#if UNITY_EDITOR
            logDirectoryPath = Path.Combine(System.IO.Directory.GetCurrentDirectory(), "Logs/");
#else
            logDirectoryPath = Path.Combine(Application.persistentDataPath, "Logs/");
#endif

            logFilePath = Path.Combine(logDirectoryPath, LOG_FILE_NAME);

            logFilePath = logFilePath.Replace("\\", "/");

            if (!Directory.Exists(logDirectoryPath))
            {
                Directory.CreateDirectory(logDirectoryPath);
            }

            Debug.Log($"logFilePath:{logFilePath}");

            Start();

            Application.logMessageReceivedThreaded += OnLogMessageReceivedThreaded;
        }

        private void Start()
        {
            if (File.Exists(logFilePath))
            {
                m_StreamWriter = new StreamWriter(logFilePath, true);
            }
            else
            {
                m_StreamWriter = new StreamWriter(logFilePath);
            }

            m_StreamWriter.Write($"\n\n\n --------======{DateTime.Now.ToString("yyyy年MM月dd日HH时mm分ss秒")}======--------\n");

            m_StreamWriter.Flush();

            m_ManualResetEvent = new ManualResetEvent(false);
            m_ConcurrentQueue = new ConcurrentQueue<LogData>();
            m_ThreadRunning = true;


            var fileThread = new Thread(FileLogThread);
            fileThread.Start();
        }

        private void Stop()
        {
            try
            {
                m_ThreadRunning = false;
                m_ManualResetEvent.Set();
                m_StreamWriter.Close();
                m_StreamWriter.Dispose();
                m_StreamWriter = null;
            }
            catch (Exception e)
            {
                //这里异常了。
                Debug.Log(e.ToString());
            }
        }


        private void Dispose()
        {
            Stop();
        }

        private void OnLogMessageReceivedThreaded(string logString, string stackTrace, LogType type)
        {
            if (m_ConcurrentQueue == null) return;

            m_ConcurrentQueue.Enqueue(new LogData() { log = logString, trace = stackTrace, level = type });
            m_ManualResetEvent.Set();
        }

        private void FileLogThread()
        {
            while (m_ThreadRunning)
            {
                m_ManualResetEvent.WaitOne();

                if (m_StreamWriter == null)
                {
                    break;
                }

                //判断文件大小,如果文件超过大小,则备份文件并重新开始写文件
                FileInfo fileInfo = new FileInfo(logFilePath);

                if (fileInfo.Length >= MAX_FILE_SIZE)
                {
                    //备份文件
                    Stop();

                    //检测文件夹中有多少文件,超过十个就删掉之前的。
                    DirectoryInfo dirInfo = new DirectoryInfo(logDirectoryPath);

                    FileInfo[] dirFiles = dirInfo.GetFiles();

                    string fn = Path.GetFileNameWithoutExtension(LOG_FILE_NAME);

                    if (dirFiles.Length >= 5)
                    {
                        foreach (var dirf in dirFiles)
                        {
                            if (dirf.Name.Equals(LOG_FILE_NAME) || !dirf.FullName.Contains(fn))
                            {
                                continue;
                            }

                            File.Delete(dirf.FullName);
                        }
                    }

                    string targetLogFilePath = Path.Combine(logDirectoryPath, string.Format("MyopiaCHomeEditionA_log_{0}.log.bak", DateTime.Now.ToString("yyyyMMddHHmmss")));

                    File.Move(logFilePath, targetLogFilePath);

                    //重新开始写文件
                    Start();

                    m_ManualResetEvent.WaitOne();

                    return;
                }


                LogData msg;

                while (m_ConcurrentQueue.Count > 0 && m_ConcurrentQueue.TryDequeue(out msg))
                {
                    if (!m_ThreadRunning)
                    {
                        break;
                    }

                    if (msg.level == LogType.Log)
                    {
                        m_StreamWriter.Write($"[Log][{DateTime.Now.ToString("yyyyMMddHHmmss")}]{msg.log}");
                    }
                    else if (msg.level == LogType.Warning)
                    {
                        m_StreamWriter.Write('\n');
                        m_StreamWriter.Write($"[Warning][{DateTime.Now.ToString("yyyyMMddHHmmss")}]{msg.log}");
                        m_StreamWriter.Write('\n');
                        m_StreamWriter.Write(msg.trace);
                    }
                    else
                    {
                        m_StreamWriter.Write('\n');
                        m_StreamWriter.Write($"[Error][{DateTime.Now.ToString("yyyyMMddHHmmss")}]{msg.log}");
                        m_StreamWriter.Write('\n');
                        m_StreamWriter.Write(msg.trace);
                    }

                    m_StreamWriter.Write("\r\n");
                }

                if (m_ThreadRunning)
                {
                    m_StreamWriter?.Flush();

                    m_ManualResetEvent?.Reset();
                }

                Thread.Sleep(1);
            }
        }

        #endregion
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值