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 {
|
|
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();
|
|
}
|
|
}
|
|
|
|
public Logger(string modName = "Default") {
|
|
SetupStatic();
|
|
_logFile = GetPath(modName);
|
|
_logFile.Create().Close();
|
|
}
|
|
|
|
public Logger(IBeatSaberPlugin plugin)
|
|
{
|
|
SetupStatic();
|
|
_logFile = GetPath(plugin);
|
|
_logFile.Create().Close();
|
|
}
|
|
|
|
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));
|
|
}
|
|
|
|
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));
|
|
}
|
|
|
|
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));
|
|
}
|
|
|
|
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();
|
|
}
|
|
}
|
|
|
|
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");
|
|
}
|
|
}
|
|
|
|
public static class LoggerExtensions {
|
|
public static Logger GetLogger(this IBeatSaberPlugin plugin) {
|
|
return new Logger(plugin);
|
|
}
|
|
}
|
|
}
|