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