Browse Source

feat(auditing): ES审计模块启动时初始化索引

pull/405/head
cKey 4 years ago
parent
commit
810f0ed1d0
  1. 2
      aspnet-core/modules/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/AbpAuditLoggingElasticsearchModule.cs
  2. 6
      aspnet-core/modules/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/AbpAuditLoggingElasticsearchOptions.cs
  3. 19
      aspnet-core/modules/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/ElasticsearchAuditLogManager.cs
  4. 19
      aspnet-core/modules/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/ElasticsearchSecurityLogManager.cs
  5. 9
      aspnet-core/modules/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/IIndexInitializer.cs
  6. 7
      aspnet-core/modules/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/IIndexNameNormalizer.cs
  7. 106
      aspnet-core/modules/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/IndexInitializer.cs
  8. 21
      aspnet-core/modules/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/IndexInitializerService.cs
  9. 32
      aspnet-core/modules/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/IndexNameNormalizer.cs
  10. 40
      aspnet-core/modules/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/DefaultEntityChangeStore.cs
  11. 9
      aspnet-core/modules/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/EntityChangeWithUsername.cs
  12. 46
      aspnet-core/modules/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/IEntityChangeStore.cs
  13. 2
      aspnet-core/services/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/Properties/launchSettings.json

2
aspnet-core/modules/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/AbpAuditLoggingElasticsearchModule.cs

@ -15,6 +15,8 @@ namespace LINGYUN.Abp.AuditLogging.Elasticsearch
{
var configuration = context.Services.GetConfiguration();
Configure<AbpAuditLoggingElasticsearchOptions>(configuration.GetSection("AuditLogging:Elasticsearch"));
context.Services.AddHostedService<IndexInitializerService>();
}
}
}

6
aspnet-core/modules/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/AbpAuditLoggingElasticsearchOptions.cs

@ -1,13 +1,17 @@
namespace LINGYUN.Abp.AuditLogging.Elasticsearch
using Nest;
namespace LINGYUN.Abp.AuditLogging.Elasticsearch
{
public class AbpAuditLoggingElasticsearchOptions
{
public const string DefaultIndexPrefix = "auditlogging";
public string IndexPrefix { get; set; }
public IIndexSettings IndexSettings { get; set; }
public AbpAuditLoggingElasticsearchOptions()
{
IndexPrefix = DefaultIndexPrefix;
IndexSettings = new IndexSettings();
}
}
}

19
aspnet-core/modules/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/ElasticsearchAuditLogManager.cs

@ -11,8 +11,6 @@ using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Auditing;
using Volo.Abp.DependencyInjection;
using Volo.Abp.MultiTenancy;
using Volo.Abp;
namespace LINGYUN.Abp.AuditLogging.Elasticsearch
{
@ -21,27 +19,24 @@ namespace LINGYUN.Abp.AuditLogging.Elasticsearch
{
private readonly AbpAuditingOptions _auditingOptions;
private readonly AbpElasticsearchOptions _elasticsearchOptions;
private readonly AbpAuditLoggingElasticsearchOptions _options;
private readonly ICurrentTenant _currentTenant;
private readonly IIndexNameNormalizer _indexNameNormalizer;
private readonly IElasticsearchClientFactory _clientFactory;
private readonly IAuditLogInfoToAuditLogConverter _converter;
public ILogger<ElasticsearchAuditLogManager> Logger { protected get; set; }
public ElasticsearchAuditLogManager(
ICurrentTenant currentTenant,
IIndexNameNormalizer indexNameNormalizer,
IOptions<AbpElasticsearchOptions> elasticsearchOptions,
IOptionsSnapshot<AbpAuditLoggingElasticsearchOptions> options,
IElasticsearchClientFactory clientFactory,
IOptions<AbpAuditingOptions> auditingOptions,
IAuditLogInfoToAuditLogConverter converter)
{
_options = options.Value;
_converter = converter;
_clientFactory = clientFactory;
_currentTenant = currentTenant;
_auditingOptions = auditingOptions.Value;
_elasticsearchOptions = elasticsearchOptions.Value;
_indexNameNormalizer = indexNameNormalizer;
Logger = NullLogger<ElasticsearchAuditLogManager>.Instance;
}
@ -330,13 +325,7 @@ namespace LINGYUN.Abp.AuditLogging.Elasticsearch
protected virtual string CreateIndex()
{
if (_currentTenant.IsAvailable)
{
return $"{_options.IndexPrefix}-audit-log-{_currentTenant.Id:N}";
}
return _options.IndexPrefix.IsNullOrWhiteSpace()
? "audit-log"
: $"{_options.IndexPrefix}-audit-log";
return _indexNameNormalizer.NormalizeIndex("audit-log");
}
private readonly static IDictionary<string, string> _fieldMaps = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase)

19
aspnet-core/modules/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/ElasticsearchSecurityLogManager.cs

@ -10,7 +10,6 @@ using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Guids;
using Volo.Abp.MultiTenancy;
using Volo.Abp.SecurityLog;
namespace LINGYUN.Abp.AuditLogging.Elasticsearch
@ -20,25 +19,22 @@ namespace LINGYUN.Abp.AuditLogging.Elasticsearch
{
private readonly AbpSecurityLogOptions _securityLogOptions;
private readonly AbpElasticsearchOptions _elasticsearchOptions;
private readonly AbpAuditLoggingElasticsearchOptions _options;
private readonly ICurrentTenant _currentTenant;
private readonly IIndexNameNormalizer _indexNameNormalizer;
private readonly IGuidGenerator _guidGenerator;
private readonly IElasticsearchClientFactory _clientFactory;
public ILogger<ElasticsearchSecurityLogManager> Logger { protected get; set; }
public ElasticsearchSecurityLogManager(
ICurrentTenant currentTenant,
IGuidGenerator guidGenerator,
IIndexNameNormalizer indexNameNormalizer,
IOptions<AbpSecurityLogOptions> securityLogOptions,
IOptions<AbpElasticsearchOptions> elasticsearchOptions,
IOptionsSnapshot<AbpAuditLoggingElasticsearchOptions> options,
IElasticsearchClientFactory clientFactory)
{
_options = options.Value;
_currentTenant = currentTenant;
_guidGenerator = guidGenerator;
_clientFactory = clientFactory;
_indexNameNormalizer = indexNameNormalizer;
_securityLogOptions = securityLogOptions.Value;
_elasticsearchOptions = elasticsearchOptions.Value;
@ -240,14 +236,7 @@ namespace LINGYUN.Abp.AuditLogging.Elasticsearch
protected virtual string CreateIndex()
{
// TODO: 会出现索引很长的情况...
if (_currentTenant.IsAvailable)
{
return $"{_options.IndexPrefix}-security-log-{_currentTenant.Id:N}";
}
return _options.IndexPrefix.IsNullOrWhiteSpace()
? "security-log"
: $"{_options.IndexPrefix}-security-log";
return _indexNameNormalizer.NormalizeIndex("security-log");
}
private readonly static IDictionary<string, string> _fieldMaps = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase)

9
aspnet-core/modules/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/IIndexInitializer.cs

@ -0,0 +1,9 @@
using System.Threading.Tasks;
namespace LINGYUN.Abp.AuditLogging.Elasticsearch
{
public interface IIndexInitializer
{
Task InitializeAsync();
}
}

7
aspnet-core/modules/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/IIndexNameNormalizer.cs

@ -0,0 +1,7 @@
namespace LINGYUN.Abp.AuditLogging.Elasticsearch
{
public interface IIndexNameNormalizer
{
string NormalizeIndex(string index);
}
}

106
aspnet-core/modules/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/IndexInitializer.cs

@ -0,0 +1,106 @@
using LINGYUN.Abp.Elasticsearch;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using Nest;
using System;
using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Json;
namespace LINGYUN.Abp.AuditLogging.Elasticsearch
{
public class IndexInitializer : IIndexInitializer, ISingletonDependency
{
private readonly AbpJsonOptions _jsonOptions;
private readonly AbpAuditLoggingElasticsearchOptions _elasticsearchOptions;
private readonly IIndexNameNormalizer _nameNormalizer;
private readonly IElasticsearchClientFactory _clientFactory;
public ILogger<IndexInitializer> Logger { protected get; set; }
public IndexInitializer(
IOptions<AbpJsonOptions> jsonOptions,
IOptions<AbpAuditLoggingElasticsearchOptions> elasticsearchOptions,
IIndexNameNormalizer nameNormalizer,
IElasticsearchClientFactory clientFactory)
{
_jsonOptions = jsonOptions.Value;
_elasticsearchOptions = elasticsearchOptions.Value;
_nameNormalizer = nameNormalizer;
_clientFactory = clientFactory;
Logger = NullLogger<IndexInitializer>.Instance;
}
public virtual async Task InitializeAsync()
{
var client = _clientFactory.Create();
var dateTimeFormat = !_jsonOptions.DefaultDateTimeFormat.IsNullOrWhiteSpace()
? $"{_jsonOptions.DefaultDateTimeFormat}||strict_date_optional_time||epoch_millis"
: "strict_date_optional_time||epoch_millis";
var indexState = new IndexState
{
Settings = _elasticsearchOptions.IndexSettings,
};
await InitlizeAuditLogIndex(client, indexState, dateTimeFormat);
await InitlizeSecurityLogIndex(client, indexState, dateTimeFormat);
}
protected virtual async Task InitlizeAuditLogIndex(IElasticClient client, IIndexState indexState, string dateTimeFormat)
{
var indexName = _nameNormalizer.NormalizeIndex("audit-log");
var indexExists = await client.Indices.ExistsAsync(indexName);
if (!indexExists.Exists)
{
var indexCreateResponse = await client.Indices.CreateAsync(
indexName,
dsl => dsl.InitializeUsing(indexState)
.Map<AuditLog>(map =>
map.AutoMap()
.Properties(mp =>
mp.Date(p => p.Name(n => n.ExecutionTime).Format(dateTimeFormat))
.Object<ExtraPropertyDictionary>(p => p.Name(n => n.ExtraProperties))
.Nested<EntityChange>(n =>
n.AutoMap()
.Name(nameof(AuditLog.EntityChanges))
.Properties(np =>
np.Object<ExtraPropertyDictionary>(p => p.Name(n => n.ExtraProperties))
.Date(p => p.Name(n => n.ChangeTime).Format(dateTimeFormat))
.Nested<EntityPropertyChange>(npn => npn.Name(nameof(EntityChange.PropertyChanges)))))
.Nested<AuditLogAction>(n => n.Name(nameof(AuditLog.Actions))
.AutoMap()
.Properties((np =>
np.Object<ExtraPropertyDictionary>(p => p.Name(n => n.ExtraProperties))
.Date(p => p.Name(n => n.ExecutionTime).Format(dateTimeFormat))))))));
if (indexCreateResponse.IsValid)
{
Logger.LogWarning("Failed to initialize index and audit log may not be retrieved.");
Logger.LogWarning(indexCreateResponse.OriginalException.ToString());
}
}
}
protected virtual async Task InitlizeSecurityLogIndex(IElasticClient client, IIndexState indexState, string dateTimeFormat)
{
var indexName = _nameNormalizer.NormalizeIndex("security-log");
var indexExists = await client.Indices.ExistsAsync(indexName);
if (!indexExists.Exists)
{
var indexCreateResponse = await client.Indices.CreateAsync(
indexName,
dsl => dsl.InitializeUsing(indexState)
.Map<SecurityLog>(map =>
map.AutoMap()
.Properties(mp =>
mp.Object<ExtraPropertyDictionary>(p => p.Name(n => n.ExtraProperties))
.Date(p => p.Name(n => n.CreationTime).Format(dateTimeFormat)))));
if (indexCreateResponse.IsValid)
{
}
}
}
}
}

21
aspnet-core/modules/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/IndexInitializerService.cs

@ -0,0 +1,21 @@
using Microsoft.Extensions.Hosting;
using System.Threading;
using System.Threading.Tasks;
namespace LINGYUN.Abp.AuditLogging.Elasticsearch
{
public class IndexInitializerService : BackgroundService
{
private readonly IIndexInitializer _indexInitializer;
public IndexInitializerService(IIndexInitializer indexInitializer)
{
_indexInitializer = indexInitializer;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
await _indexInitializer.InitializeAsync();
}
}
}

32
aspnet-core/modules/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/IndexNameNormalizer.cs

@ -0,0 +1,32 @@
using Microsoft.Extensions.Options;
using System;
using Volo.Abp.DependencyInjection;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.AuditLogging.Elasticsearch
{
public class IndexNameNormalizer : IIndexNameNormalizer, ISingletonDependency
{
private readonly ICurrentTenant _currentTenant;
private readonly AbpAuditLoggingElasticsearchOptions _options;
public IndexNameNormalizer(
ICurrentTenant currentTenant,
IOptions<AbpAuditLoggingElasticsearchOptions> options)
{
_currentTenant = currentTenant;
_options = options.Value;
}
public string NormalizeIndex(string index)
{
if (_currentTenant.IsAvailable)
{
return $"{_options.IndexPrefix}-{index}-{_currentTenant.Id:N}";
}
return _options.IndexPrefix.IsNullOrWhiteSpace()
? index
: $"{_options.IndexPrefix}-{index}";
}
}
}

40
aspnet-core/modules/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/DefaultEntityChangeStore.cs

@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Auditing;
using Volo.Abp.DependencyInjection;
namespace LINGYUN.Abp.AuditLogging
{
[Dependency(TryRegister = true)]
public class DefaultEntityChangeStore : IEntityChangeStore, ISingletonDependency
{
public Task<EntityChange> GetAsync(Guid entityChangeId, CancellationToken cancellationToken = default)
{
EntityChange entityChange = null;
return Task.FromResult(entityChange);
}
public Task<long> GetCountAsync(Guid? auditLogId = null, DateTime? startTime = null, DateTime? endTime = null, EntityChangeType? changeType = null, string entityId = null, string entityTypeFullName = null, CancellationToken cancellationToken = default)
{
return Task.FromResult(0L);
}
public Task<List<EntityChange>> GetListAsync(string sorting = null, int maxResultCount = 50, int skipCount = 0, Guid? auditLogId = null, DateTime? startTime = null, DateTime? endTime = null, EntityChangeType? changeType = null, string entityId = null, string entityTypeFullName = null, bool includeDetails = false, CancellationToken cancellationToken = default)
{
return Task.FromResult(new List<EntityChange>());
}
public Task<EntityChangeWithUsername> GetWithUsernameAsync(Guid entityChangeId, CancellationToken cancellationToken = default)
{
EntityChangeWithUsername entityChange = null;
return Task.FromResult(entityChange);
}
public Task<List<EntityChangeWithUsername>> GetWithUsernameAsync(string entityId, string entityTypeFullName, CancellationToken cancellationToken = default)
{
return Task.FromResult(new List<EntityChangeWithUsername>());
}
}
}

9
aspnet-core/modules/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/EntityChangeWithUsername.cs

@ -0,0 +1,9 @@
namespace LINGYUN.Abp.AuditLogging
{
public class EntityChangeWithUsername
{
public EntityChange EntityChange { get; set; }
public string UserName { get; set; }
}
}

46
aspnet-core/modules/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/IEntityChangeStore.cs

@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Auditing;
namespace LINGYUN.Abp.AuditLogging
{
public interface IEntityChangeStore
{
Task<EntityChange> GetAsync(
Guid entityChangeId,
CancellationToken cancellationToken = default);
Task<long> GetCountAsync(
Guid? auditLogId = null,
DateTime? startTime = null,
DateTime? endTime = null,
EntityChangeType? changeType = null,
string entityId = null,
string entityTypeFullName = null,
CancellationToken cancellationToken = default);
Task<List<EntityChange>> GetListAsync(
string sorting = null,
int maxResultCount = 50,
int skipCount = 0,
Guid? auditLogId = null,
DateTime? startTime = null,
DateTime? endTime = null,
EntityChangeType? changeType = null,
string entityId = null,
string entityTypeFullName = null,
bool includeDetails = false,
CancellationToken cancellationToken = default);
Task<EntityChangeWithUsername> GetWithUsernameAsync(
Guid entityChangeId,
CancellationToken cancellationToken = default);
Task<List<EntityChangeWithUsername>> GetWithUsernameAsync(
string entityId,
string entityTypeFullName,
CancellationToken cancellationToken = default);
}
}

2
aspnet-core/services/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host/Properties/launchSettings.json

@ -13,7 +13,7 @@
"launchBrowser": false,
"applicationUrl": "http://0.0.0.0:30010",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
"ASPNETCORE_ENVIRONMENT": "Production"
}
}
}

Loading…
Cancel
Save