Web开发:ABP框架7——前端请求头的读取 Serilog日志配置
一、前端请求头的读取
1.注入
高层代码使用注入,IHttpContextAccessor 是 ASP.NET Core 中的一个接口,用于在服务层中获取与当前 HTTP 请求相关的信息,比如请求的头部、Cookie、用户身份等。
private readonly IHttpContextAccessor _httpContextAccessor;
2.使用
var requestheaders = _httpContextAccessor.HttpContext.Request.Headers;
var curSyscode = requestheaders["SysCode"].ToString();//假设前端请求头里面有一个key='SysCode'的参数
二、日志的配置(Serilog)
1.官网
Serilog — 具有完全结构化事件的简单 .NET 日志记录
2.Program配置
// Program 类是应用程序的入口点,包含 Main 函数
public class Program
{// Main 函数是应用程序的启动方法public static int Main(string[] args){// 创建一个 ConfigurationBuilder 实例,读取当前目录下的配置文件var serilogConfig = new ConfigurationBuilder()// 设置基路径为当前目录.SetBasePath(Directory.GetCurrentDirectory())// 加载名为 "serilog.json" 的配置文件.AddJsonFile("serilog.json")// 构建配置对象.Build();// 使用 Serilog 配置来创建一个日志记录器Log.Logger = new LoggerConfiguration()// 通过配置对象加载配置(serilogConfig).ReadFrom.Configuration(serilogConfig)// 如果是调试模式,设置日志的最低日志级别为 Debug#if DEBUG.MinimumLevel.Debug()#else// 否则,设置最低日志级别为 Information.MinimumLevel.Information()#endif// 添加上下文信息以增强日志(例如线程ID、机器名等).Enrich.FromLogContext()// 如果是调试模式,使用异步的 Console 输出日志#if DEBUG.WriteTo.Async(c => c.Console())#endif// 创建日志记录器.CreateLogger();try{// 记录一条启动日志Log.Information("Starting...");// 创建并启动 Web 主机CreateHostBuilder(args).Build().Run();// 如果主机启动成功,返回 0(表示无错误)return 0;}catch (Exception ex){// 如果出现异常,记录致命错误日志Log.Fatal(ex, "Host terminated unexpectedly!");// 返回 1 表示程序异常退出return 1;}finally{// 确保在应用程序结束时,关闭并刷新日志Log.CloseAndFlush();}}// 创建 Web 主机构建器的方法internal static IHostBuilder CreateHostBuilder(string[] args) =>// 使用默认的主机构建器Host.CreateDefaultBuilder(args)// 配置 Web 主机,指定启动类(Startup)来配置服务和中间件.ConfigureWebHostDefaults(webBuilder =>{// 设置 Startup 类来配置应用程序webBuilder.UseStartup<Startup>();})// 使用 Autofac 作为依赖注入容器(如果你使用 Autofac 进行依赖注入).UseAutofac()// 配置使用 Serilog 作为日志提供程序.UseSerilog();
}
3.serilog.json输出内容配置
{"Serilog": {"Using": ["Serilog.Sinks.Console", "Serilog.Sinks.File"],//配置这两个库,需要Nuget安装"MinimumLevel": {"Default": "Information",//最低日志级别,记录>=Information的日志(Verbose Debug Information Warning Error Fatal)"Override": {"Microsoft": "Warning",//所有 Microsoft 命名空间中的日志,最小日志级别为 Warning。这意味着只会记录 Warning、Error 和 Fatal 级别的日志,忽略 Information、Debug"System": "Error" ,//所有 System 命名空间中的日志,最小日志级别为 Error。只有 Error 和 Fatal 级别的日志会被记录,Information、Warning、Debug 会被忽略。"Microsoft.EntityFrameworkCore": "Warning"//同上}},"WriteTo": [{"Name": "Console",//写到控制台"Args": {"outputTemplate": "{Timestamp:HH:mm:ss} [{Level}] {Message}{NewLine}{Exception}"}},{"Name": "File",//写到文件"Args": {"path": "Logs/log-.txt",//日志文件的路径。log-.txt 中的 - 会自动被替换为日志文件的日期,生成按天滚动的日志文件(例如 log-2024-11-27.txt)"rollingInterval": "Day",//日志的滚动周期为每天"retainedFileCountLimit": 30,//限制保留的日志文件数量为 30 个。超过此数量时,最旧的日志文件会被自动删除。"outputTemplate": "{Timestamp:HH:mm:ss} [{Level}] {Message}{NewLine}{Exception}"}}],"Enrich": ["FromLogContext",//将上下文信息(如请求 ID、用户信息等)自动添加到日志中。这个信息通常由程序运行时的上下文提供。"WithMachineName",//将机器名称添加到日志中,帮助标识日志是由哪台机器生成的(对于分布式应用很有帮助)。"WithThreadId"//将当前线程 ID 添加到日志中,帮助追踪多线程应用中的日志信息。]}
}
上面的路径配置也可以这样写:
// 创建 Serilog Logger
Log.Logger = new LoggerConfiguration()// 读取 serilog.json 配置.ReadFrom.Configuration(configuration)// 配置不同级别的日志输出.WriteTo.Logger(lc => lc.Filter.ByIncludingOnly(evt => evt.Level == LogEventLevel.Debug).WriteTo.RollingFile("Logs\\Debug\\{Date}.log", rollingInterval: RollingInterval.Day)).WriteTo.Logger(lc => lc.Filter.ByIncludingOnly(evt => evt.Level == LogEventLevel.Information).WriteTo.RollingFile("Logs\\Information\\{Date}.log", rollingInterval: RollingInterval.Day)).WriteTo.Logger(lc => lc.Filter.ByIncludingOnly(evt => evt.Level == LogEventLevel.Warning).WriteTo.RollingFile("Logs\\Warning\\{Date}.log", rollingInterval: RollingInterval.Day)).WriteTo.Logger(lc => lc.Filter.ByIncludingOnly(evt => evt.Level == LogEventLevel.Fatal).WriteTo.RollingFile("Logs\\Fatal\\{Date}.log", rollingInterval: RollingInterval.Day)).CreateLogger();
使用 Serilog 时,配置是合并的,不会覆盖之前的设置,即配置了serilog.json后,同样可以配置Log.Logger的设置。
4.看不到日志
(1)级别过滤
例如你把日志最低显示级别设置为Error,自然看不到Info的日志,可去Serilog.json或者HttpApi.Host下的Progarm.cs调整最低显示级别,例如调成Info。
(2)异步写入
Serilog 默认采用 异步方式 处理日志输出,日志记录可能会先被缓存,并异步写入目标,当你调用 Log.Information(...) 时,日志可能并不会立即写入,而是被暂时缓存在内存中,稍后再写。
这种延迟一般是为了提高性能,避免因为日志记录的 I/O 操作阻塞应用程序的主线程。如果想日志更及时地显示,可以禁用异步处理,但是及其不推荐。
(3)日志写入频率过高
日志积压,从而出现延迟,建议等待五分钟后查看。
(4)未强制刷新日志
在程序结束时调用 Log.CloseAndFlush(),以确保所有日志被正确写入。(如果已配置,开发环境重启VS2022即可强制刷新日志)
当然也可以设置刷新时间:比如在HttpApi.Host下的Progarm.cs,设置flushToDiskInterval
下面给出了两个解决方案的代码片段:
var configuration = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json").Build();Log.Logger = new LoggerConfiguration().ReadFrom.Configuration(configuration) // 从配置文件加载.WriteTo.File("logs/log.txt", rollingInterval: RollingInterval.Day, flushToDiskInterval: TimeSpan.FromMinutes(30)) // 每30分钟强制刷新一次.CreateLogger();// 其他代码...Log.CloseAndFlush();
(未完待续...)