using TradingBot.Models;
using System.Collections.Concurrent;
namespace TradingBot.Services;
///
/// Centralized logging service for application events
///
public class LoggingService
{
private readonly ConcurrentQueue _logs = new();
private const int MaxLogEntries = 500;
public event Action? OnLogAdded;
///
/// Get all log entries
///
public IReadOnlyList GetLogs()
{
return _logs.ToList().AsReadOnly();
}
///
/// Add a debug log entry
///
public void LogDebug(string category, string message, string? details = null)
{
AddLog(Models.LogLevel.Debug, category, message, details);
}
///
/// Add an info log entry
///
public void LogInfo(string category, string message, string? details = null, string? symbol = null)
{
AddLog(Models.LogLevel.Info, category, message, details, symbol);
}
///
/// Add a warning log entry
///
public void LogWarning(string category, string message, string? details = null, string? symbol = null)
{
AddLog(Models.LogLevel.Warning, category, message, details, symbol);
}
///
/// Add an error log entry
///
public void LogError(string category, string message, string? details = null, string? symbol = null)
{
AddLog(Models.LogLevel.Error, category, message, details, symbol);
}
///
/// Add a trade log entry
///
public void LogTrade(string symbol, string message, string? details = null)
{
AddLog(Models.LogLevel.Trade, "Trading", message, details, symbol);
}
///
/// Clear all logs
///
public void ClearLogs()
{
_logs.Clear();
OnLogAdded?.Invoke();
}
///
/// Get logs filtered by level
///
public IReadOnlyList GetLogsByLevel(Models.LogLevel level)
{
return _logs.Where(l => l.Level == level).ToList().AsReadOnly();
}
///
/// Get logs filtered by category
///
public IReadOnlyList GetLogsByCategory(string category)
{
return _logs.Where(l => l.Category.Equals(category, StringComparison.OrdinalIgnoreCase))
.ToList()
.AsReadOnly();
}
///
/// Get logs filtered by symbol
///
public IReadOnlyList GetLogsBySymbol(string symbol)
{
return _logs.Where(l => l.Symbol != null && l.Symbol.Equals(symbol, StringComparison.OrdinalIgnoreCase))
.ToList()
.AsReadOnly();
}
private void AddLog(Models.LogLevel level, string category, string message, string? details = null, string? symbol = null)
{
var logEntry = new LogEntry
{
Level = level,
Category = category,
Message = message,
Details = details,
Symbol = symbol
};
_logs.Enqueue(logEntry);
// Maintain max size
while (_logs.Count > MaxLogEntries)
{
_logs.TryDequeue(out _);
}
OnLogAdded?.Invoke();
}
}