Danro/Assets/Scripts/Utilities/CompositeLogger.cs
Danil Iarosh 98d5285b46 feat(logging): add advanced logging example with file output
- 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
2025-11-07 14:12:50 +03:00

355 lines
9.0 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Object = UnityEngine.Object;
public class CompositeLogger : ILogger, IDisposable
{
public ILogHandler logHandler { get; set; }
public bool logEnabled { get; set; }
public LogType filterLogType { get; set; }
private ILogger _oldLogger;
private readonly List<ILogger> _additiveLoggers = new();
public void Initialize(ILogger additiveLogger = null)
{
_oldLogger = Debug.unityLogger;
logHandler = _oldLogger.logHandler;
logEnabled = true;
filterLogType = _oldLogger.filterLogType;
if (additiveLogger != null) _additiveLoggers.Add(additiveLogger);
}
public void AddLogger(ILogger additiveLogger)
{
if (additiveLogger == null)
throw new ArgumentNullException(nameof(additiveLogger));
_additiveLoggers.Add(additiveLogger);
}
public void AddLoggers(params ILogger[] additiveLoggers)
{
if (additiveLoggers == null)
throw new ArgumentNullException(nameof(additiveLoggers));
foreach (var logger in additiveLoggers)
{
if (logger != null)
_additiveLoggers.Add(logger);
}
}
public void RemoveLogger(ILogger additiveLogger)
{
_additiveLoggers.Remove(additiveLogger);
}
public void RemoveLoggers(params ILogger[] additiveLoggers)
{
_additiveLoggers.RemoveAll(additiveLoggers.Contains);
}
public bool IsLogTypeAllowed(LogType logType)
{
return _oldLogger.IsLogTypeAllowed(logType) || _additiveLoggers.Any(logger => logger.IsLogTypeAllowed(logType));
}
#region Ilogger Implementation
public void LogFormat(LogType logType, string format, params object[] args)
{
_oldLogger.LogFormat(logType, format, args);
foreach (ILogger additiveLogger in _additiveLoggers)
{
try
{
additiveLogger.LogFormat(logType, format, args);
}
catch (Exception ex)
{
_oldLogger.LogException(ex);
}
}
}
public void LogFormat(LogType logType, Object context, string format, params object[] args)
{
_oldLogger.LogFormat(logType, context, format, args);
foreach (ILogger additiveLogger in _additiveLoggers)
{
try
{
additiveLogger.LogFormat(logType, context, format, args);
}
catch (Exception ex)
{
_oldLogger.LogException(ex);
}
}
}
public void LogException(Exception exception)
{
_oldLogger.LogException(exception);
foreach (ILogger additiveLogger in _additiveLoggers)
{
try
{
additiveLogger.LogException(exception);
}
catch (Exception ex)
{
_oldLogger.LogException(ex);
}
}
}
public void LogException(Exception exception, Object context)
{
_oldLogger.LogException(exception, context);
foreach (ILogger additiveLogger in _additiveLoggers)
{
try
{
additiveLogger.LogException(exception, context);
}
catch (Exception ex)
{
_oldLogger.LogException(ex);
}
}
}
public void Log(object message)
{
_oldLogger.Log(message);
foreach (ILogger additiveLogger in _additiveLoggers)
{
try
{
additiveLogger.Log(message);
}
catch (Exception ex)
{
_oldLogger.LogException(ex);
}
}
}
public void Log(LogType logType, object message)
{
_oldLogger.Log(logType, message);
foreach (ILogger additiveLogger in _additiveLoggers)
{
try
{
additiveLogger.Log(logType, message);
}
catch (Exception ex)
{
_oldLogger.LogException(ex);
}
}
}
public void Log(LogType logType, object message, GameObject gameObject)
{
_oldLogger.Log(logType, message, gameObject);
foreach (ILogger additiveLogger in _additiveLoggers)
{
try
{
additiveLogger.Log(logType, message, gameObject);
}
catch (Exception ex)
{
_oldLogger.LogException(ex);
}
}
}
public void Log(LogType logType, object message, Object context)
{
_oldLogger.Log(logType, message, context);
foreach (ILogger additiveLogger in _additiveLoggers)
{
try
{
additiveLogger.Log(logType, message, context);
}
catch (Exception ex)
{
_oldLogger.LogException(ex);
}
}
}
public void Log(LogType logType, string tag, object message, Object context)
{
_oldLogger.Log(logType, tag, message, context);
foreach (ILogger additiveLogger in _additiveLoggers)
{
try
{
additiveLogger.Log(logType, tag, message, context);
}
catch (Exception ex)
{
_oldLogger.LogException(ex);
}
}
}
public void Log(LogType logType, string tag, object message)
{
_oldLogger.Log(tag, message);
foreach (ILogger additiveLogger in _additiveLoggers)
{
try
{
additiveLogger.Log(tag, message);
}
catch (Exception ex)
{
_oldLogger.LogException(ex);
}
}
}
public void Log(string tag, object message)
{
_oldLogger.Log(tag, message);
foreach (ILogger additiveLogger in _additiveLoggers)
{
try
{
additiveLogger.Log(tag, message);
}
catch (Exception ex)
{
_oldLogger.LogException(ex);
}
}
}
public void Log(string tag, object message, Object context)
{
_oldLogger.Log(tag, message, context);
foreach (ILogger additiveLogger in _additiveLoggers)
{
try
{
additiveLogger.Log(tag, message, context);
}
catch (Exception ex)
{
_oldLogger.LogException(ex);
}
}
}
public void LogWarning(string tag, object message)
{
_oldLogger.LogWarning(tag, message);
foreach (ILogger additiveLogger in _additiveLoggers)
{
try
{
additiveLogger.LogWarning(tag, message);
}
catch (Exception ex)
{
_oldLogger.LogException(ex);
}
}
}
public void LogWarning(string tag, object message, Object context)
{
_oldLogger.LogWarning(tag, message, context);
foreach (ILogger additiveLogger in _additiveLoggers)
{
try
{
additiveLogger.LogWarning(tag, message, context);
}
catch (Exception ex)
{
_oldLogger.LogException(ex);
}
}
}
public void LogError(string tag, object message)
{
_oldLogger.LogError(tag, message);
foreach (ILogger additiveLogger in _additiveLoggers)
{
try
{
additiveLogger.LogError(tag, message);
}
catch (Exception ex)
{
_oldLogger.LogException(ex);
}
}
}
public void LogError(string tag, object message, Object context)
{
_oldLogger.LogError(tag, message, context);
foreach (ILogger additiveLogger in _additiveLoggers)
{
try
{
additiveLogger.LogError(tag, message, context);
}
catch (Exception ex)
{
_oldLogger.LogException(ex);
}
}
}
#endregion
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!disposing) return;
lock (_additiveLoggers)
{
foreach (ILogger additiveLogger in _additiveLoggers.ToArray())
{
try
{
if (additiveLogger is IDisposable disposableLogger)
disposableLogger.Dispose();
}
catch (Exception ex)
{
try { _oldLogger?.LogException(ex); } catch { /* ignore */ }
}
}
_additiveLoggers.Clear();
}
}
~CompositeLogger()
{
Dispose();
}
}