ToB企服应用市场:ToB评测及商务社交产业平台

标题: .NET项目重构之日志服务(Serilog) [打印本页]

作者: 半亩花草    时间: 2023-7-25 18:21
标题: .NET项目重构之日志服务(Serilog)
1. 目录

2. 前言

定时任务中比较重要的一个环节就是日志记录,有了日志可以记录系统的操作过程,也可以在系统异常时方便排查错误原因。
比如定时任务经常要做的一个事情,同步其它异构系统数据到本系统。大多情况下的操作过程时,定时请求对方接口返回JSON格式数据,我方把接收到的数据再转换为C#对象进行业务处理后保存至数据库。如果在这个过程中发生系统异常,没有日志记录很有可能连复现BUG都很难做到。
所以在这个过程中,比较正确的日志记录方式是:
2.1. 日志控件的选择

之前所有项目用的基本都是老牌Log4net,而这次重构的一大主题是学习新东西嘛,所以我选择比较年轻一点的Serilog。
为什么选择Serilog? 嗯。。。。随便选的,其实用NLog也不是不行。
3. 日志配置

在Web项目下创建Extensions文件夹并添加SerilogSetup.cs文件。

添加如下NuGet包
添加全局静态变量,用于设置打印模板,至于写法。官网是最好的老师:https://github.com/serilog/serilog/wiki/Configuration-Basics#output-templates
  1.     private static readonly string logTemplate = "{NewLine}时闻:{Timestamp:yyyy-MM-dd HH:mm:ss.fff}{NewLine}日志等级:{Level}{NewLine}线程ID:{ThreadId} 线程名:{ThreadName}{NewLine}所在类:{SourceContext}{NewLine}日志信息:{Message}{NewLine}{Exception}";
复制代码
3.1. 控制台打印

接着添加静态方法AddSerilog
  1.     public static void AddSerilog(ConfigureHostBuilder builder)
  2.     {
  3.          // 打印到控制台
  4.          // 生产环境中可以不向控制台打印
  5.          builder.UseSerilog((context, logger) =>
  6.          {
  7.              // 添加此句后可以在“执行上下文”中动态添加和删除属性
  8.              logger.Enrich.FromLogContext();
  9.              logger.MinimumLevel.Information();
  10.              logger.Enrich.WithThreadId();
  11.              logger.Enrich.WithThreadName();
  12.              logger.WriteTo.Logger(lg => lg.WriteTo.Async(a =>
  13.                      a.Console(outputTemplate: logTemplate)));
  14.          });
  15.     }
复制代码
3.2. 文件打印

在AddSerilog方法中添加如下内容
  1.    // 打印到文件
  2.    builder.UseSerilog((context, logger) =>
  3.    {
  4.        logger.Enrich.FromLogContext();
  5.        logger.Enrich.WithThreadId();
  6.        logger.Enrich.WithThreadName();
  7.        logger.WriteTo.Logger(lg => lg.Filter.ByIncludingOnly(p => p.Level == LogEventLevel.Debug).WriteTo.Async(a => a.File(logDebug, rollingInterval: RollingInterval.Hour, outputTemplate: logTemplate)));
  8.        logger.WriteTo.Logger(lg => lg.Filter.ByIncludingOnly(p => p.Level == LogEventLevel.Information).WriteTo.Async(a => a.File(logInfo, rollingInterval: RollingInterval.Hour, outputTemplate: logTemplate)));
  9.        logger.WriteTo.Logger(lg => lg.Filter.ByIncludingOnly(p => p.Level == LogEventLevel.Warning).WriteTo.Async(a => a.File(logWarn, rollingInterval: RollingInterval.Hour, outputTemplate: logTemplate)));
  10.        logger.WriteTo.Logger(lg => lg.Filter.ByIncludingOnly(p => p.Level == LogEventLevel.Error).WriteTo.Async(a => a.File(logError, rollingInterval: RollingInterval.Hour, outputTemplate: logTemplate)));
  11.        logger.WriteTo.Logger(lg => lg.Filter.ByIncludingOnly(p => p.Level == LogEventLevel.Fatal).WriteTo.Async(a => a.File(logFatal, rollingInterval: RollingInterval.Hour, outputTemplate: logTemplate)));
  12.    });
复制代码
这里要注意的是,也可以写在一个方法内,我这样做的目的是为了可以一目了然的区分开不同日志的配置。
最后在Program.cs 中注册Serilog相关配置。
  1. SerilogSetup.AddSerilog(builder.Host);
复制代码
接下来就可以找个地方做打印测试了,比如在HomeController的Index的方法中加放入
  1.     _logger.LogInformation("控制台打印");
复制代码
4. 结语

目前阶段只是做了控制台和文件打印,以后也许会接入数据库打印。
因为后期想在Web页面查看定时任务的执行状况等等。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4