diff --git a/IRaCIS.Core.API/IRaCIS.Core.API.csproj b/IRaCIS.Core.API/IRaCIS.Core.API.csproj index c99703d40..b35be1db0 100644 --- a/IRaCIS.Core.API/IRaCIS.Core.API.csproj +++ b/IRaCIS.Core.API/IRaCIS.Core.API.csproj @@ -76,7 +76,6 @@ - diff --git a/IRaCIS.Core.API/_PipelineExtensions/Serilog/SerilogConfig.cs b/IRaCIS.Core.API/_PipelineExtensions/Serilog/SerilogConfig.cs index 217197d86..6492c25ae 100644 --- a/IRaCIS.Core.API/_PipelineExtensions/Serilog/SerilogConfig.cs +++ b/IRaCIS.Core.API/_PipelineExtensions/Serilog/SerilogConfig.cs @@ -4,6 +4,7 @@ using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Serilog; +using System.Linq; namespace IRaCIS.Core.API { @@ -20,7 +21,7 @@ namespace IRaCIS.Core.API => { - opts.MessageTemplate = "{TokenUserRealName} {TokenUserTypeShortName} {ClientIp} {LocalIP} {Host} {RequestMethod} {RequestPath} {RequestBody} responded {StatusCode} in {Elapsed:0.0000} ms"; + opts.MessageTemplate = "{FullName} {UserType} {UserIp} {Host} {RequestMethod} {RequestPath} {RequestBody} responded {StatusCode} in {Elapsed:0.0000} ms"; opts.EnrichDiagnosticContext = (diagnosticContext, httpContext) => { @@ -28,10 +29,8 @@ namespace IRaCIS.Core.API var request = httpContext.Request; // Set all the common properties available for every request - diagnosticContext.Set("Host", request.Host); + diagnosticContext.Set("Host", request.Host.Value); - //diagnosticContext.Set("Protocol", request.Protocol); - //diagnosticContext.Set("Scheme", request.Scheme); // Only set it if available. You're not sending sensitive data in a querystring right?! if (request.QueryString.HasValue) @@ -39,20 +38,34 @@ namespace IRaCIS.Core.API diagnosticContext.Set("QueryString", request.QueryString.Value); } - // Set the content-type of the Response at this point - diagnosticContext.Set("ContentType", httpContext.Response.ContentType); + diagnosticContext.Set("FullName", httpContext?.User?.FindFirst(JwtIRaCISClaimType.RealName)?.Value); - diagnosticContext.Set("TokenUserRealName", httpContext?.User?.FindFirst(JwtIRaCISClaimType.RealName)?.Value); + diagnosticContext.Set("UserType", httpContext?.User?.FindFirst(JwtIRaCISClaimType.UserTypeShortName)?.Value); - diagnosticContext.Set("TokenUserTypeShortName", httpContext?.User?.FindFirst(JwtIRaCISClaimType.UserTypeShortName)?.Value); + var clientIp = httpContext.Request.Headers["X-Forwarded-For"].FirstOrDefault() ?? + httpContext.Connection.RemoteIpAddress?.ToString(); - // Retrieve the IEndpointFeature selected for the request - var endpoint = httpContext.GetEndpoint(); - if (endpoint is object) // endpoint != null + if (clientIp.StartsWith("::ffff:")) { - diagnosticContext.Set("EndpointName", endpoint.DisplayName); + 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()); diff --git a/IRaCIS.Core.API/_ServiceExtensions/Serilog/EnricherExtensions.cs b/IRaCIS.Core.API/_ServiceExtensions/Serilog/EnricherExtensions.cs deleted file mode 100644 index a6f10b4eb..000000000 --- a/IRaCIS.Core.API/_ServiceExtensions/Serilog/EnricherExtensions.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Microsoft.AspNetCore.Http; -using Serilog; -using Serilog.Configuration; -using Serilog.Core; -using Serilog.Events; -using System; - -namespace IRaCIS.Core.API -{ - public static class EnricherExtensions - { - public static LoggerConfiguration WithHttpContextInfo(this LoggerEnrichmentConfiguration enrich, IServiceProvider serviceProvider) - { - if (enrich == null) - throw new ArgumentNullException(nameof(enrich)); - - return enrich.With(new HttpContextEnricher(serviceProvider)); - } - public static LoggerConfiguration WithHttpContextInfo(this LoggerEnrichmentConfiguration enrich, IServiceProvider serviceProvider, Action enrichAction) - { - if (enrich == null) - throw new ArgumentNullException(nameof(enrich)); - - return enrich.With(new HttpContextEnricher(serviceProvider, enrichAction)); - } - - } - -} diff --git a/IRaCIS.Core.API/_ServiceExtensions/Serilog/HttpContextEnricher.cs b/IRaCIS.Core.API/_ServiceExtensions/Serilog/HttpContextEnricher.cs deleted file mode 100644 index 2f67772d4..000000000 --- a/IRaCIS.Core.API/_ServiceExtensions/Serilog/HttpContextEnricher.cs +++ /dev/null @@ -1,86 +0,0 @@ -using IRaCIS.Core.Domain.Share; -using Microsoft.AspNetCore.Http; -using Microsoft.Extensions.DependencyInjection; -using Serilog.Core; -using Serilog.Events; -using System; -using System.IO; -using System.Threading.Tasks; - -namespace IRaCIS.Core.API -{ - public class HttpContextEnricher : ILogEventEnricher - { - private readonly IServiceProvider _serviceProvider; - private readonly Action _enrichAction; - - public HttpContextEnricher(IServiceProvider serviceProvider) : this(serviceProvider, null) - { } - - public HttpContextEnricher(IServiceProvider serviceProvider, Action enrichAction) - { - _serviceProvider = serviceProvider; - if (enrichAction == null) - { - _enrichAction = (logEvent, propertyFactory, httpContext) => - { - logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("RequestIP", httpContext.Connection.RemoteIpAddress.ToString())); - - logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("LocalIP", httpContext.Connection.LocalIpAddress.MapToIPv4().ToString())); - - logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("TokenUserRealName", httpContext?.User?.FindFirst(ClaimAttributes.RealName)?.Value)); - logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("TokenUserType", httpContext?.User?.FindFirst(JwtIRaCISClaimType.UserTypeShortName)?.Value)); - - - //这样读取没用 - //logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("RequestBody", await ReadRequestBody(httpContext.Request))); - //logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("RequestIP", IPHelper.GetIP(httpContext.Request) )); - //logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("Referer", httpContext.Request.Headers["Referer"].ToString())); - //logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("request_path", httpContext.Request.Path)); - //logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("request_method", httpContext.Request.Method)); - //if (httpContext.Response.HasStarted) - //{ - // logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("response_status", httpContext.Response.StatusCode)); - //} - }; - } - else - { - _enrichAction = enrichAction; - } - } - - - public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory) - { - var httpContext = _serviceProvider.GetService()?.HttpContext; - if (null != httpContext) - { - _enrichAction.Invoke(logEvent, propertyFactory, httpContext); - } - } - - private async Task ReadRequestBody(HttpRequest request) - { - // Ensure the request's body can be read multiple times (for the next middlewares in the pipeline). - request.EnableBuffering(); - - using var streamReader = new StreamReader(request.Body, leaveOpen: true); - var requestBody = await streamReader.ReadToEndAsync(); - - // Reset the request's body stream position for next middleware in the pipeline. - request.Body.Position = 0; - return requestBody == null ? String.Empty : requestBody.Trim(); - } - - private async Task ReadResponseBody(HttpResponse response) - { - response.Body.Seek(0, SeekOrigin.Begin); - string responseBody = await new StreamReader(response.Body).ReadToEndAsync(); - response.Body.Seek(0, SeekOrigin.Begin); - - return $"{responseBody}"; - } - } - -} diff --git a/IRaCIS.Core.API/_ServiceExtensions/Serilog/SerilogSetup.cs b/IRaCIS.Core.API/_ServiceExtensions/SerilogSetup.cs similarity index 69% rename from IRaCIS.Core.API/_ServiceExtensions/Serilog/SerilogSetup.cs rename to IRaCIS.Core.API/_ServiceExtensions/SerilogSetup.cs index d78546dfa..7622f1c24 100644 --- a/IRaCIS.Core.API/_ServiceExtensions/Serilog/SerilogSetup.cs +++ b/IRaCIS.Core.API/_ServiceExtensions/SerilogSetup.cs @@ -19,30 +19,28 @@ namespace IRaCIS.Core.API // Filter out ASP.NET Core infrastructre logs that are Information and below 日志太多了 一个请求 记录好几条 .MinimumLevel.Override("Microsoft.AspNetCore", LogEventLevel.Warning) .MinimumLevel.Override("Microsoft.AspNetCore.Hosting", LogEventLevel.Warning) - .MinimumLevel.Override("Microsoft.AspNetCore.Mvc", LogEventLevel.Warning) - .MinimumLevel.Override("Microsoft.AspNetCore.Routing", LogEventLevel.Warning) - + .MinimumLevel.Override("Microsoft.AspNetCore.Mvc", LogEventLevel.Warning) + .MinimumLevel.Override("Microsoft.AspNetCore.Routing", LogEventLevel.Warning) .MinimumLevel.Override("Hangfire", LogEventLevel.Warning) - .Enrich.WithClientIp() - .Enrich.WithRequestHeader("User-Agent") + //如果有反向代理并不会获取到用户的真实IP + //.Enrich.WithClientIp() + //.Enrich.WithRequestHeader("User-Agent") .Enrich.FromLogContext() .Filter.ByExcluding(logEvent => logEvent.Properties.ContainsKey("RequestPath") && logEvent.Properties["RequestPath"].ToString().Contains("/health")) //https://github.com/serilog/serilog-formatting-compact // 控制台输出 JSON 格式 - .WriteTo.Console(restrictedToMinimumLevel: LogEventLevel.Warning, - - formatter: new CompactJsonFormatter()) + .WriteTo.Console(formatter: new CompactJsonFormatter(),LogEventLevel.Warning) // 文件输出 JSON 格式 - .WriteTo.File(new CompactJsonFormatter(),$"{AppContext.BaseDirectory}Serilogs/.json", rollingInterval: RollingInterval.Day); + .WriteTo.File(new CompactJsonFormatter(), $"{AppContext.BaseDirectory}Serilogs/.json", rollingInterval: RollingInterval.Day); - ////控制台 方便调试 问题 我们显示记录日志 时 获取上下文的ip 和用户名 用户类型 - //.WriteTo.Console(restrictedToMinimumLevel: LogEventLevel.Warning, - // outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {ClientIp} {SourceContext:l} || {Message} || {Exception} ||end {NewLine}") + ////控制台 方便调试 问题 我们显示记录日志 时 获取上下文的ip 和用户名 用户类型 + //.WriteTo.Console(restrictedToMinimumLevel: LogEventLevel.Warning, + // outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {ClientIp} {SourceContext:l} || {Message} || {Exception} ||end {NewLine}") - //.WriteTo.File($"{AppContext.BaseDirectory}Serilogs/.log", rollingInterval: RollingInterval.Day, - // outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {ClientIp} {SourceContext:l} || {Message} || {Exception} ||end {NewLine}"); + //.WriteTo.File($"{AppContext.BaseDirectory}Serilogs/.log", rollingInterval: RollingInterval.Day, + // outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {ClientIp} {SourceContext:l} || {Message} || {Exception} ||end {NewLine}"); Log.Logger = config.CreateLogger();