Browse Source

Redid logger to be both more modular and more similar to Syslog

refactor
Anairkoen Schno 6 years ago
parent
commit
89a669bcc6
19 changed files with 374 additions and 223 deletions
  1. +4
    -4
      IPA/IPA.csproj
  2. +1
    -1
      IPA/obj/Debug/IPA.csproj.CoreCompileInputs.cache
  3. +1
    -1
      IPA/packages.config
  4. +5
    -7
      IllusionInjector/BeatSaber/CompositeBSPlugin.cs
  5. +2
    -4
      IllusionInjector/IPA/CompositeIPAPlugin.cs
  6. +10
    -0
      IllusionInjector/IllusionInjector.csproj
  7. +26
    -0
      IllusionInjector/Logging/Printers/ColoredConsolePrinter.cs
  8. +55
    -0
      IllusionInjector/Logging/Printers/GlobalZFIlePrinter.cs
  9. +48
    -0
      IllusionInjector/Logging/Printers/PluginLogFilePrinter.cs
  10. +134
    -0
      IllusionInjector/Logging/StandardLogger.cs
  11. +11
    -12
      IllusionInjector/PluginManager.cs
  12. +1
    -1
      IllusionInjector/obj/Debug/IllusionInjector.csproj.CoreCompileInputs.cache
  13. +4
    -0
      IllusionInjector/packages.config
  14. +0
    -0
      IllusionPlugin/IGenericEnhancedPlugin.cs
  15. +3
    -2
      IllusionPlugin/IllusionPlugin.csproj
  16. +0
    -190
      IllusionPlugin/Logger.cs
  17. +16
    -0
      IllusionPlugin/Logging/LogPrinter.cs
  18. +52
    -0
      IllusionPlugin/Logging/Logger.cs
  19. +1
    -1
      IllusionPlugin/obj/Debug/IllusionPlugin.csproj.CoreCompileInputs.cache

+ 4
- 4
IPA/IPA.csproj View File

@ -40,19 +40,19 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Mono.Cecil, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL"> <Reference Include="Mono.Cecil, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
<HintPath>..\packages\Mono.Cecil.0.9.6.4\lib\net35\Mono.Cecil.dll</HintPath>
<HintPath>..\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.dll</HintPath>
<Private>True</Private> <Private>True</Private>
</Reference> </Reference>
<Reference Include="Mono.Cecil.Mdb, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL"> <Reference Include="Mono.Cecil.Mdb, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
<HintPath>..\packages\Mono.Cecil.0.9.6.4\lib\net35\Mono.Cecil.Mdb.dll</HintPath>
<HintPath>..\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.Mdb.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="Mono.Cecil.Pdb, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL"> <Reference Include="Mono.Cecil.Pdb, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
<HintPath>..\packages\Mono.Cecil.0.9.6.4\lib\net35\Mono.Cecil.Pdb.dll</HintPath>
<HintPath>..\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.Pdb.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="Mono.Cecil.Rocks, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL"> <Reference Include="Mono.Cecil.Rocks, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
<HintPath>..\packages\Mono.Cecil.0.9.6.4\lib\net35\Mono.Cecil.Rocks.dll</HintPath>
<HintPath>..\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.Rocks.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />


+ 1
- 1
IPA/obj/Debug/IPA.csproj.CoreCompileInputs.cache View File

@ -1 +1 @@
6744afebdfdc05ced46858bdac21e047b0d6e43f
33cd6c2ad2a5a7958d22e4f89028cf896273055b

+ 1
- 1
IPA/packages.config View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="Mono.Cecil" version="0.9.6.4" targetFramework="net35-client" requireReinstallation="true" />
<package id="Mono.Cecil" version="0.9.6.4" targetFramework="net462" />
</packages> </packages>

+ 5
- 7
IllusionInjector/BeatSaber/CompositeBSPlugin.cs View File

@ -5,7 +5,7 @@ using System.Linq;
using System.Text; using System.Text;
using UnityEngine; using UnityEngine;
using UnityEngine.SceneManagement; using UnityEngine.SceneManagement;
using Logger = IllusionPlugin.Logger;
using Logger = IllusionInjector.Logging.Logger;
namespace IllusionInjector { namespace IllusionInjector {
public class CompositeBSPlugin : IBeatSaberPlugin public class CompositeBSPlugin : IBeatSaberPlugin
@ -13,8 +13,6 @@ namespace IllusionInjector {
IEnumerable<IBeatSaberPlugin> plugins; IEnumerable<IBeatSaberPlugin> plugins;
private delegate void CompositeCall(IBeatSaberPlugin plugin); private delegate void CompositeCall(IBeatSaberPlugin plugin);
private Logger debugLogger => PluginManager.debugLogger;
public CompositeBSPlugin(IEnumerable<IBeatSaberPlugin> plugins) { public CompositeBSPlugin(IEnumerable<IBeatSaberPlugin> plugins) {
this.plugins = plugins; this.plugins = plugins;
@ -34,7 +32,7 @@ namespace IllusionInjector {
plugin.OnSceneLoaded(scene, sceneMode); plugin.OnSceneLoaded(scene, sceneMode);
} }
catch (Exception ex) { catch (Exception ex) {
debugLogger.Exception($"{plugin.Name}: {ex}");
Logger.log.Error($"{plugin.Name}: {ex}");
} }
} }
} }
@ -45,7 +43,7 @@ namespace IllusionInjector {
plugin.OnSceneUnloaded(scene); plugin.OnSceneUnloaded(scene);
} }
catch (Exception ex) { catch (Exception ex) {
debugLogger.Exception($"{plugin.Name}: {ex}");
Logger.log.Error($"{plugin.Name}: {ex}");
} }
} }
} }
@ -56,7 +54,7 @@ namespace IllusionInjector {
plugin.OnActiveSceneChanged(prevScene, nextScene); plugin.OnActiveSceneChanged(prevScene, nextScene);
} }
catch (Exception ex) { catch (Exception ex) {
debugLogger.Exception($"{plugin.Name}: {ex}");
Logger.log.Error($"{plugin.Name}: {ex}");
} }
} }
} }
@ -67,7 +65,7 @@ namespace IllusionInjector {
callback(plugin); callback(plugin);
} }
catch (Exception ex) { catch (Exception ex) {
debugLogger.Exception($"{plugin.Name}: {ex}");
Logger.log.Error($"{plugin.Name}: {ex}");
} }
} }
} }


+ 2
- 4
IllusionInjector/IPA/CompositeIPAPlugin.cs View File

@ -5,7 +5,7 @@ using System.Linq;
using System.Text; using System.Text;
using UnityEngine; using UnityEngine;
using UnityEngine.SceneManagement; using UnityEngine.SceneManagement;
using Logger = IllusionPlugin.Logger;
using Logger = IllusionInjector.Logging.Logger;
namespace IllusionInjector { namespace IllusionInjector {
#pragma warning disable CS0618 // Type or member is obsolete #pragma warning disable CS0618 // Type or member is obsolete
@ -14,8 +14,6 @@ namespace IllusionInjector {
IEnumerable<IPlugin> plugins; IEnumerable<IPlugin> plugins;
private delegate void CompositeCall(IPlugin plugin); private delegate void CompositeCall(IPlugin plugin);
private Logger debugLogger => PluginManager.debugLogger;
public CompositeIPAPlugin(IEnumerable<IPlugin> plugins) { public CompositeIPAPlugin(IEnumerable<IPlugin> plugins) {
this.plugins = plugins; this.plugins = plugins;
@ -35,7 +33,7 @@ namespace IllusionInjector {
callback(plugin); callback(plugin);
} }
catch (Exception ex) { catch (Exception ex) {
debugLogger.Exception($"{plugin.Name}: {ex}");
Logger.log.Error($"{plugin.Name}: {ex}");
} }
} }
} }


+ 10
- 0
IllusionInjector/IllusionInjector.csproj View File

@ -45,6 +45,9 @@
<HintPath>..\Libs\UnityEngine.CoreModule.dll</HintPath> <HintPath>..\Libs\UnityEngine.CoreModule.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="zlib.net, Version=1.0.3.0, Culture=neutral, PublicKeyToken=47d7877cb3620160">
<HintPath>..\packages\zlib.net.1.0.4.0\lib\zlib.net.dll</HintPath>
</Reference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Bootstrapper.cs" /> <Compile Include="Bootstrapper.cs" />
@ -52,6 +55,10 @@
<Compile Include="ConsoleWindow.cs" /> <Compile Include="ConsoleWindow.cs" />
<Compile Include="Injector.cs" /> <Compile Include="Injector.cs" />
<Compile Include="IPA\CompositeIPAPlugin.cs" /> <Compile Include="IPA\CompositeIPAPlugin.cs" />
<Compile Include="Logging\Printers\ColoredConsolePrinter.cs" />
<Compile Include="Logging\Printers\GlobalZFIlePrinter.cs" />
<Compile Include="Logging\Printers\PluginLogFilePrinter.cs" />
<Compile Include="Logging\StandardLogger.cs" />
<Compile Include="PluginManager.cs" /> <Compile Include="PluginManager.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="PluginComponent.cs" /> <Compile Include="PluginComponent.cs" />
@ -62,6 +69,9 @@
<Name>IllusionPlugin</Name> <Name>IllusionPlugin</Name>
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets. Other similar extension points exist, see Microsoft.Common.targets.


+ 26
- 0
IllusionInjector/Logging/Printers/ColoredConsolePrinter.cs View File

@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IllusionPlugin.Logging.Printers
{
public class ColoredConsolePrinter : LogPrinter
{
Logger.LogLevel filter = Logger.LogLevel.All;
public override Logger.LogLevel Filter { get => filter; set => filter = value; }
ConsoleColor color = Console.ForegroundColor;
public ConsoleColor Color { get => color; set => color = value; }
public override void Print(Logger.Level level, DateTime time, string logName, string message)
{
if (((byte)level & (byte)Filter) == 0) return;
Console.ForegroundColor = color;
foreach (var line in message.Split(new string[] { "\n", Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries))
Console.WriteLine(string.Format(Logger.LogFormat, line, logName, time, level.ToString().ToUpper()));
Console.ResetColor();
}
}
}

+ 55
- 0
IllusionInjector/Logging/Printers/GlobalZFIlePrinter.cs View File

@ -0,0 +1,55 @@
using IllusionPlugin.Logging;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using zlib;
namespace IllusionInjector.Logging.Printers
{
public class GlobalZFIlePrinter : LogPrinter
{
public override IllusionPlugin.Logging.Logger.LogLevel Filter { get; set; }
private FileInfo fileInfo;
private StreamWriter fileWriter;
private static FileInfo GetFileInfo()
{
var logsDir = new DirectoryInfo("Logs");
logsDir.Create();
var finfo = new FileInfo(Path.Combine(logsDir.FullName, $"{DateTime.Now:YYYY.MM.DD.HH.MM}.log.z"));
finfo.Create().Close();
return finfo;
}
public GlobalZFIlePrinter()
{
fileInfo = GetFileInfo();
}
public override void StartPrint()
{
fileWriter = new StreamWriter(
new ZOutputStream(fileInfo.Open(FileMode.Append, FileAccess.Write, FileShare.Read))
{
FlushMode = zlibConst.Z_FULL_FLUSH
},
Encoding.UTF8
);
}
public override void Print(IllusionPlugin.Logging.Logger.Level level, DateTime time, string logName, string message)
{
foreach (var line in message.Split(new string[] { "\n", Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries))
fileWriter.WriteLine(string.Format("[{3} @ {2:HH:mm:ss} | {1}] {0}", line, logName, time, level.ToString().ToUpper()));
}
public override void EndPrint()
{
fileWriter.Dispose();
}
}
}

+ 48
- 0
IllusionInjector/Logging/Printers/PluginLogFilePrinter.cs View File

@ -0,0 +1,48 @@
using IllusionPlugin.Logging;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IllusionInjector.Logging.Printers
{
public class PluginLogFilePrinter : LogPrinter
{
public override IllusionPlugin.Logging.Logger.LogLevel Filter { get; set; }
private FileInfo fileInfo;
private StreamWriter fileWriter;
private static FileInfo GetFileInfo(string modName)
{
var logsDir = new DirectoryInfo(Path.Combine("Logs",modName));
logsDir.Create();
var finfo = new FileInfo(Path.Combine(logsDir.FullName, $"{DateTime.Now:YYYY.MM.DD.HH.MM}.log"));
finfo.CreateText().Close();
return finfo;
}
public PluginLogFilePrinter(string name)
{
fileInfo = GetFileInfo(name);
}
public override void StartPrint()
{
fileWriter = fileInfo.AppendText();
}
public override void Print(IllusionPlugin.Logging.Logger.Level level, DateTime time, string logName, string message)
{
foreach (var line in message.Split(new string[] { "\n", Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries))
fileWriter.WriteLine(string.Format("[{3} @ {2:HH:mm:ss}] {0}", line, logName, time, level.ToString().ToUpper()));
}
public override void EndPrint()
{
fileWriter.Dispose();
}
}
}

+ 134
- 0
IllusionInjector/Logging/StandardLogger.cs View File

@ -0,0 +1,134 @@
using IllusionInjector.Logging.Printers;
using IllusionPlugin.Logging;
using IllusionPlugin.Logging.Printers;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using LoggerBase = IllusionPlugin.Logging.Logger;
namespace IllusionInjector.Logging
{
internal static class Logger
{
private static LoggerBase _log;
internal static LoggerBase log
{
get
{
if (_log == null)
_log = new StandardLogger("IllusionInjector");
return _log;
}
}
}
public class StandardLogger : LoggerBase
{
private static readonly IReadOnlyList<LogPrinter> defaultPrinters = new List<LogPrinter>()
{
new ColoredConsolePrinter()
{
Filter = LogLevel.DebugOnly,
Color = ConsoleColor.Green,
},
new ColoredConsolePrinter()
{
Filter = LogLevel.InfoOnly,
Color = ConsoleColor.White,
},
new ColoredConsolePrinter()
{
Filter = LogLevel.WarningOnly,
Color = ConsoleColor.Yellow,
},
new ColoredConsolePrinter()
{
Filter = LogLevel.ErrorOnly,
Color = ConsoleColor.Red,
},
new ColoredConsolePrinter()
{
Filter = LogLevel.CriticalOnly,
Color = ConsoleColor.Magenta,
},
new GlobalZFIlePrinter()
};
private string logName;
private static LogLevel showFilter = LogLevel.InfoUp;
public static LogLevel Filter { get => showFilter; set => showFilter = value; }
private List<LogPrinter> printers = new List<LogPrinter>(defaultPrinters);
internal StandardLogger(string name)
{
logName = name;
printers.Add(new PluginLogFilePrinter(name));
if (_logThread == null || !_logThread.IsAlive)
{
_logThread = new Thread(LogThread);
_logThread.Start();
}
}
public override void Log(Level level, string message)
{
_logQueue.Add(new LogMessage
{
level = level,
message = message,
logger = this,
time = DateTime.Now
});
}
internal struct LogMessage
{
public Level level;
public StandardLogger logger;
public string message;
public DateTime time;
}
private static BlockingCollection<LogMessage> _logQueue = new BlockingCollection<LogMessage>();
private static Thread _logThread;
private static void LogThread()
{
HashSet<LogPrinter> started = new HashSet<LogPrinter>();
while (_logQueue.TryTake(out LogMessage msg, Timeout.Infinite)) {
foreach (var printer in msg.logger.printers)
{
if (((byte)msg.level & (byte)printer.Filter) != 0)
{
if (!started.Contains(printer))
{
printer.StartPrint();
started.Add(printer);
}
printer.Print(msg.level, msg.time, msg.logger.logName, msg.message);
}
}
if (_logQueue.Count == 0)
{
foreach (var printer in started)
printer.EndPrint();
started.Clear();
}
}
}
public static void StopLogThread()
{
_logQueue.CompleteAdding();
_logThread.Join();
}
}
}

+ 11
- 12
IllusionInjector/PluginManager.cs View File

@ -1,4 +1,5 @@
using IllusionPlugin;
using IllusionInjector.Logging;
using IllusionPlugin;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
@ -14,8 +15,6 @@ namespace IllusionInjector
public static class PluginManager public static class PluginManager
{ {
#pragma warning disable CS0618 // Type or member is obsolete (IPlugin) #pragma warning disable CS0618 // Type or member is obsolete (IPlugin)
internal static readonly Logger debugLogger = new Logger("IllusionInjector");
/// <summary> /// <summary>
/// Gets the list of loaded plugins and loads them if necessary. /// Gets the list of loaded plugins and loads them if necessary.
@ -54,7 +53,7 @@ namespace IllusionInjector
// Process.GetCurrentProcess().MainModule crashes the game and Assembly.GetEntryAssembly() is NULL, // Process.GetCurrentProcess().MainModule crashes the game and Assembly.GetEntryAssembly() is NULL,
// so we need to resort to P/Invoke // so we need to resort to P/Invoke
string exeName = Path.GetFileNameWithoutExtension(AppInfo.StartupPath); string exeName = Path.GetFileNameWithoutExtension(AppInfo.StartupPath);
debugLogger.Log(exeName);
Logger.log.Info(exeName);
_bsPlugins = new List<IBeatSaberPlugin>(); _bsPlugins = new List<IBeatSaberPlugin>();
_ipaPlugins = new List<IPlugin>(); _ipaPlugins = new List<IPlugin>();
@ -93,15 +92,15 @@ namespace IllusionInjector
// DEBUG // DEBUG
debugLogger.Log($"Running on Unity {UnityEngine.Application.unityVersion}");
debugLogger.Log("-----------------------------");
debugLogger.Log($"Loading plugins from {pluginDirectory} and found {_bsPlugins.Count}");
debugLogger.Log("-----------------------------");
Logger.log.Info($"Running on Unity {UnityEngine.Application.unityVersion}");
Logger.log.Info("-----------------------------");
Logger.log.Info($"Loading plugins from {pluginDirectory} and found {_bsPlugins.Count}");
Logger.log.Info("-----------------------------");
foreach (var plugin in _bsPlugins) foreach (var plugin in _bsPlugins)
{ {
debugLogger.Log($"{plugin.Name}: {plugin.Version}");
Logger.log.Info($"{plugin.Name}: {plugin.Version}");
} }
debugLogger.Log("-----------------------------");
Logger.log.Info("-----------------------------");
} }
private static Tuple<IEnumerable<IBeatSaberPlugin>, IEnumerable<IPlugin>> LoadPluginsFromFile(string file, string exeName) private static Tuple<IEnumerable<IBeatSaberPlugin>, IEnumerable<IPlugin>> LoadPluginsFromFile(string file, string exeName)
@ -132,7 +131,7 @@ namespace IllusionInjector
} }
catch (Exception e) catch (Exception e)
{ {
debugLogger.Exception($"Could not load plugin {t.FullName} in {Path.GetFileName(file)}! {e}");
Logger.log.Error($"Could not load plugin {t.FullName} in {Path.GetFileName(file)}! {e}");
} }
} }
@ -163,7 +162,7 @@ namespace IllusionInjector
} }
catch (Exception e) catch (Exception e)
{ {
debugLogger.Error($"Could not load {Path.GetFileName(file)}! {e}");
Logger.log.Error($"Could not load {Path.GetFileName(file)}! {e}");
} }
return new Tuple<IEnumerable<IBeatSaberPlugin>, IEnumerable<IPlugin>>(bsPlugins, ipaPlugins); return new Tuple<IEnumerable<IBeatSaberPlugin>, IEnumerable<IPlugin>>(bsPlugins, ipaPlugins);


+ 1
- 1
IllusionInjector/obj/Debug/IllusionInjector.csproj.CoreCompileInputs.cache View File

@ -1 +1 @@
26a9be3d697b3ac9c2a8af98062cb97cf748184e
524c2a9e58911edfdaf36eb5bf255b181a39f814

+ 4
- 0
IllusionInjector/packages.config View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="zlib.net" version="1.0.4.0" targetFramework="net46" />
</packages>

IllusionPlugin/IPA/IGenericEnhancedPlugin.cs → IllusionPlugin/IGenericEnhancedPlugin.cs View File


+ 3
- 2
IllusionPlugin/IllusionPlugin.csproj View File

@ -47,9 +47,10 @@
<Compile Include="IniFile.cs" /> <Compile Include="IniFile.cs" />
<Compile Include="BeatSaber\IBeatSaberPlugin.cs" /> <Compile Include="BeatSaber\IBeatSaberPlugin.cs" />
<Compile Include="IPA\IEnhancedPlugin.cs" /> <Compile Include="IPA\IEnhancedPlugin.cs" />
<Compile Include="IPA\IGenericEnhancedPlugin.cs" />
<Compile Include="IGenericEnhancedPlugin.cs" />
<Compile Include="IPA\IPlugin.cs" /> <Compile Include="IPA\IPlugin.cs" />
<Compile Include="Logger.cs" />
<Compile Include="Logging\LogPrinter.cs" />
<Compile Include="Logging\Logger.cs" />
<Compile Include="ModPrefs.cs" /> <Compile Include="ModPrefs.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup> </ItemGroup>


+ 0
- 190
IllusionPlugin/Logger.cs View File

@ -1,190 +0,0 @@
using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.IO;
using System.Runtime.Remoting.Messaging;
using System.Threading;
using IllusionPlugin;
namespace IllusionPlugin {
/// <summary>
/// A general purpose logging class for any plugin to use.
/// </summary>
public class Logger {
private static BlockingCollection<logMessage> _logQueue;
private static Thread _watcherThread;
private static bool _threadRunning;
private readonly FileInfo _logFile;
private string ModName;
struct logMessage {
public static readonly string logFormat = "[{3} @ {2:HH:mm:ss} | {1}] {0}";
public WarningLevel WarningLevel;
public DateTime Time;
public Logger Log;
public string Message;
public logMessage(string msg, Logger log, DateTime time, WarningLevel wl) {
Message = msg;
WarningLevel = wl;
Log = log;
Time = time;
}
}
enum WarningLevel {
Log, Error, Exception, Warning
}
static void SetupStatic()
{
if (_logQueue == null)
_logQueue = new BlockingCollection<logMessage>();
if (_watcherThread == null || !_watcherThread.IsAlive)
{
_watcherThread = new Thread(QueueWatcher); // { IsBackground = true };
_threadRunning = true;
_watcherThread.Start();
}
}
/// <summary>
/// Creates a logger with the specified name.
/// </summary>
/// <param name="modName">the name of the logger</param>
public Logger(string modName = "Default") {
SetupStatic();
_logFile = GetPath(modName);
_logFile.Create().Close();
}
/// <summary>
/// Creates a logger for the specified plugin.
/// </summary>
/// <param name="plugin">the plugin to associate the logger with</param>
public Logger(IBeatSaberPlugin plugin)
{
SetupStatic();
_logFile = GetPath(plugin);
_logFile.Create().Close();
}
/// <summary>
/// Sends a message to the log.
/// </summary>
/// <param name="msg">the message to send</param>
public void Log(string msg) {
if(!_watcherThread.IsAlive) throw new Exception("Logger is Closed!");
//_logQueue.Add(new logMessage($"[LOG @ {DateTime.Now:HH:mm:ss} | {ModName}] {msg}", WarningLevel.Log));
_logQueue.Add(new logMessage(msg, this, DateTime.Now, WarningLevel.Log));
}
/// <summary>
/// Sends an error to the log.
/// </summary>
/// <param name="msg">the message to send</param>
public void Error(string msg) {
if(!_watcherThread.IsAlive) throw new Exception("Logger is Closed!");
//_logQueue.Add(new logMessage($"[ERROR @ {DateTime.Now:HH:mm:ss} | {ModName}] {msg}", WarningLevel.Error));
_logQueue.Add(new logMessage(msg, this, DateTime.Now, WarningLevel.Error));
}
/// <summary>
/// Sends an exception to the log.
/// </summary>
/// <param name="msg">the message to send</param>
public void Exception(string msg) {
if(!_watcherThread.IsAlive) throw new Exception("Logger is Closed!");
//_logQueue.Add(new logMessage($"[EXCEPTION @ {DateTime.Now:HH:mm:ss} | {ModName}] {msg}", WarningLevel.Exception));
_logQueue.Add(new logMessage(msg, this, DateTime.Now, WarningLevel.Exception));
}
/// <summary>
/// Sends a warning to the log.
/// </summary>
/// <param name="msg">the message to send</param>
public void Warning(string msg) {
if(!_watcherThread.IsAlive) throw new Exception("Logger is Closed!");
//_logQueue.Add(new logMessage($"[WARNING @ {DateTime.Now:HH:mm:ss} | {ModName}] {msg}", WarningLevel.Warning));
_logQueue.Add(new logMessage(msg, this, DateTime.Now, WarningLevel.Warning));
}
static void QueueWatcher() {
//StreamWriter wstream = null;
Dictionary<string, StreamWriter> wstreams = new Dictionary<string, StreamWriter>();
while (_threadRunning && _logQueue.TryTake(out logMessage message, Timeout.Infinite))
{
string msg = string.Format(logMessage.logFormat, message.Message, message.Log.ModName, message.Time, message.WarningLevel);
wstreams[message.Log.ModName] = message.Log._logFile.AppendText();
wstreams[message.Log.ModName].WriteLine(msg);
Console.ForegroundColor = GetConsoleColour(message.WarningLevel);
Console.WriteLine(message.Message);
Console.ResetColor();
if (_logQueue.Count == 0)
{ // no more messages
foreach (var kvp in wstreams)
{
if (kvp.Value == null) continue;
kvp.Value.Dispose();
wstreams[kvp.Key] = null;
}
}
}
foreach (var kvp in wstreams)
{
if (kvp.Value == null) continue;
kvp.Value.Dispose();
}
}
/// <summary>
/// Stops the logger background thread.
/// </summary>
public static void Stop() {
_threadRunning = false;
_watcherThread.Join();
}
static ConsoleColor GetConsoleColour(WarningLevel level) {
switch (level) {
case WarningLevel.Log:
return ConsoleColor.Green;
case WarningLevel.Error:
return ConsoleColor.Yellow;
case WarningLevel.Exception:
return ConsoleColor.Red;
case WarningLevel.Warning:
return ConsoleColor.Blue;
default:
return ConsoleColor.Gray;
}
}
FileInfo GetPath(IBeatSaberPlugin plugin) => GetPath(plugin.Name);
FileInfo GetPath(string modName) {
ModName = modName;
var logsDir = new DirectoryInfo($"./Logs/{modName}/{DateTime.Now:dd-MM-yy}");
logsDir.Create();
return new FileInfo($"{logsDir.FullName}/{logsDir.GetFiles().Length}.txt");
}
}
/// <summary>
///
/// </summary>
public static class LoggerExtensions {
/// <summary>
/// Gets a logger for the provided plugin.
/// </summary>
/// <param name="plugin">the plugin to get a logger for</param>
/// <returns>a Logger instance</returns>
public static Logger GetLogger(this IBeatSaberPlugin plugin) {
return new Logger(plugin);
}
}
}

+ 16
- 0
IllusionPlugin/Logging/LogPrinter.cs View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IllusionPlugin.Logging
{
public abstract class LogPrinter
{
public abstract Logger.LogLevel Filter { get; set; }
public abstract void Print(Logger.Level level, DateTime time, string logName, string message);
public virtual void StartPrint() { }
public virtual void EndPrint() { }
}
}

+ 52
- 0
IllusionPlugin/Logging/Logger.cs View File

@ -0,0 +1,52 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IllusionPlugin.Logging
{
public abstract class Logger
{
public static string LogFormat { get; protected internal set; } = "[{3} @ {2:HH:mm:ss} | {1}] {0}";
public enum Level : byte
{
None = 0,
Debug = 1,
Info = 2,
Warning = 4,
Error = 8,
Critical = 16
}
[Flags]
public enum LogLevel : byte
{
None = Level.None,
DebugOnly = Level.Debug,
InfoOnly = Level.Info,
WarningOnly = Level.Warning,
ErrorOnly = Level.Error,
CriticalOnly = Level.Critical,
ErrorUp = ErrorOnly | CriticalOnly,
WarningUp = WarningOnly | ErrorUp,
InfoUp = InfoOnly | WarningUp,
All = DebugOnly | InfoUp,
}
public abstract void Log(Level level, string message);
public void Log(Level level, Exception exeption) => Log(level, exeption.ToString());
public void Debug(string message) => Log(Level.Debug, message);
public void Debug(Exception e) => Log(Level.Debug, e);
public void Info(string message) => Log(Level.Info, message);
public void Info(Exception e) => Log(Level.Info, e);
public void Warn(string message) => Log(Level.Warning, message);
public void Warn(Exception e) => Log(Level.Warning, e);
public void Error(string message) => Log(Level.Error, message);
public void Error(Exception e) => Log(Level.Error, e);
public void Critical(string message) => Log(Level.Critical, message);
public void Critical(Exception e) => Log(Level.Critical, e);
}
}

+ 1
- 1
IllusionPlugin/obj/Debug/IllusionPlugin.csproj.CoreCompileInputs.cache View File

@ -1 +1 @@
eb108721e2940659deee6bd068631e6d4749736e
1bbd9ba53463d8e0c57caf8203d0145bfc70fa26

Loading…
Cancel
Save