- Created AdvancedLoggingExample class demonstrating composite and file loggers - Implemented multi-file logging setup with separate error and full logs - Added game event and performance logging methods - Included key input handling for log operations (flush, clear) - Setup proper resource disposal on application quit
10 KiB
10 KiB
Система логирования для Unity
Обзор
Система состоит из трёх компонентов:
- CompositeLogger - композитный логгер, пересылающий сообщения на несколько логгеров
- FileLogger - логгер для записи в файл
- LoggerInitializer - компонент для автоматической инициализации
Быстрый старт
Вариант 1: Использование через LoggerInitializer (рекомендуется)
-
Создайте пустой GameObject на сцене
-
Прикрепите компонент
LoggerInitializer -
Настройте параметры в инспекторе:
- Enable File Logging - включить запись в файл
- Custom Log Path - путь к файлу (оставьте пустым для автоматического)
- Append To Existing Log - добавлять к существующему файлу
- Clear Log On Start - очищать файл при запуске
-
Запустите игру - все логи будут автоматически писаться в файл!
Вариант 2: Ручная настройка в коде
using UnityEngine;
public class MyGameManager : MonoBehaviour
{
private CompositeLogger compositeLogger;
private FileLogger fileLogger;
void Awake()
{
// Инициализация композитного логгера
compositeLogger = new CompositeLogger();
compositeLogger.Initialize();
// Создание файлового логгера
fileLogger = new FileLogger(); // Использует путь по умолчанию
// или
// fileLogger = new FileLogger("D:/MyGame/logs/game.log", append: true);
// Добавление файлового логгера в композитный
compositeLogger.AddLogger(fileLogger);
// Теперь все логи через compositeLogger будут идти и в консоль, и в файл
compositeLogger.Log("Игра запущена!");
compositeLogger.LogWarning("Test", "Тестовое предупреждение");
}
void OnApplicationQuit()
{
fileLogger?.Dispose();
}
}
Где находится файл лога?
По умолчанию файл сохраняется в Application.persistentDataPath/game.log:
- Windows:
C:/Users/<Username>/AppData/LocalLow/<CompanyName>/<ProductName>/game.log - macOS:
~/Library/Application Support/<CompanyName>/<ProductName>/game.log - Linux:
~/.config/unity3d/<CompanyName>/<ProductName>/game.log - Android:
/storage/emulated/0/Android/data/<PackageName>/files/game.log
Узнать точный путь можно через:
Debug.Log(Application.persistentDataPath);
Примеры использования
Базовое логирование
// Через композитный логгер
compositeLogger.Log("Простое сообщение");
compositeLogger.LogWarning("Tag", "Предупреждение");
compositeLogger.LogError("Tag", "Ошибка");
// Через стандартный Debug (если вы заменили Debug.unityLogger)
Debug.Log("Это тоже пойдёт в файл");
Логирование с контекстом
compositeLogger.Log(LogType.Log, "Игрок спавнится", playerGameObject);
compositeLogger.LogWarning("AI", "Путь не найден", enemyGameObject);
Логирование исключений
try
{
// Опасный код
}
catch (Exception ex)
{
compositeLogger.LogException(ex);
}
Форматированное логирование
compositeLogger.LogFormat(LogType.Log, "Игрок {0} имеет {1} очков здоровья", playerName, health);
Добавление нескольких логгеров
var fileLogger1 = new FileLogger("logs/debug.log");
var fileLogger2 = new FileLogger("logs/errors.log");
fileLogger2.filterLogType = LogType.Error; // Только ошибки
compositeLogger.AddLoggers(fileLogger1, fileLogger2);
Настройка фильтрации
На уровне FileLogger
fileLogger.filterLogType = LogType.Warning; // Логировать только Warning, Error, Exception
fileLogger.logEnabled = false; // Временно отключить
Очистка файла лога
fileLogger.Clear(); // Очистить файл и записать новый заголовок
Принудительная запись на диск
fileLogger.Flush(); // Сбросить буфер на диск
Формат записи в файле
================================================================================
Новая сессия логирования начата: 2025-11-07 14:30:15
Unity версия: 2022.3.5f1
Платформа: WindowsEditor
Путь к логу: C:/Users/User/AppData/LocalLow/DefaultCompany/MyGame/game.log
================================================================================
[14:30:15.123] [INFO] Игра запущена!
[14:30:16.456] [WARNING] [AI] Путь не найден
[14:30:17.789] [ERROR] [Network] Соединение потеряно
[14:30:18.012] [EXCEPTION] NullReferenceException: Object reference not set to an instance of an object
StackTrace:
at MyScript.MyMethod () [0x00000] in <filename>:0
Важные замечания
Потокобезопасность
FileLogger потокобезопасен - использует lock для синхронизации записи.
Производительность
AutoFlush = trueгарантирует сохранность данных при крашах, но снижает производительность- Если нужна максимальная производительность, установите
AutoFlush = falseи вызывайтеFlush()вручную
Освобождение ресурсов
ВАЖНО: Всегда вызывайте Dispose() при завершении работы:
void OnApplicationQuit()
{
fileLogger?.Dispose();
}
Ротация логов
Для больших проектов можно реализовать ротацию:
string timestamp = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss");
string logPath = $"logs/game_{timestamp}.log";
var fileLogger = new FileLogger(logPath, append: false);
Расширенные сценарии
Отдельные логи для разных систем
// Общий лог
var mainLogger = new FileLogger("logs/game.log");
// Лог только для сетевой подсистемы
var networkLogger = new FileLogger("logs/network.log");
networkLogger.filterLogType = LogType.Log;
// Лог только для ошибок
var errorLogger = new FileLogger("logs/errors.log");
errorLogger.filterLogType = LogType.Error;
compositeLogger.AddLoggers(mainLogger, networkLogger, errorLogger);
Условное логирование
#if UNITY_EDITOR
// В редакторе не пишем в файл, только в консоль
#else
compositeLogger.AddLogger(new FileLogger());
#endif
Логирование с метками времени
public class TimestampLogger
{
private CompositeLogger logger;
public void LogWithTimestamp(string message)
{
logger.Log($"[{Time.time:F2}s] {message}");
}
}
Troubleshooting
Файл не создаётся
- Проверьте права доступа к папке
- Проверьте путь через
Debug.Log(Application.persistentDataPath) - Убедитесь, что вызвали
Initialize()на CompositeLogger
Логи не пишутся в файл
- Убедитесь, что
logEnabled = true - Проверьте
filterLogType- возможно фильтр слишком строгий - Проверьте, что логгер добавлен через
AddLogger()
Файл заблокирован
- Убедитесь, что вызвали
Dispose()перед закрытием приложения - Закройте все программы, которые могут держать файл открытым
Производительность низкая
- Установите
AutoFlush = falseв конструкторе FileLogger - Вызывайте
Flush()периодически (например, раз в секунду) - Используйте более строгий
filterLogType
API Reference
FileLogger
Конструктор
FileLogger(string filePath = null, bool append = true)
Свойства
bool logEnabled- включено ли логированиеLogType filterLogType- минимальный уровень логированияILogHandler logHandler- обработчик логов (для совместимости)
Методы
void Flush()- принудительно сбросить буфер на дискvoid Clear()- очистить файл логаvoid Dispose()- закрыть файл и освободить ресурсыbool IsLogTypeAllowed(LogType)- проверка фильтра
CompositeLogger
Методы управления
void Initialize(ILogger additiveLogger = null)- инициализацияvoid AddLogger(ILogger)- добавить логгерvoid AddLoggers(params ILogger[])- добавить несколько логгеровvoid RemoveLogger(ILogger)- удалить логгерvoid RemoveLoggers(params ILogger[])- удалить несколько логгеров
Лицензия
Свободное использование в ваших проектах.