142 lines
4.4 KiB
C#
142 lines
4.4 KiB
C#
using System.Collections.ObjectModel;
|
|
using System.IO;
|
|
using System.Text;
|
|
using System.Windows;
|
|
using System.Windows.Threading;
|
|
using EmbyToolbox.ViewModels;
|
|
|
|
namespace EmbyToolbox.Services;
|
|
|
|
public sealed class LoggingService
|
|
{
|
|
private const int UiLogLimit = 1000;
|
|
private readonly string _logsDirectory;
|
|
|
|
public LoggingService()
|
|
{
|
|
_logsDirectory = Path.Combine(
|
|
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
|
|
"EmbyToolbox",
|
|
"Logs");
|
|
Directory.CreateDirectory(_logsDirectory);
|
|
}
|
|
|
|
public ObservableCollection<LogEntryViewModel> UiEntries { get; } = new();
|
|
|
|
public LogLevel MinimumFileLogLevel { get; set; } = LogLevel.Info;
|
|
|
|
public string LogsDirectory => _logsDirectory;
|
|
|
|
public void Debug(string message, string module = "app", Exception? exception = null, string? command = null, string? stdout = null, string? stderr = null)
|
|
{
|
|
Write(LogLevel.Debug, message, module, exception, command, stdout, stderr);
|
|
}
|
|
|
|
public void Info(string message, string module = "app", Exception? exception = null, string? command = null, string? stdout = null, string? stderr = null)
|
|
{
|
|
Write(LogLevel.Info, message, module, exception, command, stdout, stderr);
|
|
}
|
|
|
|
public void Warning(string message, string module = "app", Exception? exception = null, string? command = null, string? stdout = null, string? stderr = null)
|
|
{
|
|
Write(LogLevel.Warning, message, module, exception, command, stdout, stderr);
|
|
}
|
|
|
|
public void Error(string message, string module = "app", Exception? exception = null, string? command = null, string? stdout = null, string? stderr = null)
|
|
{
|
|
Write(LogLevel.Error, message, module, exception, command, stdout, stderr);
|
|
}
|
|
|
|
public void ClearUi()
|
|
{
|
|
UiEntries.Clear();
|
|
}
|
|
|
|
private void Write(LogLevel level, string message, string module, Exception? exception, string? command, string? stdout, string? stderr)
|
|
{
|
|
var now = DateTime.Now;
|
|
var entry = new LogEntryViewModel
|
|
{
|
|
Timestamp = now,
|
|
Level = level,
|
|
LevelText = level.ToString(),
|
|
Module = module,
|
|
Message = message
|
|
};
|
|
|
|
AddUiEntryThreadSafe(entry);
|
|
|
|
if (level < MinimumFileLogLevel)
|
|
{
|
|
return;
|
|
}
|
|
|
|
WriteToFile(now, level, module, message, exception, command, stdout, stderr);
|
|
}
|
|
|
|
private void AddUiEntryThreadSafe(LogEntryViewModel entry)
|
|
{
|
|
var dispatcher = Application.Current?.Dispatcher;
|
|
if (dispatcher is null || dispatcher.CheckAccess())
|
|
{
|
|
UiEntries.Add(entry);
|
|
while (UiEntries.Count > UiLogLimit)
|
|
{
|
|
UiEntries.RemoveAt(0);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
dispatcher.BeginInvoke(
|
|
DispatcherPriority.DataBind,
|
|
new Action(
|
|
() =>
|
|
{
|
|
UiEntries.Add(entry);
|
|
while (UiEntries.Count > UiLogLimit)
|
|
{
|
|
UiEntries.RemoveAt(0);
|
|
}
|
|
}));
|
|
}
|
|
|
|
private void WriteToFile(DateTime timestamp, LogLevel level, string module, string message, Exception? exception, string? command, string? stdout, string? stderr)
|
|
{
|
|
var path = Path.Combine(_logsDirectory, $"app-{timestamp:yyyy-MM-dd}.log");
|
|
var sb = new StringBuilder();
|
|
|
|
sb.Append('[').Append(timestamp.ToString("yyyy-MM-dd HH:mm:ss")).Append("] ");
|
|
sb.Append(level.ToString().ToUpperInvariant()).Append(" ");
|
|
sb.Append("module=").Append(module).Append(" ");
|
|
sb.Append("message=").Append(message);
|
|
sb.AppendLine();
|
|
|
|
if (exception is not null)
|
|
{
|
|
sb.AppendLine("exception:");
|
|
sb.AppendLine(exception.ToString());
|
|
}
|
|
|
|
if (!string.IsNullOrWhiteSpace(command))
|
|
{
|
|
sb.Append("command: ").AppendLine(command);
|
|
}
|
|
|
|
if (!string.IsNullOrWhiteSpace(stdout))
|
|
{
|
|
sb.AppendLine("stdout:");
|
|
sb.AppendLine(stdout);
|
|
}
|
|
|
|
if (!string.IsNullOrWhiteSpace(stderr))
|
|
{
|
|
sb.AppendLine("stderr:");
|
|
sb.AppendLine(stderr);
|
|
}
|
|
|
|
sb.AppendLine(new string('-', 80));
|
|
File.AppendAllText(path, sb.ToString(), Encoding.UTF8);
|
|
}
|
|
}
|