irc-netcore-api/IRaCIS.Core.API/_PipelineExtensions/Serilog/SerilogConfig.cs

125 lines
5.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using IRaCIS.Core.API._PipelineExtensions.Serilog;
using IRaCIS.Core.Domain.Share;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Serilog;
using System.Linq;
using UAParser;
namespace IRaCIS.Core.API
{
public static class SerilogConfig
{
public static void UseSerilogConfig(this IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseMiddleware<RequestResponseLoggingMiddleware>();
// 从 DI 容器中获取 Parser 实例
var uaParser = app.ApplicationServices.GetRequiredService<Parser>();
app.UseSerilogRequestLogging(opts
=>
{
opts.MessageTemplate = "{FullName} {UserType} {UserIp} {Host} {RequestMethod} {RequestPath}{QueryString} {RequestBody} {OS} {Browser} {DeviceType} responded {StatusCode} in {Elapsed:0.0000} ms";
opts.EnrichDiagnosticContext = (diagnosticContext, httpContext) =>
{
var request = httpContext.Request;
// Set all the common properties available for every request
diagnosticContext.Set("Host", request.Host.Value);
// Only set it if available. You're not sending sensitive data in a querystring right?!
diagnosticContext.Set("QueryString", request.QueryString.Value ?? "");
diagnosticContext.Set("FullName", httpContext?.User?.FindFirst(JwtIRaCISClaimType.FullName)?.Value);
diagnosticContext.Set("UserType", httpContext?.User?.FindFirst(JwtIRaCISClaimType.UserTypeShortName)?.Value);
var clientIp = httpContext.Request.Headers["X-Forwarded-For"].FirstOrDefault() ??
httpContext.Connection.RemoteIpAddress?.ToString();
if (clientIp.StartsWith("::ffff:"))
{
clientIp = clientIp.Substring(7); // 移除前缀
}
diagnosticContext.Set("UserIp", clientIp);
// ==================== 新增:解析 User-Agent ====================
try
{
var userAgent = httpContext.Request.Headers["User-Agent"].ToString();
if (!string.IsNullOrEmpty(userAgent))
{
var clientInfo = uaParser.Parse(userAgent);
diagnosticContext.Set("OS", clientInfo.OS.ToString());
diagnosticContext.Set("Browser", clientInfo.UA.ToString());
//diagnosticContext.Set("DeviceType", clientInfo.Device.ToString());
diagnosticContext.Set("DeviceType", userAgent.Contains("Mobile") ? "Mobile": "Desktop");
}
else
{
diagnosticContext.Set("OS", "Unknown");
diagnosticContext.Set("Browser", "Unknown");
diagnosticContext.Set("DeviceType", "Unknown");
}
}
catch (Exception ex)
{
// 解析失败时记录异常,但不要影响主流程
diagnosticContext.Set("OS", "ParseError");
diagnosticContext.Set("Browser", "ParseError");
diagnosticContext.Set("DeviceType", "ParseError");
}
// ==============================================================
#region 非必要不记录
//diagnosticContext.Set("Protocol", request.Protocol);
//diagnosticContext.Set("Scheme", request.Scheme);
//// Retrieve the IEndpointFeature selected for the request
//var endpoint = httpContext.GetEndpoint();
//if (endpoint is object) // endpoint != null
//{
// diagnosticContext.Set("EndpointName", endpoint.DisplayName);
//}
// Set the content-type of the Response at this point
//diagnosticContext.Set("ContentType", httpContext.Response.ContentType);
#endregion
#region old 未用
//这种获取的Ip不准 配置服务才行
//diagnosticContext.Set("RequestIP", httpContext.Connection.RemoteIpAddress.ToString());
//这种方式可以但是serilog提供了 就不用了
//diagnosticContext.Set("TestIP", httpContext.GetUserIp());
//这种方式不行 读取的body为空字符串 必须在中间件中读取
//diagnosticContext.Set("RequestBody", await ReadRequestBody(httpContext.Request));
//diagnosticContext.Set("RequestBody", RequestPayload);
#endregion
};
});
}
}
}