Last active
June 7, 2025 20:04
-
-
Save koster/6bd37041010dfb2fc9ce05b933f3cc2e to your computer and use it in GitHub Desktop.
LogToFile in standalone builds for unity
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.IO; | |
using UnityEngine; | |
public class LogToFile : MonoBehaviour | |
{ | |
#if !UNITY_EDITOR && !UNITY_WEBGL | |
private string logFilePath; | |
private StreamWriter logWriter; | |
private int logCounter = 0; | |
private int maxLinesPerFile = 10000; // Adjust this as needed | |
void Awake() | |
{ | |
DontDestroyOnLoad(gameObject); | |
// Get the directory where the executable is located | |
string executablePath = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName; | |
string executableDirectory = Path.GetDirectoryName(executablePath); | |
// Create logs directory if it doesn't exist | |
string logsDirectory = Path.Combine(executableDirectory, "Logs"); | |
if (!Directory.Exists(logsDirectory)) | |
{ | |
Directory.CreateDirectory(logsDirectory); | |
} | |
// Create log file with timestamp in the name | |
string timestamp = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"); | |
logFilePath = Path.Combine(logsDirectory, $"AppLog_{timestamp}.log"); | |
InitializeLogFile(); | |
// Subscribe to log message events | |
Application.logMessageReceived += HandleLog; | |
Debug.Log($"Application started. Version: {Application.version}"); | |
Debug.Log($"Log file initialized at: {logFilePath}"); | |
} | |
private void InitializeLogFile() | |
{ | |
try | |
{ | |
logWriter = new StreamWriter(logFilePath, true); | |
logWriter.AutoFlush = true; | |
// Write header with system info | |
logWriter.WriteLine("=================================================="); | |
logWriter.WriteLine($"=== Log Session: {DateTime.Now} ==="); | |
logWriter.WriteLine($"=== Unity Version: {Application.unityVersion} ==="); | |
logWriter.WriteLine($"=== App Version: {Application.version} ==="); | |
logWriter.WriteLine($"=== OS: {SystemInfo.operatingSystem} ==="); | |
logWriter.WriteLine($"=== Device: {SystemInfo.deviceModel} ==="); | |
logWriter.WriteLine($"=== Processor: {SystemInfo.processorType} ==="); | |
logWriter.WriteLine($"=== Graphics: {SystemInfo.graphicsDeviceName} ==="); | |
logWriter.WriteLine("=================================================="); | |
logWriter.WriteLine(); | |
} | |
catch (Exception e) | |
{ | |
Debug.LogError($"Failed to initialize log file: {e.Message}"); | |
} | |
} | |
void HandleLog(string logString, string stackTrace, LogType type) | |
{ | |
if (logWriter == null) return; | |
try | |
{ | |
// Write the log message to the file | |
logWriter.WriteLine($"{DateTime.Now.ToString("HH:mm:ss.fff")} [{type}] {logString}"); | |
// For errors and exceptions, also write the stack trace | |
if (type == LogType.Error || type == LogType.Exception) | |
{ | |
logWriter.WriteLine(stackTrace); | |
} | |
// Increment the log counter | |
logCounter++; | |
// Check if we need to create a new log file (to avoid huge files) | |
if (logCounter >= maxLinesPerFile) | |
{ | |
RotateLogFile(); | |
} | |
} | |
catch (Exception e) | |
{ | |
// If we can't write to the file, at least try to log the error to the console | |
Debug.LogError($"Failed to write to log file: {e.Message}"); | |
} | |
} | |
private void RotateLogFile() | |
{ | |
// Close current log file | |
logWriter.WriteLine($"=== Log file continued in next file (reached {maxLinesPerFile} lines) ==="); | |
logWriter.Close(); | |
logWriter.Dispose(); | |
// Create new log file with updated timestamp | |
string timestamp = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"); | |
string executableDirectory = Path.GetDirectoryName(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName); | |
string logsDirectory = Path.Combine(executableDirectory, "Logs"); | |
logFilePath = Path.Combine(logsDirectory, $"AppLog_{timestamp}_continued.log"); | |
// Initialize the new log file | |
InitializeLogFile(); | |
// Reset counter | |
logCounter = 0; | |
} | |
void OnApplicationPause(bool pause) | |
{ | |
if (logWriter != null) | |
{ | |
if (pause) | |
{ | |
logWriter.WriteLine($"=== Application Paused: {DateTime.Now} ==="); | |
} | |
else | |
{ | |
logWriter.WriteLine($"=== Application Resumed: {DateTime.Now} ==="); | |
} | |
} | |
} | |
void OnApplicationQuit() | |
{ | |
Debug.Log("Application shutting down"); | |
} | |
void OnDestroy() | |
{ | |
// Clean up | |
if (logWriter != null) | |
{ | |
Application.logMessageReceived -= HandleLog; | |
logWriter.WriteLine(); | |
logWriter.WriteLine($"=== End Log Session: {DateTime.Now} ==="); | |
logWriter.Close(); | |
logWriter.Dispose(); | |
} | |
} | |
#endif | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment