From dd68d305582c9f8f368e3e0fcc6410daa9335df4 Mon Sep 17 00:00:00 2001 From: colin Date: Tue, 13 Jan 2026 15:01:49 +0800 Subject: [PATCH] feat(auditlog): Optimize the index of audit logs --- .../AbpAuditLoggingElasticsearchOptions.cs | 41 ++++++- .../ElasticsearchAuditLogManager.cs | 52 +++++++- .../ElasticsearchSecurityLogManager.cs | 27 +++- .../Elasticsearch/IndexInitializer.cs | 116 +++++++++--------- .../LINGYUN/Abp/AuditLogging/EntityChange.cs | 2 + .../AuditLogging/EntityChangeTypeConverter.cs | 31 +++++ .../SerilogElasticsearchLoggingManager.cs | 40 +++--- 7 files changed, 232 insertions(+), 77 deletions(-) create mode 100644 aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/EntityChangeTypeConverter.cs diff --git a/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/AbpAuditLoggingElasticsearchOptions.cs b/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/AbpAuditLoggingElasticsearchOptions.cs index 6d54ccd6b..371638b74 100644 --- a/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/AbpAuditLoggingElasticsearchOptions.cs +++ b/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/AbpAuditLoggingElasticsearchOptions.cs @@ -6,11 +6,48 @@ public class AbpAuditLoggingElasticsearchOptions { public const string DefaultIndexPrefix = "auditlogging"; public string IndexPrefix { get; set; } - public IndexSettings IndexSettings { get; set; } + /// + /// 是否启用审计日志记录 + /// + public bool IsAuditLogEnabled { get; set; } + /// + /// 审计日志索引设置 + /// + public IndexSettings AuditLogSettings { get; set; } + /// + /// 是否启用安全日志记录 + /// + public bool IsSecurityLogEnabled { get; set; } + /// + /// 安全日志索引设置 + /// + public IndexSettings SecurityLogSettings { get; set; } public AbpAuditLoggingElasticsearchOptions() { IndexPrefix = DefaultIndexPrefix; - IndexSettings = new IndexSettings(); + IsAuditLogEnabled = true; + AuditLogSettings = new IndexSettings() + { + NumberOfReplicas = 1, + NumberOfShards = 3, + Mapping = new MappingLimitSettings + { + TotalFields = new MappingLimitSettingsTotalFields + { + Limit = 1000, + }, + NestedFields = new MappingLimitSettingsNestedFields + { + Limit = 50, + }, + Depth = new MappingLimitSettingsDepth + { + Limit = 10, + }, + } + }; + IsSecurityLogEnabled = true; + SecurityLogSettings = new IndexSettings(); } } diff --git a/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/ElasticsearchAuditLogManager.cs b/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/ElasticsearchAuditLogManager.cs index 2c7a8cd25..f3276e0cb 100644 --- a/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/ElasticsearchAuditLogManager.cs +++ b/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/ElasticsearchAuditLogManager.cs @@ -8,8 +8,10 @@ using System; using System.Collections.Generic; using System.Linq; using System.Net; +using System.Text; using System.Threading; using System.Threading.Tasks; +using Volo.Abp; using Volo.Abp.Auditing; using Volo.Abp.DependencyInjection; using Volo.Abp.Timing; @@ -21,6 +23,7 @@ public class ElasticsearchAuditLogManager : IAuditLogManager, ITransientDependen { private readonly AbpAuditingOptions _auditingOptions; private readonly AbpElasticsearchOptions _elasticsearchOptions; + private readonly AbpAuditLoggingElasticsearchOptions _loggingEsOptions; private readonly IIndexNameNormalizer _indexNameNormalizer; private readonly IElasticsearchClientFactory _clientFactory; private readonly IAuditLogInfoToAuditLogConverter _converter; @@ -34,7 +37,8 @@ public class ElasticsearchAuditLogManager : IAuditLogManager, ITransientDependen IOptions elasticsearchOptions, IElasticsearchClientFactory clientFactory, IOptions auditingOptions, - IAuditLogInfoToAuditLogConverter converter) + IAuditLogInfoToAuditLogConverter converter, + IOptionsMonitor loggingEsOptions) { _clock = clock; _converter = converter; @@ -42,6 +46,7 @@ public class ElasticsearchAuditLogManager : IAuditLogManager, ITransientDependen _auditingOptions = auditingOptions.Value; _elasticsearchOptions = elasticsearchOptions.Value; _indexNameNormalizer = indexNameNormalizer; + _loggingEsOptions = loggingEsOptions.CurrentValue; Logger = NullLogger.Instance; } @@ -175,7 +180,18 @@ public class ElasticsearchAuditLogManager : IAuditLogManager, ITransientDependen var response = await client.GetAsync( id.ToString(), - dsl => dsl.Index(CreateIndex()), + dsl => + { + dsl.Index(CreateIndex()); + if (!includeDetails) + { + dsl.SourceExcludes( + ex => ex.Actions, + ex => ex.Comments, + ex => ex.Exceptions, + ex => ex.EntityChanges); + } + }, cancellationToken); return response.Source; @@ -209,6 +225,12 @@ public class ElasticsearchAuditLogManager : IAuditLogManager, ITransientDependen AuditLogInfo auditInfo, CancellationToken cancellationToken = default) { + if (!_loggingEsOptions.IsAuditLogEnabled) + { + Logger.LogInformation(auditInfo.ToString()); + return ""; + } + if (!_auditingOptions.HideErrors) { return await SaveLogAsync(auditInfo, cancellationToken); @@ -244,6 +266,32 @@ public class ElasticsearchAuditLogManager : IAuditLogManager, ITransientDependen var response = await client.BulkAsync( dsl => dsl.Index(CreateIndex()) .Create(auditLog, ct => ct.Id(auditLog.Id))); + if (!response.IsValidResponse) + { + if (response.TryGetOriginalException(out var ex)) + { + throw ex; + } + else if (response.ElasticsearchServerError != null) + { + throw new AbpException(response.ElasticsearchServerError.ToString()); + } + else if (response.ItemsWithErrors.Any()) + { + var reasonBuilder = new StringBuilder(); + foreach (var itemError in response.ItemsWithErrors) + { + if (itemError.Error?.Reason.IsNullOrWhiteSpace() == false) + { + reasonBuilder.AppendLine(itemError.Error.Reason); + } + } + if (reasonBuilder.Length > 0) + { + throw new AbpException(reasonBuilder.ToString()); + } + } + } return response.Items?.FirstOrDefault()?.Id; } diff --git a/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/ElasticsearchSecurityLogManager.cs b/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/ElasticsearchSecurityLogManager.cs index dbe73e0a1..396bdd4ab 100644 --- a/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/ElasticsearchSecurityLogManager.cs +++ b/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/ElasticsearchSecurityLogManager.cs @@ -21,6 +21,7 @@ public class ElasticsearchSecurityLogManager : ISecurityLogManager, ITransientDe { private readonly AbpSecurityLogOptions _securityLogOptions; private readonly AbpElasticsearchOptions _elasticsearchOptions; + private readonly AbpAuditLoggingElasticsearchOptions _loggingEsOptions; private readonly IIndexNameNormalizer _indexNameNormalizer; private readonly IGuidGenerator _guidGenerator; private readonly IElasticsearchClientFactory _clientFactory; @@ -34,7 +35,8 @@ public class ElasticsearchSecurityLogManager : ISecurityLogManager, ITransientDe IIndexNameNormalizer indexNameNormalizer, IOptions securityLogOptions, IOptions elasticsearchOptions, - IElasticsearchClientFactory clientFactory) + IElasticsearchClientFactory clientFactory, + IOptionsMonitor loggingEsOptions) { _clock = clock; _guidGenerator = guidGenerator; @@ -42,6 +44,7 @@ public class ElasticsearchSecurityLogManager : ISecurityLogManager, ITransientDe _indexNameNormalizer = indexNameNormalizer; _securityLogOptions = securityLogOptions.Value; _elasticsearchOptions = elasticsearchOptions.Value; + _loggingEsOptions = loggingEsOptions.CurrentValue; Logger = NullLogger.Instance; } @@ -56,17 +59,37 @@ public class ElasticsearchSecurityLogManager : ISecurityLogManager, ITransientDe return; } + + if (!_loggingEsOptions.IsSecurityLogEnabled) + { + Logger.LogInformation(securityLogInfo.ToString()); + return; + } + var client = _clientFactory.Create(); var securityLog = new SecurityLog( _guidGenerator.Create(), securityLogInfo); - await client.IndexAsync( + var response = await client.IndexAsync( securityLog, (x) => x.Index(CreateIndex()) .Id(securityLog.Id), cancellationToken); + + if (!response.IsValidResponse) + { + Logger.LogWarning("Could not save the security log object: " + Environment.NewLine + securityLogInfo.ToString()); + if (response.TryGetOriginalException(out var ex)) + { + Logger.LogWarning(ex, ex.Message); + } + else if (response.ElasticsearchServerError != null) + { + Logger.LogWarning(response.ElasticsearchServerError.ToString()); + } + } } public async virtual Task GetAsync( diff --git a/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/IndexInitializer.cs b/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/IndexInitializer.cs index 6a3a9253e..b5e4141c1 100644 --- a/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/IndexInitializer.cs +++ b/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/IndexInitializer.cs @@ -52,60 +52,61 @@ public class IndexInitializer : IIndexInitializer, ISingletonDependency { var indexCreateResponse = await client.Indices.CreateAsync(indexName, c => { - c.Settings(_elasticsearchOptions.IndexSettings); + c.Settings(_elasticsearchOptions.AuditLogSettings); c.Mappings(mp => mp + .Dynamic(DynamicMapping.False) .Properties(pd => { - pd.Keyword(k => k.Id); - pd.Keyword(k => k.ApplicationName); - pd.Keyword(k => k.UserId); - pd.Keyword(k => k.UserName); - pd.Keyword(k => k.TenantId); - pd.Keyword(k => k.TenantName); - pd.Keyword(k => k.ImpersonatorUserId); - pd.Keyword(k => k.ImpersonatorUserName); - pd.Keyword(k => k.ImpersonatorTenantId); - pd.Keyword(k => k.ImpersonatorTenantName); + pd.Text(k => k.Id, p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(36)))); + pd.Text(t => t.ApplicationName, p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(64)))); + pd.Text(k => k.UserId, p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(36)))); + pd.Text(t => t.UserName, p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(256)))); + pd.Text(k => k.TenantId, p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(36)))); + pd.Text(t => t.TenantName, p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(64)))); + pd.Text(k => k.ImpersonatorUserId, p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(36)))); + pd.Text(t => t.ImpersonatorUserName, p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(256)))); + pd.Text(k => k.ImpersonatorTenantId, p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(36)))); + pd.Text(t => t.ImpersonatorTenantName, p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(64)))); pd.Date(d => d.ExecutionTime, d => d.Format(dateTimeFormat)); pd.IntegerNumber(n => n.ExecutionDuration); - pd.Keyword(k => k.ClientIpAddress); - pd.Keyword(k => k.ClientName); - pd.Keyword(k => k.ClientId); - pd.Keyword(k => k.CorrelationId); - pd.Keyword(k => k.BrowserInfo); - pd.Keyword(k => k.HttpMethod); - pd.Keyword(k => k.Url); - pd.Keyword(k => k.Exceptions); - pd.Keyword(k => k.Comments); + pd.Text(k => k.ClientIpAddress, p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(256)))); + pd.Text(k => k.ClientName, p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(256)))); + pd.Text(k => k.ClientId, p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(256)))); + pd.Text(k => k.CorrelationId, p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(64)))); + pd.Text(k => k.BrowserInfo, p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(512)))); + pd.Text(k => k.HttpMethod, p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(36)))); + pd.Text(k => k.Url, p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(1024)))); + pd.Text(k => k.Exceptions, p => p.Store(true).Index(false)); + pd.Text(k => k.Comments, p => p.Store(true).Index(false)); pd.IntegerNumber(n => n.HttpStatusCode); pd.Nested(n => n.EntityChanges, np => { np.Dynamic(DynamicMapping.False); np.Properties(npd => { - npd.Keyword(nameof(EntityChange.Id)); - npd.Keyword(nameof(EntityChange.AuditLogId)); - npd.Keyword(nameof(EntityChange.TenantId)); + npd.Text(nameof(EntityChange.Id), p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(36)))); + npd.Text(nameof(EntityChange.AuditLogId), p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(36)))); + npd.Text(nameof(EntityChange.TenantId), p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(36)))); npd.Date(nameof(EntityChange.ChangeTime), d => d.Format(dateTimeFormat)); - npd.IntegerNumber(nameof(EntityChange.ChangeType)); - npd.Keyword(nameof(EntityChange.EntityTenantId)); - npd.Keyword(nameof(EntityChange.EntityId)); - npd.Keyword(nameof(EntityChange.EntityTypeFullName)); + npd.ByteNumber(nameof(EntityChange.ChangeType)); + npd.Text(nameof(EntityChange.EntityTenantId), p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(36)))); + npd.Text(nameof(EntityChange.EntityId), p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(128)))); + npd.Text(nameof(EntityChange.EntityTypeFullName), p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(256)))); npd.Nested(nameof(EntityChange.PropertyChanges), pc => { pc.Dynamic(DynamicMapping.False); pc.Properties(pcn => { - pcn.Keyword(nameof(EntityPropertyChange.Id)); - pcn.Keyword(nameof(EntityPropertyChange.TenantId)); - pcn.Keyword(nameof(EntityPropertyChange.EntityChangeId)); - pcn.Keyword(nameof(EntityPropertyChange.NewValue)); - pcn.Keyword(nameof(EntityPropertyChange.OriginalValue)); - pcn.Keyword(nameof(EntityPropertyChange.PropertyName)); - pcn.Keyword(nameof(EntityPropertyChange.PropertyTypeFullName)); + pcn.Text(nameof(EntityPropertyChange.Id), p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(36)))); + pcn.Text(nameof(EntityPropertyChange.TenantId), p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(36)))); + pcn.Text(nameof(EntityPropertyChange.EntityChangeId), p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(36)))); + pcn.Text(nameof(EntityPropertyChange.NewValue), p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(256)))); + pcn.Text(nameof(EntityPropertyChange.OriginalValue), p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(256)))); + pcn.Text(nameof(EntityPropertyChange.PropertyName), p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(256)))); + pcn.Text(nameof(EntityPropertyChange.PropertyTypeFullName), p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(256)))); }); }); - npd.Object(nameof(EntityChange.ExtraProperties)); + npd.Flattened(nameof(EntityChange.ExtraProperties), f => f.DepthLimit(5).EagerGlobalOrdinals(false)); }); }); pd.Nested(n => n.Actions, np => @@ -113,18 +114,18 @@ public class IndexInitializer : IIndexInitializer, ISingletonDependency np.Dynamic(DynamicMapping.False); np.Properties(npd => { - npd.Keyword(nameof(AuditLogAction.Id)); - npd.Keyword(nameof(AuditLogAction.TenantId)); - npd.Keyword(nameof(AuditLogAction.AuditLogId)); - npd.Keyword(nameof(AuditLogAction.ServiceName)); - npd.Keyword(nameof(AuditLogAction.MethodName)); - npd.Keyword(nameof(AuditLogAction.Parameters)); + npd.Text(nameof(AuditLogAction.Id), p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(36)))); + npd.Text(nameof(AuditLogAction.TenantId), p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(36)))); + npd.Text(nameof(AuditLogAction.AuditLogId), p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(36)))); + npd.Text(nameof(AuditLogAction.ServiceName), p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(256)))); + npd.Text(nameof(AuditLogAction.MethodName), p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(256)))); + npd.Text(nameof(AuditLogAction.Parameters), p => p.Store(true).Index(false)); npd.Date(nameof(AuditLogAction.ExecutionTime), d => d.Format(dateTimeFormat)); npd.IntegerNumber(nameof(AuditLogAction.ExecutionDuration)); - npd.Object(nameof(AuditLogAction.ExtraProperties)); + npd.Flattened(nameof(AuditLogAction.ExtraProperties), f => f.DepthLimit(5).EagerGlobalOrdinals(false)); }); }); - pd.Object(f => f.ExtraProperties); + pd.Flattened(f => f.ExtraProperties, f => f.DepthLimit(5).EagerGlobalOrdinals(false)); })); }); @@ -149,25 +150,26 @@ public class IndexInitializer : IIndexInitializer, ISingletonDependency { var indexCreateResponse = await client.Indices.CreateAsync(indexName, c => { - c.Settings(_elasticsearchOptions.IndexSettings); + c.Settings(_elasticsearchOptions.SecurityLogSettings); c.Mappings(mp => { + mp.Dynamic(DynamicMapping.False); mp.Properties(pd => { - pd.Keyword(k => k.Id); - pd.Keyword(k => k.TenantId); - pd.Keyword(k => k.ApplicationName); - pd.Keyword(k => k.Identity); - pd.Keyword(k => k.Action); - pd.Keyword(k => k.UserId); - pd.Keyword(k => k.UserName); - pd.Keyword(k => k.TenantName); - pd.Keyword(k => k.ClientId); - pd.Keyword(k => k.CorrelationId); - pd.Keyword(k => k.ClientIpAddress); - pd.Keyword(k => k.BrowserInfo); + pd.Text(k => k.Id, p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(36)))); + pd.Text(k => k.TenantId, p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(36)))); + pd.Text(k => k.ApplicationName, p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(256)))); + pd.Text(k => k.Identity, p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(256)))); + pd.Text(k => k.Action, p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(256)))); + pd.Text(k => k.UserId, p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(36)))); + pd.Text(k => k.UserName, p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(64)))); + pd.Text(k => k.TenantName, p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(64)))); + pd.Text(k => k.ClientId, p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(256)))); + pd.Text(k => k.CorrelationId, p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(256)))); + pd.Text(k => k.ClientIpAddress, p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(256)))); + pd.Text(k => k.BrowserInfo, p => p.Fields(f => f.Keyword("keyword", k => k.IgnoreAbove(512)))); pd.Date(k => k.CreationTime, d => d.Format(dateTimeFormat)); - pd.Object(f => f.ExtraProperties); + pd.Flattened(f => f.ExtraProperties, f => f.DepthLimit(5).EagerGlobalOrdinals(false)); }); }); }); diff --git a/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/EntityChange.cs b/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/EntityChange.cs index 4ab1ed0b3..593fe9f21 100644 --- a/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/EntityChange.cs +++ b/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/EntityChange.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text.Json.Serialization; using Volo.Abp.Auditing; using Volo.Abp.Data; using Volo.Abp.Guids; @@ -18,6 +19,7 @@ public class EntityChange : IHasExtraProperties public DateTime ChangeTime { get; set; } + [JsonConverter(typeof(EntityChangeTypeConverter))] public EntityChangeType ChangeType { get; set; } public Guid? EntityTenantId { get; set; } diff --git a/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/EntityChangeTypeConverter.cs b/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/EntityChangeTypeConverter.cs new file mode 100644 index 000000000..62a4815d3 --- /dev/null +++ b/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/EntityChangeTypeConverter.cs @@ -0,0 +1,31 @@ +using System; +using System.Text.Json; +using System.Text.Json.Serialization; +using Volo.Abp.Auditing; + +namespace LINGYUN.Abp.AuditLogging; +public class EntityChangeTypeConverter : JsonConverter +{ + public override EntityChangeType Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType == JsonTokenType.String) + { + var stringValue = reader.GetString(); + if (int.TryParse(stringValue, out var intValue)) + { + return (EntityChangeType)Enum.ToObject(typeof(EntityChangeType), intValue); + } + } + else if (reader.TokenType == JsonTokenType.Number) + { + return (EntityChangeType)Enum.ToObject(typeof(EntityChangeType), reader.GetInt32()); + } + + throw new JsonException($"Unable to convert value to enum {typeof(EntityChangeType).Name}"); + } + + public override void Write(Utf8JsonWriter writer, EntityChangeType value, JsonSerializerOptions options) + { + writer.WriteStringValue(Convert.ToInt32(value).ToString()); + } +} diff --git a/aspnet-core/framework/logging/LINGYUN.Abp.Logging.Serilog.Elasticsearch/LINGYUN/Abp/AuditLogging/Serilog/Elasticsearch/SerilogElasticsearchLoggingManager.cs b/aspnet-core/framework/logging/LINGYUN.Abp.Logging.Serilog.Elasticsearch/LINGYUN/Abp/AuditLogging/Serilog/Elasticsearch/SerilogElasticsearchLoggingManager.cs index 2e111cf4e..a845ae498 100644 --- a/aspnet-core/framework/logging/LINGYUN.Abp.Logging.Serilog.Elasticsearch/LINGYUN/Abp/AuditLogging/Serilog/Elasticsearch/SerilogElasticsearchLoggingManager.cs +++ b/aspnet-core/framework/logging/LINGYUN.Abp.Logging.Serilog.Elasticsearch/LINGYUN/Abp/AuditLogging/Serilog/Elasticsearch/SerilogElasticsearchLoggingManager.cs @@ -293,15 +293,27 @@ public class SerilogElasticsearchLoggingManager : ILoggingManager, ISingletonDep } if (!machineName.IsNullOrWhiteSpace()) { - queries.Add(new TermQuery(GetField(nameof(SerilogInfo.Fields.MachineName)), machineName)); + // 模糊匹配 + queries.Add(new WildcardQuery(GetField(nameof(SerilogInfo.Fields.MachineName))) + { + Value = $"*{machineName}*" + }); } if (!environment.IsNullOrWhiteSpace()) { - queries.Add(new TermQuery(GetField(nameof(SerilogInfo.Fields.Environment)), environment)); + // 模糊匹配 + queries.Add(new WildcardQuery(GetField(nameof(SerilogInfo.Fields.Environment))) + { + Value = $"*{environment}*" + }); } if (!application.IsNullOrWhiteSpace()) { - queries.Add(new TermQuery(GetField(nameof(SerilogInfo.Fields.Application)), application)); + // 模糊匹配 + queries.Add(new WildcardQuery(GetField(nameof(SerilogInfo.Fields.Application))) + { + Value = $"*{application}*" + }); } if (!context.IsNullOrWhiteSpace()) { @@ -396,19 +408,19 @@ public class SerilogElasticsearchLoggingManager : ILoggingManager, ISingletonDep private readonly static IDictionary _fieldMaps = new Dictionary(StringComparer.InvariantCultureIgnoreCase) { { "timestamp", "@timestamp" }, - { "level", "level.raw" }, - { "machinename", $"fields.{AbpLoggingEnricherPropertyNames.MachineName}.raw" }, - { "environment", $"fields.{AbpLoggingEnricherPropertyNames.EnvironmentName}.raw" }, - { "application", $"fields.{AbpSerilogEnrichersConsts.ApplicationNamePropertyName}.raw" }, - { "context", "fields.SourceContext.raw" }, - { "actionid", "fields.ActionId.raw" }, - { "actionname", "fields.ActionName.raw" }, - { "requestid", "fields.RequestId.raw" }, + { "level", "level.keyword" }, + { "machinename", $"fields.{AbpLoggingEnricherPropertyNames.MachineName}.keyword" }, + { "environment", $"fields.{AbpLoggingEnricherPropertyNames.EnvironmentName}.keyword" }, + { "application", $"fields.{AbpSerilogEnrichersConsts.ApplicationNamePropertyName}.keyword" }, + { "context", "fields.SourceContext.keyword" }, + { "actionid", "fields.ActionId.keyword" }, + { "actionname", "fields.ActionName.keyword" }, + { "requestid", "fields.RequestId.keyword" }, { "requestpath", "fields.RequestPath" }, { "connectionid", "fields.ConnectionId" }, - { "correlationid", "fields.CorrelationId.raw" }, - { "clientid", "fields.ClientId.raw" }, - { "userid", "fields.UserId.raw" }, + { "correlationid", "fields.CorrelationId.keyword" }, + { "clientid", "fields.ClientId.keyword" }, + { "userid", "fields.UserId.keyword" }, { "processid", "fields.ProcessId" }, { "threadid", "fields.ThreadId" }, { "id", $"fields.{AbpSerilogUniqueIdConsts.UniqueIdPropertyName}" },