| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340 | using System;using System.Collections.Generic;using System.Globalization;using System.IO;using System.Text;using UnityEngine;namespace XCharts.Runtime{    /// <summary>    /// Log system. Used to output logs with date and log type, support output to file, support custom output log type.    /// ||日志系统。用于输出带日期和日志类型的日志,支持输出到文件,支持自定义输出的日志类型。    /// </summary>    public class XLog : MonoBehaviour    {        public const int ALL = 0;        public const int WARNING = 1;        public const int DEBUG = 2;        public const int INFO = 3;        public const int PROTO = 4;        public const int VITAL = 5;        public const int ERROR = 6;        public const int EXCEPTION = 7;        private const int MAX_ERROR_LOG = 20;        public static bool isReportBug = false;        public static bool isOutputLog = false;        public static bool isUploadLog = false;        public static bool isCloseOutLog = false;        public static int errorCount = 0;        public static int exceptCount = 0;        public static int uploadTick = 20;        public static int reportTick = 10;        private static bool initFileSuccess = false;        private static bool[] levelList = new bool[] { true, true, true, true, true, true, true, true };        private static List<string> writeList = new List<string>();        private static float uploadTime = 0;        private static float reportTime = 0;        private string outpath;        private StreamWriter writer;        private string[] temp;        public int logCount = 0;        public static List<string> errorList = new List<string>();        private static object m_Lock = new object();        private static XLog m_Instance;        public static XLog Instance        {            get            {                // if (m_Instance == null)                // {                //     GameObject go = new GameObject("XLog");                //     m_Instance = go.AddComponent<XLog>();                //     DontDestroyOnLoad(go);                // }                return m_Instance;            }        }        void Awake()        {            if (m_Instance != null)            {                Destroy(gameObject);                return;            }            m_Instance = this;            InitLogFile();            // Application.logMessageReceived += HandleLog;            Application.logMessageReceivedThreaded += HandleLog;        }        void OnDestroy()        {            if (writer != null)            {                writer.Close();                writer.Dispose();            }            // Application.logMessageReceived -= HandleLog;            Application.logMessageReceivedThreaded -= HandleLog;        }        void Update()        {            uploadTime += Time.deltaTime;            reportTime += Time.deltaTime;            lock (m_Lock)            {                if (writeList.Count > 0)                {                    logCount = writeList.Count;                    if (!initFileSuccess)                    {                        writeList.Clear();                        return;                    }                    try                    {                        temp = writeList.ToArray();                        int count = 0;                        foreach (var str in temp)                        {                            count++;                            writer.WriteLine(str);                            writeList.Remove(str);                            if (count > 10) break;                        }                        writer.Flush();                    }                    catch (Exception e)                    {                        initFileSuccess = false;                        //Application.logMessageReceived -= HandleLog;                        Application.logMessageReceivedThreaded -= HandleLog;                        UnityEngine.Debug.LogError("write outlog.txt error:" + e.Message);                    }                }            }        }        private void InitLogFile()        {            ClearAllLog();            XLog.EnableLog(ALL);            if (Application.platform == RuntimePlatform.Android || Application.platform == RuntimePlatform.IPhonePlayer)            {                XLog.ClearAllLog();                XLog.EnableLog(VITAL);                XLog.EnableLog(ERROR);                XLog.isReportBug = true;                XLog.isUploadLog = true;            }            else            {                XLog.isUploadLog = false;                XLog.isReportBug = false;            }            outpath = GetLogOutputPath();            try            {                if (File.Exists(outpath))                {                    File.Delete(outpath);                }                writer = new StreamWriter(outpath, false, Encoding.UTF8);                writer.WriteLine(GetNowTime() + "init file success!!");                UnityEngine.Debug.Log(GetNowTime() + "init file success:" + outpath);                writer.Flush();                initFileSuccess = true;            }            catch (Exception e)            {                initFileSuccess = false;                Application.logMessageReceived -= HandleLog;                UnityEngine.Debug.LogError("write outlog.txt error:" + e.Message);            }        }        private static string GetLogOutputPath()        {#if UNITY_EDITOR            string path = Application.dataPath + "/../outlog.txt";#else            string path = Application.persistentDataPath + "/outlog.txt";            if (Application.platform == RuntimePlatform.Android || Application.platform == RuntimePlatform.IPhonePlayer)            {                path = Application.persistentDataPath + "/outlog.txt";            }            else            {                path = Application.dataPath + "/../outlog.txt";            }#endif            return path;        }        private void HandleLog(string logString, string stackTrace, LogType type)        {            lock (m_Lock)            {                if (!initFileSuccess) return;                int index = logString.IndexOf("stack traceback");                if (index > 0)                {                    string log = logString.Substring(0, index);                    string trace = logString.Substring(index, logString.Length - index);                    logString = log;                    stackTrace = trace;                }                if (type == LogType.Log)                {                }                else if (type == LogType.Error)                {                    if (logString.IndexOf("LUA ERROR") > 0 || logString.IndexOf("stack traceback") > 0) exceptCount++;                    else errorCount++;                    writeList.Add(logString);                    //writeList.Add(stackTrace + "\n");                    if (errorList.Count >= MAX_ERROR_LOG)                    {                        errorList.RemoveAt(1);                    }                    if (errorList.Count < MAX_ERROR_LOG)                    {                        errorList.Add(logString);                       // errorList.Add(stackTrace + "\n");                    }                }                else if (type == LogType.Exception)                {                    exceptCount++;                    writeList.Add(logString);                    writeList.Add(stackTrace + "\n");                    if (errorList.Count >= MAX_ERROR_LOG)                    {                        errorList.RemoveAt(1);                    }                    if (errorList.Count < MAX_ERROR_LOG)                    {                        errorList.Add(logString);                        errorList.Add(stackTrace + "\n");                    }                }            }        }        public static void FlushLog()        {            var instance = XLog.Instance;            if (instance != null && instance.writer != null)            {                for (int i = 0; i < writeList.Count; i++)                {                    instance.writer.WriteLine(writeList[i]);                }                instance.writer.Flush();                writeList.Clear();            }        }        public static void EnableLog(int logType)        {            if (logType < 0 || logType >= levelList.Length) return;            levelList[logType] = true;        }        public static void ClearAllLog()        {            for (int i = 0; i < levelList.Length; i++)            {                levelList[i] = false;            }        }        public static bool CanLog(int level)        {            if (level < 0 || level >= levelList.Length) return false;            return levelList[level] || levelList[0];        }        public static void Log(string log)        {            Debug(log);        }        public static void LogError(string log)        {            Error(log);        }        public static void LogWarning(string log)        {            Warning(log);        }        public static void Debug(string log)        {            if (!CanLog(DEBUG)) return;            UnityEngine.Debug.Log(GetNowTime() + "[DEBUG]\t" + log);        }        public static void Vital(string log)        {            if (!CanLog(INFO)) return;            UnityEngine.Debug.Log(GetNowTime() + "[VITAL]\t" + log);        }        public static void Info(string log)        {            if (!CanLog(INFO)) return;            UnityEngine.Debug.Log(GetNowTime() + "[INFO]\t" + log);        }        public static void Proto(string log)        {            if (!CanLog(PROTO)) return;            UnityEngine.Debug.Log(GetNowTime() + "[PROTO]\t" + log);        }        public static void Warning(string log)        {            if (!CanLog(WARNING)) return;            UnityEngine.Debug.LogWarning(GetNowTime() + "[WARN]\t" + log);        }        public static void Error(string log)        {            if (!CanLog(ERROR)) return;            UnityEngine.Debug.LogError(GetNowTime() + "[ERROR]\t" + log);        }        public static string GetNowTime(string formatter = null)        {            DateTime now = DateTime.Now;            if (formatter == null)                return now.ToString("[HH:mm:ss fff]", DateTimeFormatInfo.InvariantInfo);            else                return now.ToString(formatter, DateTimeFormatInfo.InvariantInfo);        }        public static ulong GetTimestamp()        {            return (ulong)(DateTime.Now - new DateTime(190, 1, 1, 0, 0, 0, 0)).TotalSeconds;        }    }}
 |