50 lines
1.5 KiB
C#
50 lines
1.5 KiB
C#
using System;
|
|
using System.Collections.Concurrent;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Serilog.Core;
|
|
using Serilog.Events;
|
|
|
|
namespace XP.Common.Logging.ViewModels
|
|
{
|
|
/// <summary>
|
|
/// Serilog 自定义 Sink,将日志事件转发到 RealTimeLogViewerViewModel,并维护环形缓冲区
|
|
/// Custom Serilog Sink that forwards log events and maintains a ring buffer for history
|
|
/// </summary>
|
|
public class RealTimeLogSink : ILogEventSink
|
|
{
|
|
private const int BufferCapacity = 500;
|
|
private readonly ConcurrentQueue<LogEvent> _buffer = new();
|
|
|
|
/// <summary>
|
|
/// 全局单例实例 | Global singleton instance
|
|
/// </summary>
|
|
public static RealTimeLogSink Instance { get; } = new();
|
|
|
|
/// <summary>
|
|
/// 日志事件到达时触发 | Fired when a log event arrives
|
|
/// </summary>
|
|
public event Action<LogEvent>? LogEventReceived;
|
|
|
|
public void Emit(LogEvent logEvent)
|
|
{
|
|
// 入队缓冲区 | Enqueue to buffer
|
|
_buffer.Enqueue(logEvent);
|
|
while (_buffer.Count > BufferCapacity)
|
|
{
|
|
_buffer.TryDequeue(out _);
|
|
}
|
|
|
|
LogEventReceived?.Invoke(logEvent);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取缓冲区中的历史日志快照 | Get a snapshot of buffered history logs
|
|
/// </summary>
|
|
public List<LogEvent> GetBufferedHistory()
|
|
{
|
|
return _buffer.ToList();
|
|
}
|
|
}
|
|
}
|