一、前端请求头的读取
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.官网
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();
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();
(未完待续...)