using System.Collections.Concurrent; namespace LazyBear.MCP.Services.Logging; /// /// Singleton, хранящий последние записей лога в памяти. /// Безопасен для многопоточной записи. /// public sealed class InMemoryLogSink { public const int Capacity = 500; private readonly ConcurrentQueue _entries = new(); /// Событие вызывается при добавлении новой записи. public event Action? OnLog; public void Add(LogEntry entry) { _entries.Enqueue(entry); // Обрезаем старые записи while (_entries.Count > Capacity) { _entries.TryDequeue(out _); } OnLog?.Invoke(entry); } /// /// Возвращает снимок всех записей. Опциональный фильтр по категории-префиксу. /// public IReadOnlyList 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(); }