namespace Sunfish.Log;
public enum LogLevel { Detail, Info, Warning, Error }
public sealed record LogEntry(DateTime Time, LogLevel Level, string Message);
/// <summary>
/// Registro del servidor: guarda las ultimas entradas en memoria (para las interfaces)
/// y avisa de cada entrada nueva con <see cref="Written"/>.
/// </summary>
public sealed class ServerLog
{
private readonly object _lock = new();
private readonly Queue<LogEntry> _recent = new();
private readonly int _capacity;
public ServerLog(int capacity = 1000) => _capacity = capacity;
/// <summary>Se dispara en el hilo que escribe; las interfaces deben pasar a su propio hilo.</summary>
public event Action<LogEntry>? Written;
public LogLevel MinimumLevel { get; set; } = LogLevel.Info;
public void Detail(string message) => Write(LogLevel.Detail, message);
public void Info(string message) => Write(LogLevel.Info, message);
public void Warning(string message) => Write(LogLevel.Warning, message);
public void Error(string message) => Write(LogLevel.Error, message);
public void Write(LogLevel level, string message)
{
if (level < MinimumLevel)
return;
var entry = new LogEntry(DateTime.Now, level, message);
lock (_lock)
{
_recent.Enqueue(entry);
while (_recent.Count > _capacity)
_recent.Dequeue();
}
Written?.Invoke(entry);
}
public LogEntry[] Recent()
{
lock (_lock)
return _recent.ToArray();
}
}