using System; using System.Collections.ObjectModel; using System.IO; using System.Text; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; namespace Sln.Wcs.UI.ViewModels; public partial class SystemMonitorViewModel : ObservableObject { [ObservableProperty] private ObservableCollection _logs = new(); [ObservableProperty] private int _logCount; [ObservableProperty] private string _filterText = string.Empty; [ObservableProperty] private bool _autoScroll = true; private const int MaxLogs = 5000; public SystemMonitorViewModel() { // 安装控制台输出拦截器 var original = Console.Out; var writer = new LogTextWriter(original, entry => { Avalonia.Threading.Dispatcher.UIThread.Post(() => { Logs.Add(entry); if (Logs.Count > MaxLogs) Logs.RemoveAt(0); LogCount = Logs.Count; }); }); Console.SetOut(writer); } [RelayCommand] private void Clear() { Logs.Clear(); LogCount = 0; } [RelayCommand] private void ToggleAutoScroll() { AutoScroll = !AutoScroll; } } public class LogEntry { public DateTime Time { get; set; } public string TimeText => Time.ToString("HH:mm:ss.fff"); public string Message { get; set; } = string.Empty; public string Level { get; set; } = "INFO"; } /// /// 拦截 Console.WriteLine 输出,同时写入原始输出和 ObservableCollection /// internal class LogTextWriter : TextWriter { private readonly TextWriter _original; private readonly Action _onWrite; private readonly StringBuilder _buffer = new(); public LogTextWriter(TextWriter original, Action onWrite) { _original = original; _onWrite = onWrite; } public override Encoding Encoding => Encoding.UTF8; public override void Write(char value) { _original.Write(value); if (value == '\n') { FlushBuffer(); } else if (value != '\r') { _buffer.Append(value); } } public override void WriteLine(string? message) { _original.WriteLine(message); if (message != null) { _onWrite(new LogEntry { Time = DateTime.Now, Message = message, Level = "INFO" }); } } private void FlushBuffer() { var msg = _buffer.ToString(); _buffer.Clear(); if (msg.Length > 0) { _onWrite(new LogEntry { Time = DateTime.Now, Message = msg, Level = "INFO" }); } } }