2017-04-12 17:08:54 +02:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Concurrent;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.IO.Compression;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Threading;
|
|
|
|
|
using SweetLib.Utils.Logger.Message;
|
|
|
|
|
|
|
|
|
|
namespace SweetLib.Utils.Logger.Memory
|
|
|
|
|
{
|
|
|
|
|
public class ArchivableConsoleLogMemory : ILogMemory
|
|
|
|
|
{
|
|
|
|
|
private string TempFile { get; } = Path.GetTempFileName();
|
|
|
|
|
|
2017-04-12 17:12:35 +02:00
|
|
|
|
private Timer QueueTimer { get; }
|
2017-04-12 17:08:54 +02:00
|
|
|
|
|
|
|
|
|
private ConcurrentQueue<LogMessage> LogQueue { get; } = new ConcurrentQueue<LogMessage>();
|
|
|
|
|
|
|
|
|
|
public string ArchiveFile { get; set; } = null;
|
2017-04-12 17:12:35 +02:00
|
|
|
|
|
2017-04-12 17:08:54 +02:00
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-17 11:20:57 +02:00
|
|
|
|
private void ProcessQueue(bool isDisposing = false)
|
2017-04-12 17:08:54 +02:00
|
|
|
|
{
|
|
|
|
|
if (LogQueue.IsEmpty)
|
|
|
|
|
return;
|
|
|
|
|
|
2017-04-17 11:20:57 +02:00
|
|
|
|
// if we are disposing no need to lock. This might cause issues!
|
|
|
|
|
if (!isDisposing)
|
|
|
|
|
{
|
|
|
|
|
lock (this)
|
|
|
|
|
{
|
|
|
|
|
if (LogQueue.IsEmpty)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
LogMessage message;
|
|
|
|
|
if (LogQueue.TryDequeue(out message))
|
|
|
|
|
File.AppendAllText(TempFile, message.ToString());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
2017-04-12 17:08:54 +02:00
|
|
|
|
{
|
|
|
|
|
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())
|
|
|
|
|
{
|
2017-04-12 17:44:02 +02:00
|
|
|
|
if (!Directory.Exists(Path.GetDirectoryName(fullFileName)))
|
|
|
|
|
Directory.CreateDirectory(Path.GetDirectoryName(fullFileName));
|
|
|
|
|
|
2017-04-12 17:08:54 +02:00
|
|
|
|
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();
|
|
|
|
|
|
2017-04-17 11:20:57 +02:00
|
|
|
|
ProcessQueue(true);
|
2017-04-12 17:08:54 +02:00
|
|
|
|
|
|
|
|
|
if (AutoArchiveOnDispose)
|
2017-04-12 17:44:02 +02:00
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
Archive();
|
|
|
|
|
}
|
|
|
|
|
catch (FileNotFoundException)
|
|
|
|
|
{
|
|
|
|
|
if (disposing)
|
|
|
|
|
throw;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
File.Delete(TempFile);
|
2017-04-12 17:08:54 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|