Added logger utils
This commit is contained in:
parent
6821f80b73
commit
fd9d4241fb
|
@ -42,6 +42,11 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Utils\Logger\Memory\ArchivableConsoleLogMemory.cs" />
|
||||
<Compile Include="Utils\Logger\Memory\ILogMemory.cs" />
|
||||
<Compile Include="Utils\Logger\Message\LogMessageFormatter.cs" />
|
||||
<Compile Include="Utils\Logger\Logger.cs" />
|
||||
<Compile Include="Utils\Logger\Message\LogMessage.cs" />
|
||||
<Compile Include="Utils\TaskBar\TaskBarProgress.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
|
|
72
SweetLib/Utils/Logger/Logger.cs
Normal file
72
SweetLib/Utils/Logger/Logger.cs
Normal file
|
@ -0,0 +1,72 @@
|
|||
using System;
|
||||
using SweetLib.Utils.Logger.Memory;
|
||||
using SweetLib.Utils.Logger.Message;
|
||||
|
||||
namespace SweetLib.Utils.Logger
|
||||
{
|
||||
[Flags]
|
||||
public enum LogLevel
|
||||
{
|
||||
None = 0,
|
||||
Trace = 1 << 0,
|
||||
Debug = 1 << 1,
|
||||
Info = 1 << 2,
|
||||
Warn = 1 << 3,
|
||||
Error = 1 << 4
|
||||
};
|
||||
|
||||
public static class Logger
|
||||
{
|
||||
public static LogLevel GlobalLogLevel { get; set; } = LogLevel.Info | LogLevel.Warn | LogLevel.Error;
|
||||
public static ILogMemory DefaultLogMemory = new ArchivableConsoleLogMemory();
|
||||
|
||||
public static void Log(LogLevel logLevel, string message)
|
||||
{
|
||||
Log(logLevel, message, DefaultLogMemory);
|
||||
}
|
||||
|
||||
public static void Log(LogLevel logLevel, string message, ILogMemory logMemory)
|
||||
{
|
||||
Log(new LogMessage(logLevel, message), logMemory);
|
||||
}
|
||||
|
||||
public static void Log(LogMessage message, ILogMemory logMemory)
|
||||
{
|
||||
if (message == null)
|
||||
throw new ArgumentNullException(nameof(message));
|
||||
|
||||
if (logMemory == null)
|
||||
throw new ArgumentNullException(nameof(logMemory));
|
||||
|
||||
if ((GlobalLogLevel & message.LogLevel) == LogLevel.None)
|
||||
return;
|
||||
|
||||
logMemory.Remember(message);
|
||||
}
|
||||
|
||||
public static void Trace(string message)
|
||||
{
|
||||
Log(LogLevel.Trace, message);
|
||||
}
|
||||
|
||||
public static void Debug(string message)
|
||||
{
|
||||
Log(LogLevel.Debug, message);
|
||||
}
|
||||
|
||||
public static void Info(string message)
|
||||
{
|
||||
Log(LogLevel.Info, message);
|
||||
}
|
||||
|
||||
public static void Warn(string message)
|
||||
{
|
||||
Log(LogLevel.Warn, message);
|
||||
}
|
||||
|
||||
public static void Error(string message)
|
||||
{
|
||||
Log(LogLevel.Error, message);
|
||||
}
|
||||
}
|
||||
}
|
135
SweetLib/Utils/Logger/Memory/ArchivableConsoleLogMemory.cs
Normal file
135
SweetLib/Utils/Logger/Memory/ArchivableConsoleLogMemory.cs
Normal file
|
@ -0,0 +1,135 @@
|
|||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using SweetLib.Utils.Logger.Message;
|
||||
|
||||
namespace SweetLib.Utils.Logger.Memory
|
||||
{
|
||||
public class ArchivableConsoleLogMemory : ILogMemory
|
||||
{
|
||||
private string TempFile { get; } = Path.GetTempFileName();
|
||||
|
||||
private Timer QueueTimer;
|
||||
|
||||
private ConcurrentQueue<LogMessage> LogQueue { get; } = new ConcurrentQueue<LogMessage>();
|
||||
|
||||
public string ArchiveFile { get; set; } = null;
|
||||
public bool AutoArchiveOnDispose { get; set; } = true;
|
||||
|
||||
public ArchivableConsoleLogMemory() : this(null) { }
|
||||
|
||||
public ArchivableConsoleLogMemory(string archiveFile)
|
||||
{
|
||||
ArchiveFile = archiveFile;
|
||||
|
||||
QueueTimer = new Timer(e => ProcessQueue(), null, TimeSpan.Zero, TimeSpan.FromSeconds(30));
|
||||
}
|
||||
|
||||
~ArchivableConsoleLogMemory()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
private void ProcessQueue()
|
||||
{
|
||||
if (LogQueue.IsEmpty)
|
||||
return;
|
||||
|
||||
lock (this)
|
||||
{
|
||||
if (LogQueue.IsEmpty)
|
||||
return;
|
||||
|
||||
LogMessage message;
|
||||
if (LogQueue.TryDequeue(out message))
|
||||
File.AppendAllText(TempFile, message.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public void Remember(LogMessage message)
|
||||
{
|
||||
var consoleColor = Console.ForegroundColor;
|
||||
|
||||
switch (message.LogLevel)
|
||||
{
|
||||
case LogLevel.Trace:
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
break;
|
||||
case LogLevel.Debug:
|
||||
Console.ForegroundColor = ConsoleColor.DarkYellow;
|
||||
break;
|
||||
case LogLevel.Info:
|
||||
Console.ForegroundColor = ConsoleColor.Cyan;
|
||||
break;
|
||||
case LogLevel.Warn:
|
||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||
break;
|
||||
case LogLevel.Error:
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
break;
|
||||
}
|
||||
|
||||
Console.WriteLine(message.ToString());
|
||||
LogQueue.Enqueue(message);
|
||||
|
||||
Console.ForegroundColor = consoleColor;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void Forget(LogMessage message)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
var lines = File.ReadAllLines(TempFile).ToList();
|
||||
foreach (var line in lines)
|
||||
{
|
||||
if (line == message.ToString())
|
||||
lines.Remove(line);
|
||||
}
|
||||
|
||||
File.WriteAllLines(TempFile, lines);
|
||||
}
|
||||
}
|
||||
|
||||
public void Archive(string fullFileName = null)
|
||||
{
|
||||
if (fullFileName == null)
|
||||
fullFileName = ArchiveFile;
|
||||
|
||||
if (fullFileName == null)
|
||||
throw new FileNotFoundException("target file not found");
|
||||
|
||||
using (var tmpFileStream = new FileInfo(TempFile).OpenRead())
|
||||
{
|
||||
using (var compressedFileStream = File.Create(fullFileName))
|
||||
{
|
||||
using (var compressionsStream = new GZipStream(compressedFileStream, CompressionMode.Compress))
|
||||
{
|
||||
tmpFileStream.CopyTo(compressionsStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
QueueTimer.Dispose();
|
||||
|
||||
ProcessQueue();
|
||||
|
||||
if (AutoArchiveOnDispose)
|
||||
Archive();
|
||||
}
|
||||
}
|
||||
}
|
11
SweetLib/Utils/Logger/Memory/ILogMemory.cs
Normal file
11
SweetLib/Utils/Logger/Memory/ILogMemory.cs
Normal file
|
@ -0,0 +1,11 @@
|
|||
using SweetLib.Utils.Logger.Message;
|
||||
|
||||
namespace SweetLib.Utils.Logger.Memory
|
||||
{
|
||||
public interface ILogMemory
|
||||
{
|
||||
void Remember(LogMessage message);
|
||||
void Forget(LogMessage message);
|
||||
void Archive(string fullFileName);
|
||||
}
|
||||
}
|
37
SweetLib/Utils/Logger/Message/LogMessage.cs
Normal file
37
SweetLib/Utils/Logger/Message/LogMessage.cs
Normal file
|
@ -0,0 +1,37 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
|
||||
namespace SweetLib.Utils.Logger.Message
|
||||
{
|
||||
public class LogMessage : IFormattable
|
||||
{
|
||||
public LogLevel LogLevel { get; }
|
||||
public string Message { get; }
|
||||
public DateTime LogDateTime { get; }
|
||||
|
||||
public LogMessage(LogLevel logLevel, string message) : this(logLevel, message, DateTime.Now) { }
|
||||
|
||||
public LogMessage(LogLevel logLevel, string message, DateTime logDateTime)
|
||||
{
|
||||
if (message == null)
|
||||
throw new ArgumentNullException(nameof(message));
|
||||
|
||||
if (logDateTime == null)
|
||||
throw new ArgumentNullException(nameof(logDateTime));
|
||||
|
||||
LogLevel = logLevel;
|
||||
Message = message;
|
||||
LogDateTime = logDateTime;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return ToString($"[{CultureInfo.CurrentCulture.DateTimeFormat}] (LL) - V", CultureInfo.CurrentCulture);
|
||||
}
|
||||
|
||||
public string ToString(string format, IFormatProvider formatProvider)
|
||||
{
|
||||
return LogMessageFormatter.Instance.Format(format, this, formatProvider);
|
||||
}
|
||||
}
|
||||
}
|
53
SweetLib/Utils/Logger/Message/LogMessageFormatter.cs
Normal file
53
SweetLib/Utils/Logger/Message/LogMessageFormatter.cs
Normal file
|
@ -0,0 +1,53 @@
|
|||
using System;
|
||||
|
||||
namespace SweetLib.Utils.Logger.Message
|
||||
{
|
||||
public class LogMessageFormatter : ICustomFormatter
|
||||
{
|
||||
private LogMessageFormatter() { }
|
||||
private static LogMessageFormatter FormatterInstance { get; set; }
|
||||
private static object Locker { get; } = new object();
|
||||
|
||||
public static LogMessageFormatter Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (FormatterInstance != null)
|
||||
return FormatterInstance;
|
||||
|
||||
lock (Locker)
|
||||
{
|
||||
if (FormatterInstance != null)
|
||||
return FormatterInstance;
|
||||
|
||||
FormatterInstance = new LogMessageFormatter();
|
||||
}
|
||||
return FormatterInstance;
|
||||
}
|
||||
}
|
||||
|
||||
public string Format(string format, object arg, IFormatProvider formatProvider)
|
||||
{
|
||||
if (format == null)
|
||||
throw new ArgumentNullException(nameof(format));
|
||||
|
||||
if (arg == null)
|
||||
throw new ArgumentNullException(nameof(arg));
|
||||
|
||||
if (arg.GetType() != typeof(LogMessage))
|
||||
{
|
||||
var formattable = arg as IFormattable;
|
||||
return formattable?.ToString(format, formatProvider) ?? arg.ToString();
|
||||
}
|
||||
|
||||
var message = (LogMessage)arg;
|
||||
|
||||
var result = message.LogDateTime.ToString(format, formatProvider);
|
||||
|
||||
result = result.Replace("LL", message.LogLevel.ToString());
|
||||
result = result.Replace("V", message.Message);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue