当前位置: 首页> 汽车> 行情 > 长春网站制作诚推源晟_wap游戏制作_百度快照优化推广_下载班级优化大师并安装

长春网站制作诚推源晟_wap游戏制作_百度快照优化推广_下载班级优化大师并安装

时间:2025/8/23 16:09:20来源:https://blog.csdn.net/rwo_bear/article/details/134554248 浏览次数: 0次
长春网站制作诚推源晟_wap游戏制作_百度快照优化推广_下载班级优化大师并安装

目录

一、Serilog日志实现

1、实现 ILogEventSink接口

2、日志类Log

3、日志级别LogLevel 

4、ILogger接口

5、日志服务实现

6、日志视图View

7、ViewModel

二、功能扩展

1、日志扩展方法

2、Trace追踪扩展日志

3、自动滚动至底部


一、Serilog日志实现

安装NuGet包:Serilog

Sink有很多种,这里介绍两种:

                Console接收器(安装Serilog.Sinks.Console);

                File接收器(安装Serilog.Sinks.File);

MinimumLevel:最小记录级别

rollingInterval:生成日志文件周期

outputTemplate:输出日志模板

继承ILogEventSink接口实现 Emit:当Sink器接收到新日志时触发

通过该接口将接收器接收的日志添加进内部日志集合

将该接口实现类实例化对象通过WriteTo.Sink(myEventSink)与Logger绑定

1、实现 ILogEventSink接口

    public class LogEveSink : ILogEventSink{readonly object _lock = new object();static readonly Lazy<LogEveSink> _sink = new Lazy<LogEveSink>(() => new LogEveSink());public static LogEveSink Instance => _sink.Value;/// <summary>/// 日志内部集合/// </summary>private ObservableCollection<Log> _logs;/// <summary>/// 绑定到前台的日志视图/// </summary>public ListCollectionView Logs { get; set; }private LogEveSink(){_logs = new ObservableCollection<Log>();Logs = new ListCollectionView(_logs);}//private readonly ITextFormatter _formatter =//           new MessageTemplateTextFormatter("{Message} Location:{FilePath}[{LineNumber}]");public void Emit(LogEvent logEvent){lock (_lock){if (_logs.Count > 500){if (!Application.Current.CheckAccess())Application.Current.Dispatcher.Invoke(() =>{_logs.Clear();});else_logs.Clear();}if (logEvent != null){//var textWriter = new StringWriter();//_formatter.Format(logEvent, textWriter);if (!Application.Current.CheckAccess())Application.Current?.Dispatcher.InvokeAsync(() =>{_logs.Insert(0, new Log(){Time = logEvent?.Timestamp.ToString("yyyy-MM-dd HH:mm:ss.fff"),Level = logEvent.Level,User = "Auston",Message = logEvent.MessageTemplate.ToString() //textWriter.ToString()});});else{_logs.Insert(0, new Log(){Time = logEvent?.Timestamp.ToString("yyyy-MM-dd HH:mm:ss.fff"),Level = logEvent.Level,User = "Auston",Message = logEvent.MessageTemplate.ToString() //textWriter.ToString()});}}}}}

2、日志类Log

    public class Log{public string Time { get; set; }public LogEventLevel Level { get; set; }public string User { get; set; }public string Message { get; set; }}

3、日志级别LogLevel 

    public enum LogLevel{INFO,WARN,ERROR,DEBUG,FATAL}

4、ILogger接口

    public interface ILogger{void WriteLog(string message, LogLevel level=LogLevel.INFO);UserControl GetLogView();}

5、日志服务实现

    public class LoggerService : ILogger{public static LoggerService Default => new LoggerService();Serilog.ILogger logger;LogView logView = new LogView();//string outputTemplate = "{NewLine}Date: {Timestamp:yyyy-MM-dd HH:mm:ss.fff}\tLevel: {Level}\tCallName: {SourceContext}->{MemberName}"//     + "{NewLine}Path: {FilePath}[{LineNumber}]"//     + "{NewLine}Message: {Message}";string outputTemplate = "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} " +"[{Level:u3}] " +"Message:{Message}{NewLine}" +"{Exception}{NewLine}";public LoggerService(){logger = new LoggerConfiguration().Enrich.FromLogContext()//记录相关上下文信息.MinimumLevel.Debug().WriteTo.Sink(LogEveSink.Instance).WriteTo.File("Logs\\ALL\\.txt", rollingInterval: RollingInterval.Day, outputTemplate: outputTemplate).WriteTo.Logger(log => log.Filter.ByIncludingOnly(p => p.Level == LogEventLevel.Error).WriteTo.File("Logs\\Error\\.txt", rollingInterval: RollingInterval.Day, outputTemplate: outputTemplate)).CreateLogger();}public void WriteLog(string message, LogLevel level = LogLevel.INFO){switch (level){case LogLevel.DEBUG:logger.Debug(message);break;case LogLevel.INFO:logger.Information(message);break;case LogLevel.WARN:logger.Warning(message);break;case LogLevel.ERROR:logger.Error(message);break;case LogLevel.FATAL:logger.Fatal(message);break;default:logger.Verbose(message);break;}}public UserControl GetLogView(){return logView;}}

6、日志视图View

<UserControl x:Class="Test.Logger.View.LogView"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"xmlns:vm="clr-namespace:Test.Logger.ViewModel"x:Name="LogUC" d:DesignHeight="450"d:DesignWidth="800" mc:Ignorable="d"><UserControl.DataContext><vm:LogViewModel x:Name="viewmodel" /></UserControl.DataContext><UserControl.Resources><ResourceDictionary><ResourceDictionary.MergedDictionaries><ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/SkinDefault.xaml" /><ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/Theme.xaml" /></ResourceDictionary.MergedDictionaries><!--<CollectionViewSource x:Key="SortSoruce" Source="{Binding ElementName=viewmodel, Path=LogSink.Logs}"><CollectionViewSource.SortDescriptions><scm:SortDescription Direction="Descending" PropertyName="Time" /></CollectionViewSource.SortDescriptions></CollectionViewSource>--></ResourceDictionary></UserControl.Resources><Grid><Grid.RowDefinitions><RowDefinition Height="Auto" /><RowDefinition Height="*" /></Grid.RowDefinitions><StackPanel Margin="5" VerticalAlignment="Center"Orientation="Horizontal"><RadioButton Margin="5"Command="{Binding LogFilter}"CommandParameter="0" Content="ALL"FontWeight="Bold" GroupName="filter"IsChecked="True" /><RadioButton Margin="5"Command="{Binding LogFilter}"CommandParameter="1" Content="INFO"FontWeight="Bold" Foreground="Green"GroupName="filter" /><RadioButton Margin="5"Command="{Binding LogFilter}"CommandParameter="2" Content="WARN"FontWeight="Bold" Foreground="Orange"GroupName="filter" /><RadioButton Margin="5"Command="{Binding LogFilter}"CommandParameter="3" Content="ERROR"FontWeight="Bold" Foreground="Red"GroupName="filter" /></StackPanel><DataGrid Grid.Row="1" Margin="5"AutoGenerateColumns="False"EnableColumnVirtualization="True"EnableRowVirtualization="True" FontWeight="Bold"IsReadOnly="True"ItemsSource="{Binding ElementName=viewmodel, Path=LogSink.Logs}"VirtualizingPanel.IsVirtualizing="True"VirtualizingPanel.VirtualizationMode="Recycling"><DataGrid.Columns><DataGridTextColumn Width="Auto"Binding="{Binding Time}"Header="Time" /><DataGridTextColumn Width="Auto"Binding="{Binding Level}"Header="Level" /><DataGridTextColumn Width="Auto"Binding="{Binding User}"Header="User" /><DataGridTextColumn Width="*"Binding="{Binding Message}"Header="Message"><DataGridTextColumn.ElementStyle><Style><Setter Property="TextBlock.TextWrapping" Value="Wrap" /><Setter Property="TextBlock.TextAlignment" Value="Left" /></Style></DataGridTextColumn.ElementStyle></DataGridTextColumn></DataGrid.Columns><DataGrid.RowStyle><Style TargetType="DataGridRow" BasedOn="{StaticResource DataGridRowStyle}"><Style.Triggers><DataTrigger Binding="{Binding Level}" Value="Information"><Setter Property="Foreground" Value="Green" /></DataTrigger><DataTrigger Binding="{Binding Level}" Value="Warning"><Setter Property="Foreground" Value="Orange" /></DataTrigger><DataTrigger Binding="{Binding Level}" Value="Error"><Setter Property="Foreground" Value="Red" /></DataTrigger></Style.Triggers></Style></DataGrid.RowStyle></DataGrid></Grid>
</UserControl>

7、ViewModel

    public class LogViewModel : ObservableObject{private LogEveSink logSink = LogEveSink.Instance;public LogEveSink LogSink{get => logSink;set => SetProperty(ref logSink, value);}/// <summary>/// 日志过滤命令/// </summary>public RelayCommand<string> LogFilter{get{return new RelayCommand<string>((para) =>{DoFilter(para);});}}/// <summary>/// 日志过滤命令注册函数/// </summary>/// <param name="mask"></param>private void DoFilter(string mask){switch (mask){case "0":LogSink.Logs.Filter = null;break;case "1":LogSink.Logs.Filter = i => ((Log)i).Level == LogEventLevel.Information || ((Log)i).Level == LogEventLevel.Verbose || ((Log)i).Level == LogEventLevel.Debug;break;case "2":LogSink.Logs.Filter = i => ((Log)i).Level == LogEventLevel.Warning;break;case "3":LogSink.Logs.Filter = i => ((Log)i).Level == LogEventLevel.Error || ((Log)i).Level == LogEventLevel.Fatal;break;}LogSink.Logs.Refresh();}}

二、功能扩展

1、日志扩展方法

    static class LogExtension{public static void CallError<T>(this ILogger logger, string message,[CallerMemberName] string meberName = "",[CallerFilePath] string filepath = "",[CallerLineNumber] int lineNum = 0)=> logger.ForContext<T>().ForContext("MemberName", meberName).ForContext("FilePath", filepath).ForContext("LineNumber", lineNum).Error(message);public static void CallError<T>(this ILogger logger, Exception e, string message,[CallerMemberName] string meberName = "",[CallerFilePath] string filepath = "",[CallerLineNumber] int lineNum = 0)=> logger.ForContext<T>().ForContext("MemberName", meberName).ForContext("FilePath", filepath).ForContext("LineNumber", lineNum).Error(e, message);}

2、Trace追踪扩展日志

继承抽象类TraceListener,重写方法TraceEvent

注意:添加监听对象Trace.Listeners.Add(this),推荐放到App.cs;

    public class TraceLog{public string Message { get; set; }public LogLevel Level { get; set; }}public class LoggerTraceListener : TraceListener{public static LoggerTraceListener Default => new LoggerTraceListener();public LoggerTraceListener(){Trace.Listeners.Add(this);}ILogger logger;ConcurrentQueue<TraceLog> _traceLogs = new ConcurrentQueue<TraceLog>();public void InitLogger(){logger = IOCService.Instance.AccessService<ILogger>();if (logger != null){Task.Run(() =>{while (_traceLogs.TryDequeue(out TraceLog log)){logger.WriteLog(log.Message, log.Level);}});}}public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string message){LogLevel logLevel = LogLevel.INFO;switch (eventType){case TraceEventType.Error:logLevel = LogLevel.ERROR;break;case TraceEventType.Warning:logLevel = LogLevel.WARN;break;case TraceEventType.Information:logLevel = LogLevel.INFO;break;default:logLevel = LogLevel.DEBUG;break;}if (logger != null){logger.WriteLog(message, logLevel);return;}_traceLogs.Enqueue(new TraceLog() { Message = message, Level = logLevel });}public override void Write(string message){//MessageBox.Show(message);}public override void WriteLine(string message){//MessageBox.Show(message + "\r\n");}}

3、自动滚动至底部

通过ObservableCollection类的CollectionChanged事件实现日志自动滚动到底部:

        集合改变触发事件,更改附加属性AutoScroll值,值更改触发CallBack将日志滚动到底部;

注意:MouseEnterMouseLeave两事件的响应原因:查看日志时,防止日志自动滚动到底部;

        <DataGrid attach:ScrollHelper.AutoScroll="{Binding AutoScroll}"AutoGenerateColumns="False"CanUserAddRows="False"CanUserDeleteRows="False"CanUserReorderColumns="False"CanUserResizeColumns="False"CanUserResizeRows="False"CanUserSortColumns="False"ItemsSource="{Binding LogService.Logs}"><i:Interaction.Triggers><i:EventTrigger EventName="MouseEnter"><i:InvokeCommandAction Command="{Binding MouseEnterCommand}" /></i:EventTrigger><i:EventTrigger EventName="MouseLeave"><i:InvokeCommandAction Command="{Binding MouseLeaveCommand}" /></i:EventTrigger></i:Interaction.Triggers><DataGrid.Columns><DataGridTextColumn Binding="{Binding Time}" Header="时间" /><DataGridTextColumn Binding="{Binding Lev}" Header="级别" /><DataGridTextColumn Binding="{Binding Message}" Header="信息"><DataGridTextColumn.ElementStyle><Style><Setter Property="TextBlock.TextWrapping" Value="Wrap" /><Setter Property="TextBlock.TextAlignment" Value="Left" /></Style></DataGridTextColumn.ElementStyle></DataGridTextColumn></DataGrid.Columns><DataGrid.RowStyle><Style TargetType="DataGridRow" BasedOn="{StaticResource DataGridRowStyle}"><Style.Triggers><DataTrigger Binding="{Binding Lev}" Value="Error"><Setter Property="Foreground" Value="Red"/></DataTrigger><DataTrigger Binding="{Binding Lev}" Value="Warn"><Setter Property="Foreground" Value="Orange"/></DataTrigger></Style.Triggers></Style></DataGrid.RowStyle></DataGrid>
        public LogService LogService { get; set; }=LogService.GetInstance();private bool _autoScroll;public bool AutoScroll{get { return _autoScroll; }set => SetProperty(ref _autoScroll, value);}[RelayCommand]public void MouseEnter(){LogService._logs.CollectionChanged -= Scroll;}[RelayCommand]public void MouseLeave(){LogService._logs.CollectionChanged += Scroll;}private void Scroll(object sender, NotifyCollectionChangedEventArgs e){AutoScroll = !AutoScroll;}public MainWinViewModel(){LogService.OpenListen();LogService._logs.CollectionChanged += Scroll;}

关键字:长春网站制作诚推源晟_wap游戏制作_百度快照优化推广_下载班级优化大师并安装

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: