Created
September 26, 2024 07:23
-
-
Save Ddemon26/d0ffaf758d3b06e197b4596a51fb5c98 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Diagnostics; | |
using UnityEngine; | |
using Debug = UnityEngine.Debug; | |
using Object = UnityEngine.Object; | |
namespace TCS.TestSystems.Logging { | |
public static class GameLogger { | |
// Dictionary to hold Logger instances for each system, identified by Type | |
static readonly Dictionary<Type, Logger> Loggers = new(); | |
// Central log storage | |
static readonly List<LogEntry> LogEntries = new(); | |
// Maximum number of logs to store to prevent memory issues | |
const int MAX_LOG_ENTRIES = 100; | |
// Global flag to enable or disable all logging | |
static bool s_globalLoggingEnabled = true; | |
// Flag to allow runtime toggling of logs in development and runtime builds | |
static bool s_allowRuntimeToggling = | |
#if UNITY_EDITOR || DEVELOPMENT_BUILD | |
true; | |
#else | |
true; // Set to true if you want to allow runtime toggling in runtime builds | |
#endif | |
// Lock object for thread safety | |
static readonly object LockObj = new(); | |
public static void Log(string message, Object context = null) { | |
var callerType = GetCallerType(); | |
if (callerType == null) { | |
Debug.Log($"[Unknown] {message}", context); | |
AddLogEntry(new LogEntry { | |
Timestamp = DateTime.Now, | |
Type = LogType.Log, | |
SystemName = "Unknown", | |
Message = message | |
}); | |
return; | |
} | |
var logger = GetLogger(callerType); | |
logger.LogMessage(message, context); | |
} | |
public static void LogWarning(string message, Object context = null) { | |
var callerType = GetCallerType(); | |
if (callerType == null) { | |
Debug.LogWarning($"[Unknown] {message}", context); | |
AddLogEntry(new LogEntry { | |
Timestamp = DateTime.Now, | |
Type = LogType.Warning, | |
SystemName = "Unknown", | |
Message = message | |
}); | |
return; | |
} | |
var logger = GetLogger(callerType); | |
logger.LogWarningMessage(message, context); | |
} | |
public static void LogError(string message, Object context = null) { | |
var callerType = GetCallerType(); | |
if (callerType == null) { | |
Debug.LogError($"[Unknown] {message}", context); | |
AddLogEntry(new LogEntry { | |
Timestamp = DateTime.Now, | |
Type = LogType.Error, | |
SystemName = "Unknown", | |
Message = message | |
}); | |
return; | |
} | |
var logger = GetLogger(callerType); | |
logger.LogErrorMessage(message, context); | |
} | |
public static void SetGlobalLogging(bool enabled) { | |
lock (LockObj) { | |
s_globalLoggingEnabled = enabled; | |
} | |
} | |
public static void SetLoggingEnabled<T>(bool enabled) { | |
var systemType = typeof(T); | |
lock (LockObj) { | |
if (Loggers.TryGetValue(systemType, out var logger)) { | |
logger.IsEnabled = enabled; | |
} | |
else { | |
Loggers.Add(systemType, new Logger(systemType, enabled)); | |
} | |
} | |
} | |
public static void SetColor<T>(Color color) { | |
var systemType = typeof(T); | |
lock (LockObj) { | |
if (Loggers.TryGetValue(systemType, out var logger)) { | |
logger.SetLogColor(color); | |
} | |
else { | |
Loggers.Add(systemType, new Logger(systemType, true, color)); | |
} | |
} | |
} | |
public static void SetRuntimeToggling(bool allow) { | |
lock (LockObj) { | |
if (s_allowRuntimeToggling) { | |
s_allowRuntimeToggling = allow; | |
} | |
else { | |
Debug.LogWarning("Runtime toggling is disabled in this build."); | |
} | |
} | |
} | |
public static List<LogEntry> GetAllLogs() { | |
lock (LockObj) { | |
return new List<LogEntry>(LogEntries); | |
} | |
} | |
public static List<LogEntry> GetLogsByType(LogType type) { | |
lock (LockObj) { | |
return LogEntries.FindAll(entry => entry.Type == type); | |
} | |
} | |
public static void ClearLogs() { | |
lock (LockObj) { | |
LogEntries.Clear(); | |
} | |
} | |
internal static void AddLogEntry(LogEntry entry) { | |
lock (LockObj) { | |
if (LogEntries.Count >= MAX_LOG_ENTRIES) { | |
LogEntries.RemoveAt(0); // Remove the oldest log to maintain the max size | |
} | |
LogEntries.Add(entry); | |
} | |
} | |
static Logger GetLogger(Type systemType) { | |
lock (LockObj) { | |
if (!Loggers.ContainsKey(systemType)) { | |
Loggers.Add(systemType, new Logger(systemType, true)); | |
} | |
return Loggers[systemType]; | |
} | |
} | |
static Type GetCallerType() { | |
try { | |
var stackTrace = new StackTrace(); | |
// The frame at index 0 is this method, index 1 is the Log method, index 2 is the caller | |
if (stackTrace.FrameCount >= 3) { | |
var method = stackTrace.GetFrame(2).GetMethod(); | |
return method.DeclaringType; | |
} | |
} | |
catch (Exception ex) { | |
Debug.LogError($"GameLogger: Failed to get caller type. Exception: {ex.Message}"); | |
} | |
return null; | |
} | |
class Logger { | |
public Type SystemType { get; } | |
public bool IsEnabled { get; set; } | |
Color LogColor { get; set; } | |
internal Logger(Type systemType, bool isEnabled, Color? logColor = null) { | |
SystemType = systemType; | |
IsEnabled = isEnabled; | |
LogColor = logColor ?? Color.white; // Default to white if no color is provided | |
} | |
public void SetLogColor(Color color) { | |
LogColor = color; | |
} | |
public void LogMessage(string message, Object context = null) { | |
if (ShouldLog()) { | |
string coloredName = $"[{SystemType.Name}]".RichColor(LogColor); | |
var formattedMessage = $"{coloredName} {message}"; | |
Debug.Log(formattedMessage, context); | |
AddLogEntry(new LogEntry { | |
Timestamp = DateTime.Now, | |
Type = LogType.Log, | |
SystemName = SystemType.Name, | |
Message = message | |
}); | |
} | |
} | |
public void LogWarningMessage(string message, Object context = null) { | |
if (ShouldLog()) { | |
string coloredName = $"[{SystemType.Name}]".RichColor(LogColor); | |
var formattedMessage = $"{coloredName} {message}"; | |
Debug.LogWarning(formattedMessage, context); | |
AddLogEntry(new LogEntry { | |
Timestamp = DateTime.Now, | |
Type = LogType.Warning, | |
SystemName = SystemType.Name, | |
Message = message | |
}); | |
} | |
} | |
public void LogErrorMessage(string message, Object context = null) { | |
if (ShouldLog()) { | |
string coloredName = $"[{SystemType.Name}]".RichColor(LogColor); | |
var formattedMessage = $"{coloredName} {message}"; | |
Debug.LogError(formattedMessage, context); | |
AddLogEntry(new LogEntry { | |
Timestamp = DateTime.Now, | |
Type = LogType.Error, | |
SystemName = SystemType.Name, | |
Message = message | |
}); | |
} | |
} | |
bool ShouldLog() { | |
return s_globalLoggingEnabled && IsEnabled; | |
} | |
} | |
public class LogEntry { | |
public DateTime Timestamp { get; set; } | |
public LogType Type { get; set; } | |
public string SystemName { get; set; } | |
public string Message { get; set; } | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment