Files
SethDiscordBot/DiscordBotCore/Logging/Logger.cs

111 lines
4.2 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using DiscordBotCore.Interfaces.Logger;
using DiscordBotCore.Others;
namespace DiscordBotCore.Logging;
public sealed class Logger : ILogger
{
private FileStream _LogFileStream;
private readonly List<string> _LogMessageProperties = typeof(ILogMessage).GetProperties().Select(p => p.Name).ToList();
private Action<string, LogType>? _OutFunction;
public string LogMessageFormat { get ; set; }
public Logger(string logFolder, string logMessageFormat, Action<string, LogType>? outFunction = null)
{
this.LogMessageFormat = logMessageFormat;
var logFile = Path.Combine(logFolder, $"{DateTime.Now:yyyy-MM-dd}.log");
_LogFileStream = File.Open(logFile, FileMode.Append, FileAccess.Write, FileShare.Read);
this._OutFunction = outFunction ?? DefaultLogFunction;
}
private void DefaultLogFunction(string message, LogType logType)
{
Console.WriteLine($"[{logType}] {message}");
}
/// <summary>
/// Generate a formatted string based on the default parameters of the ILogMessage and a string defined as model
/// </summary>
/// <param name="message">The message</param>
/// <returns>A formatted string with the message values</returns>
private string GenerateLogMessage(ILogMessage message)
{
string messageAsString = new string(LogMessageFormat);
foreach (var prop in _LogMessageProperties)
{
Type messageType = typeof(ILogMessage);
messageAsString = messageAsString.Replace("{" + prop + "}", messageType?.GetProperty(prop)?.GetValue(message)?.ToString());
}
return messageAsString;
}
private async void LogToFile(string message)
{
byte[] messageAsBytes = System.Text.Encoding.ASCII.GetBytes(message);
await _LogFileStream.WriteAsync(messageAsBytes, 0, messageAsBytes.Length);
byte[] newLine = System.Text.Encoding.ASCII.GetBytes(Environment.NewLine);
await _LogFileStream.WriteAsync(newLine, 0, newLine.Length);
await _LogFileStream.FlushAsync();
}
private string GenerateLogMessage(ILogMessage message, string customFormat)
{
string messageAsString = customFormat;
foreach (var prop in _LogMessageProperties)
{
Type messageType = typeof(ILogMessage);
messageAsString = messageAsString.Replace("{" + prop + "}", messageType?.GetProperty(prop)?.GetValue(message)?.ToString());
}
return messageAsString;
}
public void Log(ILogMessage message, string format)
{
string messageAsString = GenerateLogMessage(message, format);
_OutFunction?.Invoke(messageAsString, message.LogMessageType);
LogToFile(messageAsString);
}
public void Log(ILogMessage message)
{
string messageAsString = GenerateLogMessage(message);
_OutFunction?.Invoke(messageAsString, message.LogMessageType);
LogToFile(messageAsString);
}
public void Log(string message) => Log(new LogMessage(message, string.Empty, LogType.Info));
public void Log(string message, LogType logType, string format) => Log(new LogMessage(message, logType), format);
public void Log(string message, LogType logType) => Log(new LogMessage(message, logType));
public void Log(string message, object Sender) => Log(new LogMessage(message, Sender));
public void Log(string message, object Sender, LogType type) => Log(new LogMessage(message, Sender, type));
public void LogException(Exception exception, object Sender, bool logFullStack = false) => Log(LogMessage.CreateFromException(exception, Sender, logFullStack));
public void SetOutFunction(Action<string, LogType> outFunction)
{
this._OutFunction = outFunction;
}
public string GetLogsHistory()
{
string fileName = _LogFileStream.Name;
_LogFileStream.Flush();
_LogFileStream.Close();
string[] logs = File.ReadAllLines(fileName);
_LogFileStream = File.Open(fileName, FileMode.Append, FileAccess.Write, FileShare.Read);
return string.Join(Environment.NewLine, logs);
}
}