.Net 6.0 .Net7.0 .Net8.0 .Net9.0 使用 Serilog 按日志等级写入日志及 appsetting.json 配置方式实现

前言 

    最近使用最新版的Serilog记录日志时,发现以前有些关于Serilog的Nuget弃用了,最关键的是有些配置写法也改变,于是就整理了一下最新版的Serilog配置方式(appsetting.json)的使用

说明:我是用的.Net6,最新长期支持版到.Net8了,不过Serilog我用的是最新版,配置方式都一样

1.安装Serilog相关Nuget包

新版Serilog相关Nuget

Serilog.AspNetCore
Serilog.Expressions
Serilog.Sinks.File

也可以把下面代码直接放入.csjproj工程项目文件中,把这三个包引用放进ItemGroup标签内,所需Nuget包会自动下载

 <ItemGroup>
  <PackageReference Include="Serilog.AspNetCore" Version="8.0.1" />
  <PackageReference Include="Serilog.Expressions" Version="4.0.0" />
  <PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
 </ItemGroup>

本文项目使用.Net9.0: 

<ItemGroup>
  <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.0" />
  <PackageReference Include="Serilog.AspNetCore" Version="9.0.0" />
  <PackageReference Include="Serilog.Expressions" Version="5.0.0" />
  <PackageReference Include="Serilog.Sinks.File" Version="6.0.0" />
</ItemGroup> 

.NET6.0、.NET7.0、.NET8.0 Serilog版本如下:

较旧版本如下 :

2.Program代码如下

.NET6.0、.NET7.0、.NET8.0 Program.cs代码如下: 虽然使用.NET6.0 写法基本一致

using Serilog;
namespace WebAppNet6_Serilog
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);
            //使用Serilog
            builder.Host.UseSerilog((context, logger) =>
            {
                //Serilog读取配置
                logger.ReadFrom.Configuration(context.Configuration);
                logger.Enrich.FromLogContext();
            });

 
            // Add services to the container.
 
            builder.Services.AddControllers();
            // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
            builder.Services.AddEndpointsApiExplorer();
            builder.Services.AddSwaggerGen();
 
            var app = builder.Build();
 
            // Configure the HTTP request pipeline.
            if (app.Environment.IsDevelopment())
            {
                app.UseSwagger();
                app.UseSwaggerUI();
            }
 
            app.UseAuthorization();
 
 
            app.MapControllers();
 
            app.Run();
        }
    }

.NET 9.0 Program.cs代码: 

using Serilog;

var builder = WebApplication.CreateBuilder(args);

//使用Serilog
builder.Host.UseSerilog((context, logger) =>
{
    //Serilog读取配置
    logger.ReadFrom.Configuration(context.Configuration);
    logger.Enrich.FromLogContext();
});

// Add services to the container.

builder.Services.AddControllers();
// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
builder.Services.AddOpenApi();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.MapOpenApi();
}

app.UseAuthorization();

app.MapControllers();

app.Run();

3.配置文件(appsetting.json)代码如下

"Serilog": {
   //"Using": [
   //  "Serilog.Sinks.RollingFile", //老版本的写入日志文件的Nuget包,现在已经弃用,请改用Serilog.Sinks.File
   //  "Serilog.Sinks.Console",
   //  "Serilog.Filters.Expressions" //老版本的日志过滤Nuget包,现在已经弃用,请改用Serilog.Expressions
   //],
   "Using": [ "Serilog.Sinks.File", "Serilog.Expressions" ],
   "MinimumLevel": {
     "Default": "Information", //最小记录日志级别
     "Override": {
       "Default": "Information",
       "System": "Information",
       "Microsoft": "Information"
     }
   },
   "Enrich": [ "FromLogContext", "WithThreadId" ],
   "WriteTo": [
     {
       "Name": "Console",
       "Args": {
         "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss,fff} [{Level}] [{SourceContext}] {Message:lj}{NewLine}{Exception}"
       }
     },
     {
       "Name": "Logger",
       "Args": {
         "configureLogger": {
           "Filter": [
             {
               "Name": "ByIncludingOnly",
               "Args": {
                 "expression": "@l = 'Information'"
               }
             }
           ],
           "WriteTo": [
             {
               "Name": "File",
               "Args": {
                 "path": "Logs/Info/log.txt",
                 "rollingInterval": "Day",
                 //"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss,fff} LogLevel:{Level} {Message:lj}{NewLine}{Exception}"
                 "outputTemplate": "【时间】{Timestamp:yyyy-MM-dd HH:mm:ss,fff}{NewLine}【等级】[{Level}]{NewLine}【消息】[{SourceContext}] {Message:lj}{NewLine}{Exception}{NewLine}"
               }
             }
           ]
         }
       }
     },
     {
       "Name": "Logger",
       "Args": {
         "configureLogger": {
           "Filter": [
             {
               "Name": "ByIncludingOnly",
               "Args": {
                 "expression": "@l= 'Warning'"
               }
             }
           ],
           "WriteTo": [
             {
               "Name": "File",
               "Args": {
                 "path": "Logs/Warn/log.txt",
                 "rollingInterval": "Day",
                 //"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss,fff} WARNING {ClassName}:0 - [{Version}] [{HttpRequestIP}] [{AppName}] {Message:lj}{NewLine}{Exception}"
                 //"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss,fff}[{Level}]{HttpRequestId}{Message:lj}{NewLine}{Exception}{NewLine}"
                 "outputTemplate": "【时间】{Timestamp:yyyy-MM-dd HH:mm:ss,fff}{NewLine}【等级】[{Level}]{NewLine}【消息】[{SourceContext}] {Message:lj}{NewLine}{Exception}{NewLine}"
               }
             }
           ]
         }
       }
     },
     {
       "Name": "Logger",
       "Args": {
         "configureLogger": {
           "Filter": [
             {
               "Name": "ByIncludingOnly",
               "Args": {
                 "expression": "@l= 'Error'"
               }
             }
           ],
           "WriteTo": [
             {
               "Name": "File",
               "Args": {
                 "path": "Logs/Error/log.txt",
                 "rollingInterval": "Day",
                 //"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss,fff} ERROR {ClassName}:0 - [{Version}] [{HttpRequestIP}] [{AppName}] {Message:lj}{NewLine}{Exception}"
                 "outputTemplate": "【时间】{Timestamp:yyyy-MM-dd HH:mm:ss,fff}{NewLine}【等级】[{Level}]{NewLine}【消息】[{SourceContext}] {Message:lj}{NewLine}{Exception}{NewLine}"
               }
             }
           ]
         }
       }
     }
 
   ]
 } 

4.依赖注入方式使用Serilog记录日志文件

.NET6.0、.NET7.0、.NET8.0 WeatherForecastController.cs代码如下:  

private readonly ILogger<WeatherForecastController> _logger;
 
  //注入日志
  public WeatherForecastController(ILogger<WeatherForecastController> logger)
  {
      _logger = logger;
  }
 
  [HttpGet(Name = "GetWeatherForecast")]
  public IEnumerable<WeatherForecast> Get()
  {
      //记录日志
      _logger.LogInformation("测试LogInformation");
      _logger.LogWarning("测试LogWarning");
      _logger.LogError("测试LogError");
      return Enumerable.Range(1, 5).Select(index => new WeatherForecast
      {
          Date = DateTime.Now.AddDays(index),//如果这里报错,请看下面.NET9.0代码
          TemperatureC = Random.Shared.Next(-20, 55),
          Summary = Summaries[Random.Shared.Next(Summaries.Length)]
      })
      .ToArray();
  } 

.NET 9.0 SerilogController.cs代码: 

 [Route("api/[controller]")]
 [ApiController]
 public class SerilogController : ControllerBase
 {
     private readonly ILogger<SerilogController> _logger;

     //注入日志
     public SerilogController(ILogger<SerilogController> logger)
     {
         _logger = logger;
     }

     private static readonly string[] Summaries = new[]
    {
         "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
     };

     [HttpGet(Name = "SerilogTest")]
     public IEnumerable<WeatherForecast> Get()
     {
         //记录日志
         _logger.LogInformation("测试LogInformation");
         _logger.LogWarning("测试LogWarning");
         _logger.LogError("测试LogError");
         return Enumerable.Range(1, 5).Select(index => new WeatherForecast
         {
             Date = DateOnly.Parse(DateTime.Now.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture)),
             TemperatureC = Random.Shared.Next(-20, 55),
             Summary = Summaries[Random.Shared.Next(Summaries.Length)]
         })
         .ToArray();
     }
 }

调试运行后,复制下面启动后界面输出的地址到浏览器,打开即可: 

在地址后面加:/api/serilog,看你控制器的配置 

5.效果

按日志级别,记录的内容就在这三个txt日志文件中 

参考文章:.Net Core(.Net6) 使用Serilog按日志等级写入日志,appsetting.json配置方式实现 - Misterj - 博客园

如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。  

在C# ASP.NET MVC应用程序中,若需要从类库的`appsettings.json`文件中读取配置值,通常的做法是结合依赖注入和`IConfiguration`接口来实现。ASP.NET Core提供了一套灵活的配置系统,支持从多种来源(如JSON文件、环境变量等)加载配置信息。 ### 使用 `IConfiguration` 接口读取配置 1. **添加 `appsettings.json` 文件** 确保在类库项目中已添加了`appsettings.json`文件,并且其内容格式如下: ```json { "AppSettings": { "SiteName": "Professional C# Sample" }, "Data": { "DefaultConnection": { "ConnectionString": "Server=(localdb)\\MSSQLLocalDB;Database=_CHANGE_ME;Trusted_Connection=True;" } } } ``` 2. **注册配置服务** 在主应用程序(如ASP.NET Core MVC项目)的`Startup.cs`或`Program.cs`(适用于.NET 6及以上版本)中,确保已正确注册了配置服务。默认情况下,`CreateDefaultBuilder`方法会自动加载`appsettings.json`文件。 ```csharp public class Startup { public IConfiguration Configuration { get; } public Startup(IConfiguration configuration) { Configuration = configuration; } public void ConfigureServices(IServiceCollection services) { // 注册配置选项 services.Configure<AppSettings>(Configuration.GetSection("AppSettings")); services.AddControllersWithViews(); } } ``` 3. **定义配置模型类** 创建一个类来映射`appsettings.json`中的配置部分。例如,可以定义一个`AppSettings`类: ```csharp public class AppSettings { public string SiteName { get; set; } } ``` 4. **通过依赖注入使用配置** 在类库中,可以通过构造函数注入`IOptions<AppSettings>`来访问配置值: ```csharp public class MyService { private readonly AppSettings _appSettings; public MyService(IOptions<AppSettings> options) { _appSettings = options.Value; } public void PrintSiteName() { Console.WriteLine($"Site Name: {_appSettings.SiteName}"); } } ``` 5. **在控制器或其他服务中调用** 在控制器或其他服务中,可以直接注入`MyService`并调用其方法: ```csharp public class HomeController : Controller { private readonly MyService _myService; public HomeController(MyService myService) { _myService = myService; } public IActionResult Index() { _myService.PrintSiteName(); return View(); } } ``` ### 注意事项 - 确保`appsettings.json`文件的“复制到输出目录”属性设置为“始终复制”或“如果较新则复制”,以便在运行时能够正确读取。 - 如果类库项目本身不是ASP.NET Core项目,则无法直接使用`IConfiguration`,此时可以考虑将配置读取逻辑放在主应用程序中,并通过参数传递给类库。 - 配置值的读取是基于`IConfiguration`接口的,因此必须确保依赖注入容器中已注册相关服务[^2]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hefeng_aspnet

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值