Skip to content

Instantly share code, notes, and snippets.

@koster
Last active June 7, 2025 20:04
Show Gist options
  • Save koster/6bd37041010dfb2fc9ce05b933f3cc2e to your computer and use it in GitHub Desktop.
Save koster/6bd37041010dfb2fc9ce05b933f3cc2e to your computer and use it in GitHub Desktop.
LogToFile in standalone builds for unity
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