From f7e47293dddd2c108cf51e72fb411e86166de3fb Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Mon, 21 Oct 2024 15:39:57 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E4=BF=AE=E6=94=B9serilog?= =?UTF-8?q?=20=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/IRaCIS.Core.API.xml | 7 +-- IRaCIS.Core.API/Progranm.cs | 3 +- .../Serilog/SerilogConfig.cs | 48 +++++++++++++++- .../Serilog/SerilogHelper.cs | 56 ------------------- .../Serilog/SerilogSetup.cs | 15 +++-- 5 files changed, 62 insertions(+), 67 deletions(-) delete mode 100644 IRaCIS.Core.API/_PipelineExtensions/Serilog/SerilogHelper.cs diff --git a/IRaCIS.Core.API/IRaCIS.Core.API.xml b/IRaCIS.Core.API/IRaCIS.Core.API.xml index 216f82c9a..4b4186d94 100644 --- a/IRaCIS.Core.API/IRaCIS.Core.API.xml +++ b/IRaCIS.Core.API/IRaCIS.Core.API.xml @@ -340,13 +340,10 @@ 序列化,反序列化的时候,处理时间 时区转换 - + - 创建属性 + LowerCamelCaseJsonAttribute 可以设置类小写返回给前端 - 类型 - 序列化成员 - diff --git a/IRaCIS.Core.API/Progranm.cs b/IRaCIS.Core.API/Progranm.cs index 419c98313..0863231cd 100644 --- a/IRaCIS.Core.API/Progranm.cs +++ b/IRaCIS.Core.API/Progranm.cs @@ -80,6 +80,7 @@ builder.Services.AddExceptionHandler(); //健康检查 builder.Services.AddHealthChecks(); +builder.Services.AddSerilog(); //本地化 builder.Services.AddJsonLocalization(options => options.ResourcesPath = "Resources"); @@ -197,7 +198,7 @@ app.UseExceptionHandler(o => { }); app.UseIRacisHostStaticFileStore(env); //本地化 - await app.UseLocalization(app.Services); +await app.UseLocalization(app.Services); app.UseForwardedHeaders(); diff --git a/IRaCIS.Core.API/_PipelineExtensions/Serilog/SerilogConfig.cs b/IRaCIS.Core.API/_PipelineExtensions/Serilog/SerilogConfig.cs index e4f418057..79496bf3e 100644 --- a/IRaCIS.Core.API/_PipelineExtensions/Serilog/SerilogConfig.cs +++ b/IRaCIS.Core.API/_PipelineExtensions/Serilog/SerilogConfig.cs @@ -1,6 +1,8 @@ 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; namespace IRaCIS.Core.API @@ -17,8 +19,52 @@ namespace IRaCIS.Core.API app.UseSerilogRequestLogging(opts => { + opts.MessageTemplate = "{TokenUserRealName} {TokenUserTypeShortName} {ClientIp} {LocalIP} {Host} {Protocol} {RequestMethod} {RequestPath} {RequestBody} responded {StatusCode} in {Elapsed:0.0000} ms"; - opts.EnrichDiagnosticContext = SerilogHelper.EnrichFromRequest; + + opts.EnrichDiagnosticContext = (diagnosticContext, httpContext) => + { + + var request = httpContext.Request; + + // Set all the common properties available for every request + diagnosticContext.Set("Host", request.Host); + + diagnosticContext.Set("Protocol", request.Protocol); + diagnosticContext.Set("Scheme", request.Scheme); + + #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 + + // 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); + } + + // Set the content-type of the Response at this point + diagnosticContext.Set("ContentType", httpContext.Response.ContentType); + + diagnosticContext.Set("TokenUserRealName", httpContext?.User?.FindFirst(JwtIRaCISClaimType.RealName)?.Value); + + diagnosticContext.Set("TokenUserTypeShortName", httpContext?.User?.FindFirst(JwtIRaCISClaimType.UserTypeShortName)?.Value); + + // Retrieve the IEndpointFeature selected for the request + var endpoint = httpContext.GetEndpoint(); + if (endpoint is object) // endpoint != null + { + diagnosticContext.Set("EndpointName", endpoint.DisplayName); + } + }; }); diff --git a/IRaCIS.Core.API/_PipelineExtensions/Serilog/SerilogHelper.cs b/IRaCIS.Core.API/_PipelineExtensions/Serilog/SerilogHelper.cs deleted file mode 100644 index 7df3c4267..000000000 --- a/IRaCIS.Core.API/_PipelineExtensions/Serilog/SerilogHelper.cs +++ /dev/null @@ -1,56 +0,0 @@ -using IRaCIS.Core.Domain.Share; -using Microsoft.AspNetCore.Http; -using Serilog; - -namespace IRaCIS.Core.API -{ - public class SerilogHelper - { - //public static string RequestPayload = ""; - - public static void EnrichFromRequest(IDiagnosticContext diagnosticContext, HttpContext httpContext) - { - var request = httpContext.Request; - - // Set all the common properties available for every request - diagnosticContext.Set("Host", request.Host); - - diagnosticContext.Set("Protocol", request.Protocol); - diagnosticContext.Set("Scheme", request.Scheme); - - #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 - - // 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); - } - - // Set the content-type of the Response at this point - diagnosticContext.Set("ContentType", httpContext.Response.ContentType); - - diagnosticContext.Set("TokenUserRealName", httpContext?.User?.FindFirst(JwtIRaCISClaimType.RealName)?.Value); - - diagnosticContext.Set("TokenUserTypeShortName", httpContext?.User?.FindFirst(JwtIRaCISClaimType.UserTypeShortName)?.Value); - - // Retrieve the IEndpointFeature selected for the request - var endpoint = httpContext.GetEndpoint(); - if (endpoint is object) // endpoint != null - { - diagnosticContext.Set("EndpointName", endpoint.DisplayName); - } - } - - - } -} diff --git a/IRaCIS.Core.API/_ServiceExtensions/Serilog/SerilogSetup.cs b/IRaCIS.Core.API/_ServiceExtensions/Serilog/SerilogSetup.cs index b7576f849..df89d5457 100644 --- a/IRaCIS.Core.API/_ServiceExtensions/Serilog/SerilogSetup.cs +++ b/IRaCIS.Core.API/_ServiceExtensions/Serilog/SerilogSetup.cs @@ -16,18 +16,25 @@ namespace IRaCIS.Core.API .MinimumLevel.Override("Microsoft", LogEventLevel.Information) // 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("Hangfire", LogEventLevel.Warning) - .MinimumLevel.Override("System.Net.Http.HttpClient.HttpReports", LogEventLevel.Warning) .Enrich.WithClientIp() + .Enrich.WithRequestHeader("User-Agent") .Enrich.FromLogContext() .Filter.ByExcluding(logEvent => logEvent.Properties.ContainsKey("RequestPath") && logEvent.Properties["RequestPath"].ToString().Contains("/health")) //控制台 方便调试 问题 我们显示记录日志 时 获取上下文的ip 和用户名 用户类型 .WriteTo.Console(restrictedToMinimumLevel: LogEventLevel.Warning, - outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {SourceContext:l} || {Message} || {Exception} ||end {NewLine}") + 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}] {SourceContext:l} || {Message} || {Exception} ||end {NewLine}"); + outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {ClientIp} {SourceContext:l} || {Message} || {Exception} ||end {NewLine}"); + + + Log.Logger = config.CreateLogger(); //.WriteTo.MSSqlServer("Data Source=DESKTOP-4TU9A6M;Initial Catalog=CoreFrame;User ID=sa;Password=123456", "logs", autoCreateSqlTable: true, restrictedToMinimumLevel: LogEventLevel.Information)//从左至右四个参数分别是数据库连接字符串、表名、如果表不存在是否创建、最低等级。Serilog会默认创建一些列。 @@ -46,7 +53,7 @@ namespace IRaCIS.Core.API //} //扩展方法 获取上下文的ip 用户名 用户类型 - Log.Logger = config.Enrich.WithHttpContextInfo(serviceProvider).CreateLogger(); + //Log.Logger = config.Enrich.WithHttpContextInfo(serviceProvider).CreateLogger(); } } From de0b95a22bd2de91401fb6f18131acd99d311273 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Mon, 21 Oct 2024 16:19:14 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E4=BF=AE=E6=94=B9json=20=E6=97=A5=E5=BF=97?= =?UTF-8?q?=E5=B1=95=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/IRaCIS.Core.API.csproj | 1 + .../Serilog/SerilogSetup.cs | 20 ++++++++++++++----- .../IRaCIS.Core.Application.xml | 10 ++++++++++ 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/IRaCIS.Core.API/IRaCIS.Core.API.csproj b/IRaCIS.Core.API/IRaCIS.Core.API.csproj index 34d17bbd7..c99703d40 100644 --- a/IRaCIS.Core.API/IRaCIS.Core.API.csproj +++ b/IRaCIS.Core.API/IRaCIS.Core.API.csproj @@ -77,6 +77,7 @@ + diff --git a/IRaCIS.Core.API/_ServiceExtensions/Serilog/SerilogSetup.cs b/IRaCIS.Core.API/_ServiceExtensions/Serilog/SerilogSetup.cs index df89d5457..848de4d7d 100644 --- a/IRaCIS.Core.API/_ServiceExtensions/Serilog/SerilogSetup.cs +++ b/IRaCIS.Core.API/_ServiceExtensions/Serilog/SerilogSetup.cs @@ -1,5 +1,7 @@ using Serilog; using Serilog.Events; +using Serilog.Formatting.Compact; + //using Serilog.Sinks.Email; using System; @@ -26,12 +28,20 @@ namespace IRaCIS.Core.API .Enrich.FromLogContext() .Filter.ByExcluding(logEvent => logEvent.Properties.ContainsKey("RequestPath") && logEvent.Properties["RequestPath"].ToString().Contains("/health")) - //控制台 方便调试 问题 我们显示记录日志 时 获取上下文的ip 和用户名 用户类型 - .WriteTo.Console(restrictedToMinimumLevel: LogEventLevel.Warning, - outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {ClientIp} {SourceContext:l} || {Message} || {Exception} ||end {NewLine}") + //https://github.com/serilog/serilog-formatting-compact + // 控制台输出 JSON 格式 + .WriteTo.Console(restrictedToMinimumLevel: LogEventLevel.Warning, + formatter: new CompactJsonFormatter()) - .WriteTo.File($"{AppContext.BaseDirectory}Serilogs/.log", rollingInterval: RollingInterval.Day, - outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {ClientIp} {SourceContext:l} || {Message} || {Exception} ||end {NewLine}"); + // 文件输出 JSON 格式 + .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}") + + //.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(); diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index d37814e29..596cba3fe 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -16806,6 +16806,16 @@ 入组 Selection 列表查询参数 + + + 工作兼职 + + + + + 工作兼职En + + 工作兼职 From 922e61a6369be269fe94e13709750fb9cd5b98cb Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Mon, 21 Oct 2024 17:06:01 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E4=BF=AE=E6=94=B9scp=20=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=BC=A9=E7=95=A5=E5=9B=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRC.Core.SCP/Service/CStoreSCPService.cs | 2 +- IRC.Core.SCP/Service/DicomArchiveService.cs | 8 ++--- .../Serilog/SerilogConfig.cs | 32 ++++++++++--------- .../Serilog/SerilogSetup.cs | 1 + 4 files changed, 23 insertions(+), 20 deletions(-) diff --git a/IRC.Core.SCP/Service/CStoreSCPService.cs b/IRC.Core.SCP/Service/CStoreSCPService.cs index fe1f91e00..1f2dae205 100644 --- a/IRC.Core.SCP/Service/CStoreSCPService.cs +++ b/IRC.Core.SCP/Service/CStoreSCPService.cs @@ -315,7 +315,7 @@ namespace IRaCIS.Core.SCP.Service _SCPStudyIdList.Add(scpStudyId); } - var series = await _seriesRepository.FindAsync(seriesId); + var series = await _seriesRepository.FirstOrDefaultAsync(t => t.Id == seriesId); //没有缩略图 if (series != null && string.IsNullOrEmpty(series.ImageResizePath)) diff --git a/IRC.Core.SCP/Service/DicomArchiveService.cs b/IRC.Core.SCP/Service/DicomArchiveService.cs index ac0edd173..e522f6690 100644 --- a/IRC.Core.SCP/Service/DicomArchiveService.cs +++ b/IRC.Core.SCP/Service/DicomArchiveService.cs @@ -75,9 +75,9 @@ namespace IRaCIS.Core.SCP.Service //using (@lock.Acquire()) { var findPatient = await _patientRepository.FirstOrDefaultAsync(t => t.PatientIdStr == patientIdStr && t.TrialSiteId==trialSiteId ); - var findStudy = await _studyRepository.FindAsync(studyId); - var findSerice = await _seriesRepository.FindAsync(seriesId); - var findInstance = await _instanceRepository.FindAsync(instanceId); + var findStudy = await _studyRepository.FirstOrDefaultAsync(t=>t.Id== studyId); + var findSerice = await _seriesRepository.FirstOrDefaultAsync(t => t.Id == seriesId); + var findInstance = await _instanceRepository.FirstOrDefaultAsync(t => t.Id == instanceId); DateTime? studyTime = dataset.GetSingleValueOrDefault(DicomTag.StudyDate, string.Empty) == string.Empty ? null : dataset.GetSingleValue(DicomTag.StudyDate).Add(dataset.GetSingleValueOrDefault(DicomTag.StudyTime, string.Empty) == string.Empty ? TimeSpan.Zero : dataset.GetSingleValue(DicomTag.StudyTime).TimeOfDay); @@ -307,7 +307,7 @@ namespace IRaCIS.Core.SCP.Service await _instanceRepository.BatchUpdateNoTrackingAsync(t => t.Id == instanceId, u => new SCPInstance() { Path = fileRelativePath,FileSize=fileSize }); } - //await _studyRepository.SaveChangesAsync(); + await _studyRepository.SaveChangesAsync(); return findStudy.Id; } diff --git a/IRaCIS.Core.API/_PipelineExtensions/Serilog/SerilogConfig.cs b/IRaCIS.Core.API/_PipelineExtensions/Serilog/SerilogConfig.cs index 79496bf3e..217197d86 100644 --- a/IRaCIS.Core.API/_PipelineExtensions/Serilog/SerilogConfig.cs +++ b/IRaCIS.Core.API/_PipelineExtensions/Serilog/SerilogConfig.cs @@ -20,7 +20,7 @@ namespace IRaCIS.Core.API => { - opts.MessageTemplate = "{TokenUserRealName} {TokenUserTypeShortName} {ClientIp} {LocalIP} {Host} {Protocol} {RequestMethod} {RequestPath} {RequestBody} responded {StatusCode} in {Elapsed:0.0000} ms"; + opts.MessageTemplate = "{TokenUserRealName} {TokenUserTypeShortName} {ClientIp} {LocalIP} {Host} {RequestMethod} {RequestPath} {RequestBody} responded {StatusCode} in {Elapsed:0.0000} ms"; opts.EnrichDiagnosticContext = (diagnosticContext, httpContext) => { @@ -30,20 +30,8 @@ namespace IRaCIS.Core.API // Set all the common properties available for every request diagnosticContext.Set("Host", request.Host); - diagnosticContext.Set("Protocol", request.Protocol); - diagnosticContext.Set("Scheme", request.Scheme); - - #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 + //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) @@ -64,6 +52,20 @@ namespace IRaCIS.Core.API { diagnosticContext.Set("EndpointName", endpoint.DisplayName); } + + #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 + + }; }); diff --git a/IRaCIS.Core.API/_ServiceExtensions/Serilog/SerilogSetup.cs b/IRaCIS.Core.API/_ServiceExtensions/Serilog/SerilogSetup.cs index 848de4d7d..d78546dfa 100644 --- a/IRaCIS.Core.API/_ServiceExtensions/Serilog/SerilogSetup.cs +++ b/IRaCIS.Core.API/_ServiceExtensions/Serilog/SerilogSetup.cs @@ -31,6 +31,7 @@ namespace IRaCIS.Core.API //https://github.com/serilog/serilog-formatting-compact // 控制台输出 JSON 格式 .WriteTo.Console(restrictedToMinimumLevel: LogEventLevel.Warning, + formatter: new CompactJsonFormatter()) // 文件输出 JSON 格式 From 48ff2a347e1ded513745b8627c1fa6272711ec13 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Mon, 21 Oct 2024 17:27:20 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=97=A5=E5=BF=97?= =?UTF-8?q?=E8=AE=B0=E5=BD=95=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/IRaCIS.Core.API.csproj | 1 - .../Serilog/SerilogConfig.cs | 37 +++++--- .../Serilog/EnricherExtensions.cs | 29 ------- .../Serilog/HttpContextEnricher.cs | 86 ------------------- .../{Serilog => }/SerilogSetup.cs | 26 +++--- 5 files changed, 37 insertions(+), 142 deletions(-) delete mode 100644 IRaCIS.Core.API/_ServiceExtensions/Serilog/EnricherExtensions.cs delete mode 100644 IRaCIS.Core.API/_ServiceExtensions/Serilog/HttpContextEnricher.cs rename IRaCIS.Core.API/_ServiceExtensions/{Serilog => }/SerilogSetup.cs (69%) 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();