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; namespace IRaCIS.Core.API { public static class SerilogConfig { public static void UseSerilogConfig(this IApplicationBuilder app, IWebHostEnvironment env) { app.UseMiddleware(); app.UseSerilogRequestLogging(opts => { opts.MessageTemplate = "{FullName} {UserType} {UserIp} {Host} {RequestMethod} {RequestPath} {RequestBody} 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?! if (request.QueryString.HasValue) { 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); #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 }; }); } } }