- Добавлен RazorConsole.Core для интерактивного TUI-дашборда - ToolRegistryService: живое включение/отключение модулей и отдельных методов - InMemoryLogSink: кольцевой буфер логов с фильтрацией по модулю - TUI: 3 таба (Overview, Logs, Settings) - IToolModule: generic-интерфейс для легкого добавления новых MCP-модулей - Guard-проверка TryCheckEnabled() во всех существующих инструментах
48 lines
1.4 KiB
C#
48 lines
1.4 KiB
C#
using System.Collections.Concurrent;
|
|
|
|
namespace LazyBear.MCP.Services.Logging;
|
|
|
|
/// <summary>
|
|
/// Singleton, хранящий последние <see cref="Capacity"/> записей лога в памяти.
|
|
/// Безопасен для многопоточной записи.
|
|
/// </summary>
|
|
public sealed class InMemoryLogSink
|
|
{
|
|
public const int Capacity = 500;
|
|
|
|
private readonly ConcurrentQueue<LogEntry> _entries = new();
|
|
|
|
/// <summary>Событие вызывается при добавлении новой записи.</summary>
|
|
public event Action<LogEntry>? OnLog;
|
|
|
|
public void Add(LogEntry entry)
|
|
{
|
|
_entries.Enqueue(entry);
|
|
|
|
// Обрезаем старые записи
|
|
while (_entries.Count > Capacity)
|
|
{
|
|
_entries.TryDequeue(out _);
|
|
}
|
|
|
|
OnLog?.Invoke(entry);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Возвращает снимок всех записей. Опциональный фильтр по категории-префиксу.
|
|
/// </summary>
|
|
public IReadOnlyList<LogEntry> GetEntries(string? categoryPrefix = null)
|
|
{
|
|
var all = _entries.ToArray();
|
|
|
|
if (string.IsNullOrWhiteSpace(categoryPrefix))
|
|
{
|
|
return all;
|
|
}
|
|
|
|
return Array.FindAll(all, e => e.Category.StartsWith(categoryPrefix, StringComparison.OrdinalIgnoreCase));
|
|
}
|
|
|
|
public void Clear() => _entries.Clear();
|
|
}
|