.NET 集成 日志 (Serilog/NLog)、AOP、简单限流

一、环境准备(新建 .NET Web API)

  先安装所有需要的 NuGet 包:  

必装包

 

# AOP 核心
Install-Package Autofac
Install-Package Autofac.Extras.DynamicProxy
Install-Package Microsoft.Extensions.DependencyInjection

# Serilog 二选一
Install-Package Serilog
Install-Package Serilog.AspNetCore
Install-Package Serilog.Sinks.Console
Install-Package Serilog.Sinks.File

# NLog 二选一
Install-Package NLog Install-Package NLog.Web.AspNetCore # 限流 Install-Package AspNetCoreRateLimit 

   


 

二、日志实现(二选一即可)

 

方案 1:Serilog(简洁强大)

 

1. Program.cs 配置

 

using Serilog;

var builder = WebApplication.CreateBuilder(args);

// 配置 Serilog
Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Information()
    .Enrich.FromLogContext()
    .WriteTo.Console() // 输出到控制台
    .WriteTo.File("Logs/log-.txt", rollingInterval: RollingInterval.Day) // 按天切割
    .CreateLogger();

builder.Host.UseSerilog(); // 替换系统默认日志

builder.Services.AddControllers();
var app = builder.Build();

app.MapControllers();
app.Run();

 

2. 使用日志

 

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

    // 直接注入使用
    public TestController(ILogger<TestController> logger)
    {
        _logger = logger;
    }

    [HttpGet]
    public IActionResult Get()
    {
        _logger.LogInformation("请求 Test 接口");
        return Ok("Hello Serilog");
    }
}

 


 

方案 2:NLog(配置灵活)

 

1. 添加 nlog.config 文件

  xml  

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      autoReload="true">

  <targets>
    <target xsi:type="Console" name="console"/>
    <target xsi:type="File" name="file" fileName="logs/${shortdate}.log" layout="${longdate}|${level}|${message} ${exception:format=tostring}"/>
  </targets>

  <rules>
    <logger name="*" minlevel="Info" writeTo="console,file"/>
  </rules>
</nlog>

 

2. Program.cs

 

var builder = WebApplication.CreateBuilder(args);
builder.Host.UseNLog(); // 使用 NLog
builder.Services.AddControllers();

var app = builder.Build();
app.MapControllers();
app.Run();

    使用方式和 Serilog 完全一样,直接注入
ILogger<T> 即可。  


 

三、AOP 切面编程(Autofac + 拦截器)

 

用途:自动记录方法执行日志、耗时、异常,不用每个方法手写

 

1. 编写 AOP 拦截器

 

using Castle.DynamicProxy;
using Microsoft.Extensions.Logging;
using System.Diagnostics;

public class LogInterceptor : IInterceptor
{
    private readonly ILogger<LogInterceptor> _logger;

    public LogInterceptor(ILogger<LogInterceptor> logger)
    {
        _logger = logger;
    }

    public void Intercept(IInvocation invocation)
    {
        var method = invocation.Method;
        var stopwatch = Stopwatch.StartNew();

        try
        {
            _logger.LogInformation($"【AOP 执行】 {method.DeclaringType.Name}.{method.Name} 开始");
            
            // 执行目标方法
            invocation.Proceed();

            stopwatch.Stop();
            _logger.LogInformation($"【AOP 完成】 {method.Name},耗时:{stopwatch.ElapsedMilliseconds} ms");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"【AOP 异常】 {method.Name} 执行出错");
            throw;
        }
    }
}

 

2. 注册 Autofac + AOP

 

using Autofac;
using Autofac.Extras.DynamicProxy;

var builder = WebApplication.CreateBuilder(args);
builder.Host.UseSerilog();

// Autofac 容器
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
builder.Host.ConfigureContainer<ContainerBuilder>(containerBuilder =>
{
    // 注册拦截器
    containerBuilder.RegisterType<LogInterceptor>();

    // 注册需要 AOP 的服务(示例:TestService)
    containerBuilder.RegisterType<TestService>()
        .As<ITestService>()
        .EnableInterfaceInterceptors() // 开启接口拦截
        .InterceptedBy(typeof(LogInterceptor)); // 使用拦截器
});

builder.Services.AddControllers();

 

   

功能 .NET 自带 DI Autofac
上手难度 ⭐ 极简单 ⭐⭐ 简单
构造函数注入 支持 支持
生命周期管理 基础 更精细
批量注册 不支持 一键批量注入
属性注入 不支持 支持
AOP 切面 很难 完美支持
模块化配置
性能 更快

 

 

3. 测试服务 + 接口

 

// 接口
public interface ITestService
{
    void Test();
}

// 实现
public class TestService : ITestService
{
    public void Test()
    {
        Console.WriteLine("业务方法执行");
    }
}

// 控制器
[ApiController]
[Route("[controller]")]
public class TestController : ControllerBase
{
    private readonly ITestService _testService;

    public TestController(ITestService testService)
    {
        _testService = testService;
    }

    [HttpGet("aop")]
    public IActionResult AopTest()
    {
        _testService.Test();
        return Ok("AOP 已生效");
    }
}

  访问
/test/aop 就能看到 自动日志 + 耗时统计。  


 

四、简单限流(2 种常用方案)

 

方案 1:固定窗口限流(固定时间窗口限流,此外还有滑动窗口和令牌桶等)

 

Program.cs

 

using AspNetCoreRateLimit;

var builder = WebApplication.CreateBuilder(args);
builder.Host.UseSerilog();

// 限流配置
builder.Services.AddInMemoryRateLimiting();
builder.Services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();

builder.Services.AddControllers();

var app = builder.Build();

// 启用限流
app.UseIpRateLimiting();

app.MapControllers();
app.Run();

 

添加限流规则(appsettings.json)

 

"IpRateLimiting": {
  "GeneralRules": [
    {
      "Endpoint": "*",
      "Period": "1m",
      "Limit": 10
    }
  ]
}

  表示:1 分钟内最多请求 10 次。  


 

方案 2:.NET 原生限流

 

Program.cs

 

var builder = WebApplication.CreateBuilder(args);
builder.Host.UseSerilog();

// 原生限流
builder.Services.AddRateLimiter(options =>
{
    // 固定窗口:每秒最多 2 个请求
    options.AddFixedWindowLimiter("fixed", opt =>
    {
        opt.Window = TimeSpan.FromSeconds(1);
        opt.PermitLimit = 2;
    });
});

builder.Services.AddControllers();
var app = builder.Build();

app.UseRateLimiter(); // 启用限流中间件
app.MapControllers();
app.Run();

 

控制器使用

 

[HttpGet("limit")]
[EnableRateLimiting("fixed")] // 启用限流
public IActionResult LimitTest()
{
    return Ok("限流测试");
}

 


 

五、三合一效果

  你访问接口时,会自动:  

  1. Serilog/NLog 记录日志(控制台 + 文件)
  2. AOP 拦截:记录方法执行、耗时、异常
  3. 限流保护:防止恶意刷接口

 


 

总结

 

  1. 日志:Serilog 最简单,NLog 更灵活,二选一即可
  2. AOP:Autofac 拦截器实现统一日志、异常、耗时管理
  3. 限流:推荐 .NET 7+ 原生限流,轻量无依赖
  4. 所有代码可直接复制运行,无需额外调整

文章摘自:https://www.cnblogs.com/chuansheng/p/19913713