227 lines
8.0 KiB
C#
227 lines
8.0 KiB
C#
using System;
|
|
using System.IO;
|
|
using UnityEngine;
|
|
|
|
namespace BrewMonster
|
|
{
|
|
/// <summary>
|
|
/// Handles file logging for each Unity play session.
|
|
/// Overwrites the same log file when play mode starts, with timestamp in filename to detect updates.
|
|
/// Intercepts BMLogger calls and writes them to the session log file.
|
|
///
|
|
/// Usage:
|
|
/// - Automatically initializes when play mode starts
|
|
/// - Call BMLogger.LogError("HIHIHIHI") and it will appear in the log file
|
|
/// - Each play session overwrites the log file (old files are cleaned up)
|
|
/// - Filename includes timestamp so you can see when it was last updated
|
|
/// - Log files are saved in the "Logs" directory in your project root
|
|
/// </summary>
|
|
public class SessionFileLogger : MonoBehaviour
|
|
{
|
|
private static SessionFileLogger s_Instance = null;
|
|
private string m_LogFilePath = null;
|
|
private StreamWriter m_LogWriter = null;
|
|
private readonly object m_LockObject = new object();
|
|
|
|
[Header("Log Settings")]
|
|
[Tooltip("Directory where log files will be saved (relative to project root)")]
|
|
public string logDirectory = "Logs";
|
|
|
|
[Tooltip("Log file name prefix")]
|
|
public string logFileNamePrefix = "SessionLog";
|
|
|
|
/// <summary>
|
|
/// Auto-initializes when play mode starts.
|
|
/// Creates the SessionFileLogger GameObject automatically.
|
|
/// This ensures a fresh log file is created for each play session.
|
|
/// </summary>
|
|
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
|
|
private static void AutoInitialize()
|
|
{
|
|
// Clean up any existing instance (in case of play mode restart)
|
|
if (s_Instance != null)
|
|
{
|
|
if (s_Instance.m_LogWriter != null)
|
|
{
|
|
s_Instance.Cleanup();
|
|
}
|
|
if (s_Instance.gameObject != null)
|
|
{
|
|
DestroyImmediate(s_Instance.gameObject);
|
|
}
|
|
s_Instance = null;
|
|
}
|
|
|
|
// Create new instance for this play session
|
|
GameObject loggerObj = new GameObject("SessionFileLogger");
|
|
s_Instance = loggerObj.AddComponent<SessionFileLogger>();
|
|
}
|
|
|
|
private void Awake()
|
|
{
|
|
// Ensure only one instance exists
|
|
if (s_Instance != null && s_Instance != this)
|
|
{
|
|
Destroy(this);
|
|
return;
|
|
}
|
|
|
|
s_Instance = this;
|
|
DontDestroyOnLoad(gameObject);
|
|
InitializeLogFile();
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
if (s_Instance == this)
|
|
{
|
|
Cleanup();
|
|
s_Instance = null;
|
|
}
|
|
}
|
|
|
|
private void OnApplicationQuit()
|
|
{
|
|
Cleanup();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes a new log file for the current play session.
|
|
/// Overwrites old log files and creates a new one with timestamp in filename.
|
|
/// </summary>
|
|
private void InitializeLogFile()
|
|
{
|
|
try
|
|
{
|
|
// Get project root directory
|
|
string projectRoot = Application.dataPath.Replace("/Assets", "").Replace("\\Assets", "");
|
|
string logDir = Path.Combine(projectRoot, logDirectory);
|
|
|
|
// Ensure directory exists
|
|
if (!Directory.Exists(logDir))
|
|
{
|
|
Directory.CreateDirectory(logDir);
|
|
}
|
|
|
|
// Clean up old log files with the same prefix (keep only the latest)
|
|
CleanupOldLogFiles(logDir);
|
|
|
|
// Generate log file path with timestamp (so you can see when it was updated)
|
|
string timestamp = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss");
|
|
string fileName = $"{logFileNamePrefix}_{timestamp}.txt";
|
|
m_LogFilePath = Path.Combine(logDir, fileName);
|
|
|
|
// Create/overwrite the log file
|
|
m_LogWriter = new StreamWriter(m_LogFilePath, false);
|
|
m_LogWriter.WriteLine($"=== Play Session Log ===");
|
|
m_LogWriter.WriteLine($"Started: {DateTime.Now:yyyy-MM-dd HH:mm:ss}");
|
|
m_LogWriter.WriteLine($"Project: {Application.productName}");
|
|
m_LogWriter.WriteLine($"Unity Version: {Application.unityVersion}");
|
|
m_LogWriter.WriteLine($"==========================================");
|
|
m_LogWriter.WriteLine();
|
|
m_LogWriter.Flush();
|
|
|
|
// Set up BMLogger callback
|
|
BMLogger.SetFileLogCallback(WriteLogMessage);
|
|
|
|
Debug.Log($"[SessionFileLogger] Log file initialized: {m_LogFilePath}");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.LogError($"[SessionFileLogger] Failed to initialize log file: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Deletes old log files with the same prefix to keep only the current session file.
|
|
/// </summary>
|
|
private void CleanupOldLogFiles(string logDir)
|
|
{
|
|
try
|
|
{
|
|
if (!Directory.Exists(logDir))
|
|
return;
|
|
|
|
string searchPattern = $"{logFileNamePrefix}_*.txt";
|
|
string[] oldFiles = Directory.GetFiles(logDir, searchPattern);
|
|
|
|
foreach (string oldFile in oldFiles)
|
|
{
|
|
try
|
|
{
|
|
File.Delete(oldFile);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.LogWarning($"[SessionFileLogger] Failed to delete old log file {oldFile}: {ex.Message}");
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.LogWarning($"[SessionFileLogger] Error cleaning up old log files: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Writes a log message to the file.
|
|
/// Called by BMLogger when Log, LogError, or LogWarning is called.
|
|
/// </summary>
|
|
private void WriteLogMessage(string message)
|
|
{
|
|
if (m_LogWriter == null || string.IsNullOrEmpty(m_LogFilePath))
|
|
return;
|
|
|
|
lock (m_LockObject)
|
|
{
|
|
try
|
|
{
|
|
string timestamp = DateTime.Now.ToString("HH:mm:ss.fff");
|
|
m_LogWriter.WriteLine($"[{timestamp}] {message}");
|
|
m_LogWriter.Flush();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.LogError($"[SessionFileLogger] Failed to write log message: {ex.Message}");
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Cleans up the log file and removes BMLogger callback.
|
|
/// </summary>
|
|
private void Cleanup()
|
|
{
|
|
lock (m_LockObject)
|
|
{
|
|
try
|
|
{
|
|
if (m_LogWriter != null)
|
|
{
|
|
m_LogWriter.WriteLine();
|
|
m_LogWriter.WriteLine($"==========================================");
|
|
m_LogWriter.WriteLine($"Session ended: {DateTime.Now:yyyy-MM-dd HH:mm:ss}");
|
|
m_LogWriter.Flush();
|
|
m_LogWriter.Close();
|
|
m_LogWriter = null;
|
|
}
|
|
|
|
BMLogger.ClearFileLogCallback();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.LogError($"[SessionFileLogger] Error during cleanup: {ex.Message}");
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the current log file path (for debugging/inspection).
|
|
/// </summary>
|
|
public static string GetLogFilePath()
|
|
{
|
|
return s_Instance != null ? s_Instance.m_LogFilePath : null;
|
|
}
|
|
}
|
|
}
|