From 1df5c7f6bd90354f87bcc0fa7ec71f4785189b58 Mon Sep 17 00:00:00 2001
From: guotianliang <1265346495@qq.com>
Date: Thu, 12 May 2022 17:32:31 +0800
Subject: [PATCH] add auditing-logging
---
Directory.Build.props | 2 +
Sanhe.Abp.Framework.sln | 73 ++++
.../FodyWeavers.xml | 3 +
.../README.md | 38 ++
...anhe.Abp.AuditLogging.Elasticsearch.csproj | 20 +
.../AbpAuditLoggingElasticsearchModule.cs | 22 +
.../AbpAuditLoggingElasticsearchOptions.cs | 17 +
.../AuditLogInfoToAuditLogConverter.cs | 104 +++++
.../ElasticsearchAuditLogManager.cs | 362 +++++++++++++++
.../ElasticsearchEntityChangeStore.cs | 371 ++++++++++++++++
.../ElasticsearchSecurityLogManager.cs | 268 ++++++++++++
.../IAuditLogInfoToAuditLogConverter.cs | 10 +
.../Elasticsearch/IIndexInitializer.cs | 9 +
.../Elasticsearch/IIndexNameNormalizer.cs | 7 +
.../Elasticsearch/IndexInitializer.cs | 107 +++++
.../Elasticsearch/IndexInitializerService.cs | 21 +
.../Elasticsearch/IndexNameNormalizer.cs | 30 ++
.../FodyWeavers.xml | 3 +
.../README.md | 32 ++
...bp.AuditLogging.EntityFrameworkCore.csproj | 21 +
...bpAuditLoggingEntityFrameworkCoreModule.cs | 25 ++
.../AbpAuditingMapperProfile.cs | 21 +
.../EntityFrameworkCore/AuditLogManager.cs | 179 ++++++++
.../EntityFrameworkCore/SecurityLogManager.cs | 144 ++++++
.../Sanhe.Abp.AuditLogging/FodyWeavers.xml | 3 +
.../Sanhe.Abp.AuditLogging.csproj | 17 +
.../Abp/AuditLogging/AbpAuditLoggingModule.cs | 15 +
.../Sanhe/Abp/AuditLogging/AuditLog.cs | 115 +++++
.../Sanhe/Abp/AuditLogging/AuditLogAction.cs | 47 ++
.../Sanhe/Abp/AuditLogging/AuditingStore.cs | 23 +
.../AuditLogging/DefaultAuditLogManager.cs | 96 ++++
.../AuditLogging/DefaultEntityChangeStore.cs | 40 ++
.../AuditLogging/DefaultSecurityLogManager.cs | 87 ++++
.../Sanhe/Abp/AuditLogging/EntityChange.cs | 69 +++
.../AuditLogging/EntityChangeWithUsername.cs | 9 +
.../Abp/AuditLogging/EntityPropertyChange.cs | 43 ++
.../Abp/AuditLogging/IAuditLogManager.cs | 64 +++
.../Abp/AuditLogging/IEntityChangeStore.cs | 46 ++
.../Abp/AuditLogging/ISecurityLogManager.cs | 56 +++
.../Sanhe/Abp/AuditLogging/SecurityLog.cs | 72 +++
.../Abp/AuditLogging/SecurityLogStore.cs | 23 +
.../FodyWeavers.xml | 3 +
....Abp.Auditing.Application.Contracts.csproj | 28 ++
.../AbpAuditingApplicationContractsModule.cs | 34 ++
.../Auditing/AuditLogs/AuditLogActionDto.cs | 18 +
.../Abp/Auditing/AuditLogs/AuditLogDto.cs | 55 +++
.../AuditLogs/AuditLogGetByPagedDto.cs | 24 +
.../Abp/Auditing/AuditLogs/EntityChangeDto.cs | 27 ++
.../AuditLogs/EntityChangeGetByPagedDto.cs | 15 +
.../EntityChangeGetWithUsernameDto.cs | 7 +
.../AuditLogs/EntityChangeWithUsernameDto.cs | 8 +
.../AuditLogs/EntityPropertyChangeDto.cs | 16 +
.../Auditing/AuditLogs/IAuditLogAppService.cs | 16 +
.../AuditLogs/IEntityChangesAppService.cs | 17 +
.../Auditing/AuditingRemoteServiceConsts.cs | 7 +
.../AuditingFeatureDefinitionProvider.cs | 43 ++
.../Auditing/Features/AuditingFeatureNames.cs | 15 +
.../Auditing/Localization/Resources/en.json | 88 ++++
.../Localization/Resources/zh-Hans.json | 88 ++++
.../Sanhe/Abp/Auditing/Logging/Dto/LogDto.cs | 15 +
.../Auditing/Logging/Dto/LogExceptionDto.cs | 13 +
.../Abp/Auditing/Logging/Dto/LogFieldDto.cs | 21 +
.../Auditing/Logging/Dto/LogGetByPagedDto.cs | 23 +
.../Abp/Auditing/Logging/ILogAppService.cs | 14 +
.../AuditingPermissionDefinitionProvider.cs | 35 ++
.../Permissions/AuditingPermissionNames.cs | 18 +
.../SecurityLogs/ISecurityLogAppService.cs | 16 +
.../Auditing/SecurityLogs/SecurityLogDto.cs | 30 ++
.../SecurityLogs/SecurityLogGetByPagedDto.cs | 18 +
.../FodyWeavers.xml | 3 +
.../Sanhe.Abp.Auditing.Application.csproj | 22 +
.../Auditing/AbpAuditingApplicationModule.cs | 24 +
.../Abp/Auditing/AbpAuditingMapperProfile.cs | 31 ++
.../Auditing/AuditLogs/AuditLogAppService.cs | 63 +++
.../AuditLogs/EntityChangesAppService.cs | 61 +++
.../AuditingApplicationServiceBase.cs | 14 +
.../Abp/Auditing/Logging/LogAppService.cs | 49 +++
.../SecurityLogs/SecurityLogAppService.cs | 57 +++
.../FodyWeavers.xml | 3 +
.../Sanhe.Abp.Auditing.HttpApi.csproj | 19 +
.../Abp/Auditing/AbpAuditingHttpApiModule.cs | 41 ++
.../Auditing/AuditLogs/AuditLogController.cs | 61 +++
.../AuditLogs/EntityChangesController.cs | 49 +++
.../Abp/Auditing/Logging/LogController.cs | 49 +++
.../SecurityLogs/SecurityLogController.cs | 62 +++
.../FodyWeavers.xml | 3 +
.../README.md | 32 ++
...e.Abp.Logging.Serilog.Elasticsearch.csproj | 24 +
...oggingSerilogElasticsearchMapperProfile.cs | 16 +
.../AbpLoggingSerilogElasticsearchModule.cs | 31 ++
.../AbpLoggingSerilogElasticsearchOptions.cs | 12 +
.../SerilogElasticsearchLoggingManager.cs | 412 ++++++++++++++++++
.../Serilog/Elasticsearch/SerilogException.cs | 26 ++
.../Serilog/Elasticsearch/SerilogField.cs | 58 +++
.../Serilog/Elasticsearch/SerilogInfo.cs | 26 ++
.../logging/Sanhe.Abp.Logging/FodyWeavers.xml | 3 +
modules/logging/Sanhe.Abp.Logging/README.md | 15 +
.../Sanhe.Abp.Logging.csproj | 14 +
.../AbpLoggingEnricherPropertyNames.cs | 8 +
.../Sanhe/Abp/Logging/AbpLoggingModule.cs | 15 +
.../Abp/Logging/DefaultLoggingManager.cs | 72 +++
.../Sanhe/Abp/Logging/ILoggingManager.cs | 51 +++
.../Sanhe/Abp/Logging/LogException.cs | 13 +
.../Sanhe/Abp/Logging/LogField.cs | 21 +
.../Sanhe/Abp/Logging/LogInfo.cs | 15 +
.../FodyWeavers.xml | 3 +
.../README.md | 48 ++
...e.Abp.Serilog.Enrichers.Application.csproj | 16 +
.../AbpSerilogEnrichersApplicationModule.cs | 9 +
.../Application/AbpSerilogEnrichersConsts.cs | 8 +
.../Application/ApplicationNameEnricher.cs | 30 ++
...pplicationLoggerConfigurationExtensions.cs | 16 +
.../FodyWeavers.xml | 3 +
...anhe.Abp.Serilog.Enrichers.UniqueId.csproj | 19 +
.../AbpSerilogEnrichersUniqueIdModule.cs | 17 +
.../AbpSerilogEnrichersUniqueIdOptions.cs | 12 +
.../UniqueId/AbpSerilogUniqueIdConsts.cs | 7 +
.../Enrichers/UniqueId/UniqueIdEnricher.cs | 19 +
.../UniqueIdLoggerConfigurationExtensions.cs | 16 +
119 files changed, 5124 insertions(+)
create mode 100644 modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/FodyWeavers.xml
create mode 100644 modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/README.md
create mode 100644 modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe.Abp.AuditLogging.Elasticsearch.csproj
create mode 100644 modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/AbpAuditLoggingElasticsearchModule.cs
create mode 100644 modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/AbpAuditLoggingElasticsearchOptions.cs
create mode 100644 modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/AuditLogInfoToAuditLogConverter.cs
create mode 100644 modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/ElasticsearchAuditLogManager.cs
create mode 100644 modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/ElasticsearchEntityChangeStore.cs
create mode 100644 modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/ElasticsearchSecurityLogManager.cs
create mode 100644 modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/IAuditLogInfoToAuditLogConverter.cs
create mode 100644 modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/IIndexInitializer.cs
create mode 100644 modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/IIndexNameNormalizer.cs
create mode 100644 modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/IndexInitializer.cs
create mode 100644 modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/IndexInitializerService.cs
create mode 100644 modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/IndexNameNormalizer.cs
create mode 100644 modules/auditing/Sanhe.Abp.AuditLogging.EntityFrameworkCore/FodyWeavers.xml
create mode 100644 modules/auditing/Sanhe.Abp.AuditLogging.EntityFrameworkCore/README.md
create mode 100644 modules/auditing/Sanhe.Abp.AuditLogging.EntityFrameworkCore/Sanhe.Abp.AuditLogging.EntityFrameworkCore.csproj
create mode 100644 modules/auditing/Sanhe.Abp.AuditLogging.EntityFrameworkCore/Sanhe/Abp/AuditLogging/EntityFrameworkCore/AbpAuditLoggingEntityFrameworkCoreModule.cs
create mode 100644 modules/auditing/Sanhe.Abp.AuditLogging.EntityFrameworkCore/Sanhe/Abp/AuditLogging/EntityFrameworkCore/AbpAuditingMapperProfile.cs
create mode 100644 modules/auditing/Sanhe.Abp.AuditLogging.EntityFrameworkCore/Sanhe/Abp/AuditLogging/EntityFrameworkCore/AuditLogManager.cs
create mode 100644 modules/auditing/Sanhe.Abp.AuditLogging.EntityFrameworkCore/Sanhe/Abp/AuditLogging/EntityFrameworkCore/SecurityLogManager.cs
create mode 100644 modules/auditing/Sanhe.Abp.AuditLogging/FodyWeavers.xml
create mode 100644 modules/auditing/Sanhe.Abp.AuditLogging/Sanhe.Abp.AuditLogging.csproj
create mode 100644 modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/AbpAuditLoggingModule.cs
create mode 100644 modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/AuditLog.cs
create mode 100644 modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/AuditLogAction.cs
create mode 100644 modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/AuditingStore.cs
create mode 100644 modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/DefaultAuditLogManager.cs
create mode 100644 modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/DefaultEntityChangeStore.cs
create mode 100644 modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/DefaultSecurityLogManager.cs
create mode 100644 modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/EntityChange.cs
create mode 100644 modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/EntityChangeWithUsername.cs
create mode 100644 modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/EntityPropertyChange.cs
create mode 100644 modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/IAuditLogManager.cs
create mode 100644 modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/IEntityChangeStore.cs
create mode 100644 modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/ISecurityLogManager.cs
create mode 100644 modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/SecurityLog.cs
create mode 100644 modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/SecurityLogStore.cs
create mode 100644 modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/FodyWeavers.xml
create mode 100644 modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe.Abp.Auditing.Application.Contracts.csproj
create mode 100644 modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AbpAuditingApplicationContractsModule.cs
create mode 100644 modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AuditLogs/AuditLogActionDto.cs
create mode 100644 modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AuditLogs/AuditLogDto.cs
create mode 100644 modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AuditLogs/AuditLogGetByPagedDto.cs
create mode 100644 modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AuditLogs/EntityChangeDto.cs
create mode 100644 modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AuditLogs/EntityChangeGetByPagedDto.cs
create mode 100644 modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AuditLogs/EntityChangeGetWithUsernameDto.cs
create mode 100644 modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AuditLogs/EntityChangeWithUsernameDto.cs
create mode 100644 modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AuditLogs/EntityPropertyChangeDto.cs
create mode 100644 modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AuditLogs/IAuditLogAppService.cs
create mode 100644 modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AuditLogs/IEntityChangesAppService.cs
create mode 100644 modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AuditingRemoteServiceConsts.cs
create mode 100644 modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/Features/AuditingFeatureDefinitionProvider.cs
create mode 100644 modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/Features/AuditingFeatureNames.cs
create mode 100644 modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/Localization/Resources/en.json
create mode 100644 modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/Localization/Resources/zh-Hans.json
create mode 100644 modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/Logging/Dto/LogDto.cs
create mode 100644 modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/Logging/Dto/LogExceptionDto.cs
create mode 100644 modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/Logging/Dto/LogFieldDto.cs
create mode 100644 modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/Logging/Dto/LogGetByPagedDto.cs
create mode 100644 modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/Logging/ILogAppService.cs
create mode 100644 modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/Permissions/AuditingPermissionDefinitionProvider.cs
create mode 100644 modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/Permissions/AuditingPermissionNames.cs
create mode 100644 modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/SecurityLogs/ISecurityLogAppService.cs
create mode 100644 modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/SecurityLogs/SecurityLogDto.cs
create mode 100644 modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/SecurityLogs/SecurityLogGetByPagedDto.cs
create mode 100644 modules/auditing/Sanhe.Abp.Auditing.Application/FodyWeavers.xml
create mode 100644 modules/auditing/Sanhe.Abp.Auditing.Application/Sanhe.Abp.Auditing.Application.csproj
create mode 100644 modules/auditing/Sanhe.Abp.Auditing.Application/Sanhe/Abp/Auditing/AbpAuditingApplicationModule.cs
create mode 100644 modules/auditing/Sanhe.Abp.Auditing.Application/Sanhe/Abp/Auditing/AbpAuditingMapperProfile.cs
create mode 100644 modules/auditing/Sanhe.Abp.Auditing.Application/Sanhe/Abp/Auditing/AuditLogs/AuditLogAppService.cs
create mode 100644 modules/auditing/Sanhe.Abp.Auditing.Application/Sanhe/Abp/Auditing/AuditLogs/EntityChangesAppService.cs
create mode 100644 modules/auditing/Sanhe.Abp.Auditing.Application/Sanhe/Abp/Auditing/AuditingApplicationServiceBase.cs
create mode 100644 modules/auditing/Sanhe.Abp.Auditing.Application/Sanhe/Abp/Auditing/Logging/LogAppService.cs
create mode 100644 modules/auditing/Sanhe.Abp.Auditing.Application/Sanhe/Abp/Auditing/SecurityLogs/SecurityLogAppService.cs
create mode 100644 modules/auditing/Sanhe.Abp.Auditing.HttpApi/FodyWeavers.xml
create mode 100644 modules/auditing/Sanhe.Abp.Auditing.HttpApi/Sanhe.Abp.Auditing.HttpApi.csproj
create mode 100644 modules/auditing/Sanhe.Abp.Auditing.HttpApi/Sanhe/Abp/Auditing/AbpAuditingHttpApiModule.cs
create mode 100644 modules/auditing/Sanhe.Abp.Auditing.HttpApi/Sanhe/Abp/Auditing/AuditLogs/AuditLogController.cs
create mode 100644 modules/auditing/Sanhe.Abp.Auditing.HttpApi/Sanhe/Abp/Auditing/AuditLogs/EntityChangesController.cs
create mode 100644 modules/auditing/Sanhe.Abp.Auditing.HttpApi/Sanhe/Abp/Auditing/Logging/LogController.cs
create mode 100644 modules/auditing/Sanhe.Abp.Auditing.HttpApi/Sanhe/Abp/Auditing/SecurityLogs/SecurityLogController.cs
create mode 100644 modules/logging/Sanhe.Abp.Logging.Serilog.Elasticsearch/FodyWeavers.xml
create mode 100644 modules/logging/Sanhe.Abp.Logging.Serilog.Elasticsearch/README.md
create mode 100644 modules/logging/Sanhe.Abp.Logging.Serilog.Elasticsearch/Sanhe.Abp.Logging.Serilog.Elasticsearch.csproj
create mode 100644 modules/logging/Sanhe.Abp.Logging.Serilog.Elasticsearch/Sanhe/Abp/AuditLogging/Serilog/Elasticsearch/AbpLoggingSerilogElasticsearchMapperProfile.cs
create mode 100644 modules/logging/Sanhe.Abp.Logging.Serilog.Elasticsearch/Sanhe/Abp/AuditLogging/Serilog/Elasticsearch/AbpLoggingSerilogElasticsearchModule.cs
create mode 100644 modules/logging/Sanhe.Abp.Logging.Serilog.Elasticsearch/Sanhe/Abp/AuditLogging/Serilog/Elasticsearch/AbpLoggingSerilogElasticsearchOptions.cs
create mode 100644 modules/logging/Sanhe.Abp.Logging.Serilog.Elasticsearch/Sanhe/Abp/AuditLogging/Serilog/Elasticsearch/SerilogElasticsearchLoggingManager.cs
create mode 100644 modules/logging/Sanhe.Abp.Logging.Serilog.Elasticsearch/Sanhe/Abp/AuditLogging/Serilog/Elasticsearch/SerilogException.cs
create mode 100644 modules/logging/Sanhe.Abp.Logging.Serilog.Elasticsearch/Sanhe/Abp/AuditLogging/Serilog/Elasticsearch/SerilogField.cs
create mode 100644 modules/logging/Sanhe.Abp.Logging.Serilog.Elasticsearch/Sanhe/Abp/AuditLogging/Serilog/Elasticsearch/SerilogInfo.cs
create mode 100644 modules/logging/Sanhe.Abp.Logging/FodyWeavers.xml
create mode 100644 modules/logging/Sanhe.Abp.Logging/README.md
create mode 100644 modules/logging/Sanhe.Abp.Logging/Sanhe.Abp.Logging.csproj
create mode 100644 modules/logging/Sanhe.Abp.Logging/Sanhe/Abp/Logging/AbpLoggingEnricherPropertyNames.cs
create mode 100644 modules/logging/Sanhe.Abp.Logging/Sanhe/Abp/Logging/AbpLoggingModule.cs
create mode 100644 modules/logging/Sanhe.Abp.Logging/Sanhe/Abp/Logging/DefaultLoggingManager.cs
create mode 100644 modules/logging/Sanhe.Abp.Logging/Sanhe/Abp/Logging/ILoggingManager.cs
create mode 100644 modules/logging/Sanhe.Abp.Logging/Sanhe/Abp/Logging/LogException.cs
create mode 100644 modules/logging/Sanhe.Abp.Logging/Sanhe/Abp/Logging/LogField.cs
create mode 100644 modules/logging/Sanhe.Abp.Logging/Sanhe/Abp/Logging/LogInfo.cs
create mode 100644 modules/logging/Sanhe.Abp.Serilog.Enrichers.Application/FodyWeavers.xml
create mode 100644 modules/logging/Sanhe.Abp.Serilog.Enrichers.Application/README.md
create mode 100644 modules/logging/Sanhe.Abp.Serilog.Enrichers.Application/Sanhe.Abp.Serilog.Enrichers.Application.csproj
create mode 100644 modules/logging/Sanhe.Abp.Serilog.Enrichers.Application/Sanhe/Abp/Serilog/Enrichers/Application/AbpSerilogEnrichersApplicationModule.cs
create mode 100644 modules/logging/Sanhe.Abp.Serilog.Enrichers.Application/Sanhe/Abp/Serilog/Enrichers/Application/AbpSerilogEnrichersConsts.cs
create mode 100644 modules/logging/Sanhe.Abp.Serilog.Enrichers.Application/Sanhe/Abp/Serilog/Enrichers/Application/ApplicationNameEnricher.cs
create mode 100644 modules/logging/Sanhe.Abp.Serilog.Enrichers.Application/Serilog/ApplicationLoggerConfigurationExtensions.cs
create mode 100644 modules/logging/Sanhe.Abp.Serilog.Enrichers.UniqueId/FodyWeavers.xml
create mode 100644 modules/logging/Sanhe.Abp.Serilog.Enrichers.UniqueId/Sanhe.Abp.Serilog.Enrichers.UniqueId.csproj
create mode 100644 modules/logging/Sanhe.Abp.Serilog.Enrichers.UniqueId/Sanhe/Abp/Serilog/Enrichers/UniqueId/AbpSerilogEnrichersUniqueIdModule.cs
create mode 100644 modules/logging/Sanhe.Abp.Serilog.Enrichers.UniqueId/Sanhe/Abp/Serilog/Enrichers/UniqueId/AbpSerilogEnrichersUniqueIdOptions.cs
create mode 100644 modules/logging/Sanhe.Abp.Serilog.Enrichers.UniqueId/Sanhe/Abp/Serilog/Enrichers/UniqueId/AbpSerilogUniqueIdConsts.cs
create mode 100644 modules/logging/Sanhe.Abp.Serilog.Enrichers.UniqueId/Sanhe/Abp/Serilog/Enrichers/UniqueId/UniqueIdEnricher.cs
create mode 100644 modules/logging/Sanhe.Abp.Serilog.Enrichers.UniqueId/Serilog/UniqueIdLoggerConfigurationExtensions.cs
diff --git a/Directory.Build.props b/Directory.Build.props
index a6ba50d..01c9358 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -5,5 +5,7 @@
6.0.*
1.9.7
7.15.1
+ 2.10.0
+ 8.4.1
\ No newline at end of file
diff --git a/Sanhe.Abp.Framework.sln b/Sanhe.Abp.Framework.sln
index eb6a0fd..38ff7bf 100644
--- a/Sanhe.Abp.Framework.sln
+++ b/Sanhe.Abp.Framework.sln
@@ -109,6 +109,28 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sanhe.Abp.MenuManagement.Ht
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "logging", "logging", "{56577207-AF97-4354-9C7A-ABBEE80FA1CA}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "auditing", "auditing", "{5BD41DAA-FBB1-4F52-A5D5-3C1D6A123645}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sanhe.Abp.Logging", "modules\logging\Sanhe.Abp.Logging\Sanhe.Abp.Logging.csproj", "{1E0D237A-070E-44A5-A2E5-B1EA3FF397C3}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sanhe.Abp.Serilog.Enrichers.UniqueId", "modules\logging\Sanhe.Abp.Serilog.Enrichers.UniqueId\Sanhe.Abp.Serilog.Enrichers.UniqueId.csproj", "{68056A12-29B7-41F5-9ABC-1E3BFFC5BF02}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sanhe.Abp.Serilog.Enrichers.Application", "modules\logging\Sanhe.Abp.Serilog.Enrichers.Application\Sanhe.Abp.Serilog.Enrichers.Application.csproj", "{3F2C7B9A-4145-42BF-9470-D7FCAF5D25A6}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sanhe.Abp.Logging.Serilog.Elasticsearch", "modules\logging\Sanhe.Abp.Logging.Serilog.Elasticsearch\Sanhe.Abp.Logging.Serilog.Elasticsearch.csproj", "{0DE6DCC3-48CA-4F2F-B6B1-88AA37B0208E}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sanhe.Abp.AuditLogging", "modules\auditing\Sanhe.Abp.AuditLogging\Sanhe.Abp.AuditLogging.csproj", "{11D7834B-EB00-4940-AB94-1835AACA0F13}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sanhe.Abp.AuditLogging.Elasticsearch", "modules\auditing\Sanhe.Abp.AuditLogging.Elasticsearch\Sanhe.Abp.AuditLogging.Elasticsearch.csproj", "{539069FD-3973-4DEB-A1EC-2BD25753698C}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sanhe.Abp.AuditLogging.EntityFrameworkCore", "modules\auditing\Sanhe.Abp.AuditLogging.EntityFrameworkCore\Sanhe.Abp.AuditLogging.EntityFrameworkCore.csproj", "{8B73A116-D859-439A-B3F0-BB8DE902D2D2}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sanhe.Abp.Auditing.Application.Contracts", "modules\auditing\Sanhe.Abp.Auditing.Application.Contracts\Sanhe.Abp.Auditing.Application.Contracts.csproj", "{D014ED3D-E73A-4AFB-873E-C50B81493C8B}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sanhe.Abp.Auditing.Application", "modules\auditing\Sanhe.Abp.Auditing.Application\Sanhe.Abp.Auditing.Application.csproj", "{58BE1EAE-9C41-4ED4-B4B9-4F8052B3E9D7}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sanhe.Abp.Auditing.HttpApi", "modules\auditing\Sanhe.Abp.Auditing.HttpApi\Sanhe.Abp.Auditing.HttpApi.csproj", "{A82C2175-AD0D-4AF5-B4F9-E264E47617C3}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -267,6 +289,46 @@ Global
{4A545053-9CD6-4578-92AF-1637AAC79F80}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4A545053-9CD6-4578-92AF-1637AAC79F80}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4A545053-9CD6-4578-92AF-1637AAC79F80}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1E0D237A-070E-44A5-A2E5-B1EA3FF397C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1E0D237A-070E-44A5-A2E5-B1EA3FF397C3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1E0D237A-070E-44A5-A2E5-B1EA3FF397C3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1E0D237A-070E-44A5-A2E5-B1EA3FF397C3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {68056A12-29B7-41F5-9ABC-1E3BFFC5BF02}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {68056A12-29B7-41F5-9ABC-1E3BFFC5BF02}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {68056A12-29B7-41F5-9ABC-1E3BFFC5BF02}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {68056A12-29B7-41F5-9ABC-1E3BFFC5BF02}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3F2C7B9A-4145-42BF-9470-D7FCAF5D25A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3F2C7B9A-4145-42BF-9470-D7FCAF5D25A6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3F2C7B9A-4145-42BF-9470-D7FCAF5D25A6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3F2C7B9A-4145-42BF-9470-D7FCAF5D25A6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0DE6DCC3-48CA-4F2F-B6B1-88AA37B0208E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0DE6DCC3-48CA-4F2F-B6B1-88AA37B0208E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0DE6DCC3-48CA-4F2F-B6B1-88AA37B0208E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0DE6DCC3-48CA-4F2F-B6B1-88AA37B0208E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {11D7834B-EB00-4940-AB94-1835AACA0F13}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {11D7834B-EB00-4940-AB94-1835AACA0F13}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {11D7834B-EB00-4940-AB94-1835AACA0F13}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {11D7834B-EB00-4940-AB94-1835AACA0F13}.Release|Any CPU.Build.0 = Release|Any CPU
+ {539069FD-3973-4DEB-A1EC-2BD25753698C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {539069FD-3973-4DEB-A1EC-2BD25753698C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {539069FD-3973-4DEB-A1EC-2BD25753698C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {539069FD-3973-4DEB-A1EC-2BD25753698C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8B73A116-D859-439A-B3F0-BB8DE902D2D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8B73A116-D859-439A-B3F0-BB8DE902D2D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8B73A116-D859-439A-B3F0-BB8DE902D2D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8B73A116-D859-439A-B3F0-BB8DE902D2D2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D014ED3D-E73A-4AFB-873E-C50B81493C8B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D014ED3D-E73A-4AFB-873E-C50B81493C8B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D014ED3D-E73A-4AFB-873E-C50B81493C8B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D014ED3D-E73A-4AFB-873E-C50B81493C8B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {58BE1EAE-9C41-4ED4-B4B9-4F8052B3E9D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {58BE1EAE-9C41-4ED4-B4B9-4F8052B3E9D7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {58BE1EAE-9C41-4ED4-B4B9-4F8052B3E9D7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {58BE1EAE-9C41-4ED4-B4B9-4F8052B3E9D7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A82C2175-AD0D-4AF5-B4F9-E264E47617C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A82C2175-AD0D-4AF5-B4F9-E264E47617C3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A82C2175-AD0D-4AF5-B4F9-E264E47617C3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A82C2175-AD0D-4AF5-B4F9-E264E47617C3}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -319,6 +381,17 @@ Global
{F60BA528-E8FE-465D-BAED-EAC48DE57847} = {1D9012F7-AAA3-49E0-9852-4A97FFB26E8C}
{4A545053-9CD6-4578-92AF-1637AAC79F80} = {1D9012F7-AAA3-49E0-9852-4A97FFB26E8C}
{56577207-AF97-4354-9C7A-ABBEE80FA1CA} = {F5F5D604-531B-4B57-A88E-C9C5CEEC55D7}
+ {5BD41DAA-FBB1-4F52-A5D5-3C1D6A123645} = {F5F5D604-531B-4B57-A88E-C9C5CEEC55D7}
+ {1E0D237A-070E-44A5-A2E5-B1EA3FF397C3} = {56577207-AF97-4354-9C7A-ABBEE80FA1CA}
+ {68056A12-29B7-41F5-9ABC-1E3BFFC5BF02} = {56577207-AF97-4354-9C7A-ABBEE80FA1CA}
+ {3F2C7B9A-4145-42BF-9470-D7FCAF5D25A6} = {56577207-AF97-4354-9C7A-ABBEE80FA1CA}
+ {0DE6DCC3-48CA-4F2F-B6B1-88AA37B0208E} = {56577207-AF97-4354-9C7A-ABBEE80FA1CA}
+ {11D7834B-EB00-4940-AB94-1835AACA0F13} = {5BD41DAA-FBB1-4F52-A5D5-3C1D6A123645}
+ {539069FD-3973-4DEB-A1EC-2BD25753698C} = {5BD41DAA-FBB1-4F52-A5D5-3C1D6A123645}
+ {8B73A116-D859-439A-B3F0-BB8DE902D2D2} = {5BD41DAA-FBB1-4F52-A5D5-3C1D6A123645}
+ {D014ED3D-E73A-4AFB-873E-C50B81493C8B} = {5BD41DAA-FBB1-4F52-A5D5-3C1D6A123645}
+ {58BE1EAE-9C41-4ED4-B4B9-4F8052B3E9D7} = {5BD41DAA-FBB1-4F52-A5D5-3C1D6A123645}
+ {A82C2175-AD0D-4AF5-B4F9-E264E47617C3} = {5BD41DAA-FBB1-4F52-A5D5-3C1D6A123645}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {AB69BFDE-9DDB-4D16-8CB8-72472C0319CD}
diff --git a/modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/FodyWeavers.xml b/modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/FodyWeavers.xml
new file mode 100644
index 0000000..1715698
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/FodyWeavers.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/README.md b/modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/README.md
new file mode 100644
index 0000000..3da5f31
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/README.md
@@ -0,0 +1,38 @@
+# LINGYUN.Abp.AuditLogging.Elasticsearch
+
+审计模块 Elasticsearch 实现
+
+ElasticsearchAuditLogManager 实现了 IAuditLogManager, 审计日志由ES管理
+ElasticsearchSecurityLogManager 实现了 ISecurityLogManager, 安全日志由ES管理
+
+## 模块引用
+
+
+```csharp
+[DependsOn(typeof(AbpAuditLoggingElasticsearchModule))]
+public class YouProjectModule : AbpModule
+{
+ // other
+}
+```
+
+## 配置项
+
+* AbpAuditLoggingElasticsearchOptions.IndexPrefix 索引前缀, 默认 auditlogging
+
+## 注意事项
+
+与租户模块集成, 跨租户时将会切换索引
+
+## appsettings.json
+
+```json
+{
+ "AuditLogging": {
+ "Elasticsearch": {
+ "IndexPrefix": "auditlogging"
+ }
+ }
+}
+
+```
\ No newline at end of file
diff --git a/modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe.Abp.AuditLogging.Elasticsearch.csproj b/modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe.Abp.AuditLogging.Elasticsearch.csproj
new file mode 100644
index 0000000..e895200
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe.Abp.AuditLogging.Elasticsearch.csproj
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+ netstandard2.0
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/AbpAuditLoggingElasticsearchModule.cs b/modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/AbpAuditLoggingElasticsearchModule.cs
new file mode 100644
index 0000000..eab799d
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/AbpAuditLoggingElasticsearchModule.cs
@@ -0,0 +1,22 @@
+using Sanhe.Abp.Elasticsearch;
+using Microsoft.Extensions.DependencyInjection;
+using Volo.Abp.Json;
+using Volo.Abp.Modularity;
+
+namespace Sanhe.Abp.AuditLogging.Elasticsearch
+{
+ [DependsOn(
+ typeof(AbpAuditLoggingModule),
+ typeof(AbpElasticsearchModule),
+ typeof(AbpJsonModule))]
+ public class AbpAuditLoggingElasticsearchModule : AbpModule
+ {
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ var configuration = context.Services.GetConfiguration();
+ Configure(configuration.GetSection("AuditLogging:Elasticsearch"));
+
+ context.Services.AddHostedService();
+ }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/AbpAuditLoggingElasticsearchOptions.cs b/modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/AbpAuditLoggingElasticsearchOptions.cs
new file mode 100644
index 0000000..f528bd3
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/AbpAuditLoggingElasticsearchOptions.cs
@@ -0,0 +1,17 @@
+using Nest;
+
+namespace Sanhe.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();
+ }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/AuditLogInfoToAuditLogConverter.cs b/modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/AuditLogInfoToAuditLogConverter.cs
new file mode 100644
index 0000000..c01dcdc
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/AuditLogInfoToAuditLogConverter.cs
@@ -0,0 +1,104 @@
+using Microsoft.Extensions.Options;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Volo.Abp.AspNetCore.ExceptionHandling;
+using Volo.Abp.Auditing;
+using Volo.Abp.Data;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.Guids;
+using Volo.Abp.Http;
+using Volo.Abp.Json;
+
+namespace Sanhe.Abp.AuditLogging.Elasticsearch
+{
+ public class AuditLogInfoToAuditLogConverter : IAuditLogInfoToAuditLogConverter, ITransientDependency
+ {
+ protected IGuidGenerator GuidGenerator { get; }
+ protected AbpExceptionHandlingOptions ExceptionHandlingOptions { get; }
+ protected IExceptionToErrorInfoConverter ExceptionToErrorInfoConverter { get; }
+ protected IJsonSerializer JsonSerializer { get; }
+
+ public AuditLogInfoToAuditLogConverter(
+ IGuidGenerator guidGenerator,
+ IOptions exceptionHandlingOptions,
+ IExceptionToErrorInfoConverter exceptionToErrorInfoConverter,
+ IJsonSerializer jsonSerializer)
+ {
+ GuidGenerator = guidGenerator;
+ ExceptionHandlingOptions = exceptionHandlingOptions.Value;
+ ExceptionToErrorInfoConverter = exceptionToErrorInfoConverter;
+ JsonSerializer = jsonSerializer;
+ }
+
+ public virtual Task ConvertAsync(AuditLogInfo auditLogInfo)
+ {
+ var auditLogId = GuidGenerator.Create();
+
+ var extraProperties = new ExtraPropertyDictionary();
+ if (auditLogInfo.ExtraProperties != null)
+ {
+ foreach (var pair in auditLogInfo.ExtraProperties)
+ {
+ extraProperties.Add(pair.Key, pair.Value);
+ }
+ }
+
+ var entityChanges = auditLogInfo
+ .EntityChanges?
+ .Select(entityChangeInfo => new EntityChange(GuidGenerator, auditLogId, entityChangeInfo, tenantId: auditLogInfo.TenantId))
+ .ToList()
+ ?? new List();
+
+ var actions = auditLogInfo
+ .Actions?
+ .Select(auditLogActionInfo => new AuditLogAction(GuidGenerator.Create(), auditLogId, auditLogActionInfo, tenantId: auditLogInfo.TenantId))
+ .ToList()
+ ?? new List();
+
+ var remoteServiceErrorInfos = auditLogInfo.Exceptions?.Select(exception =>
+ ExceptionToErrorInfoConverter.Convert(exception, options =>
+ {
+ options.SendExceptionsDetailsToClients = ExceptionHandlingOptions.SendExceptionsDetailsToClients;
+ options.SendStackTraceToClients = ExceptionHandlingOptions.SendStackTraceToClients;
+ })) ?? new List();
+
+ var exceptions = remoteServiceErrorInfos.Any()
+ ? JsonSerializer.Serialize(remoteServiceErrorInfos, indented: true)
+ : null;
+
+ var comments = auditLogInfo
+ .Comments?
+ .JoinAsString(Environment.NewLine);
+
+ var auditLog = new AuditLog(
+ auditLogId,
+ auditLogInfo.ApplicationName,
+ auditLogInfo.TenantId,
+ auditLogInfo.TenantName,
+ auditLogInfo.UserId,
+ auditLogInfo.UserName,
+ auditLogInfo.ExecutionTime,
+ auditLogInfo.ExecutionDuration,
+ auditLogInfo.ClientIpAddress,
+ auditLogInfo.ClientName,
+ auditLogInfo.ClientId,
+ auditLogInfo.CorrelationId,
+ auditLogInfo.BrowserInfo,
+ auditLogInfo.HttpMethod,
+ auditLogInfo.Url,
+ auditLogInfo.HttpStatusCode,
+ auditLogInfo.ImpersonatorUserId,
+ auditLogInfo.ImpersonatorTenantId,
+ extraProperties,
+ entityChanges,
+ actions,
+ exceptions,
+ comments
+ );
+
+ return Task.FromResult(auditLog);
+ }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/ElasticsearchAuditLogManager.cs b/modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/ElasticsearchAuditLogManager.cs
new file mode 100644
index 0000000..8701f07
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/ElasticsearchAuditLogManager.cs
@@ -0,0 +1,362 @@
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Logging.Abstractions;
+using Microsoft.Extensions.Options;
+using Nest;
+using Sanhe.Abp.Elasticsearch;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Threading;
+using System.Threading.Tasks;
+using Volo.Abp.Auditing;
+using Volo.Abp.DependencyInjection;
+
+namespace Sanhe.Abp.AuditLogging.Elasticsearch
+{
+ [Dependency(ReplaceServices = true)]
+ public class ElasticsearchAuditLogManager : IAuditLogManager, ITransientDependency
+ {
+ private readonly AbpAuditingOptions _auditingOptions;
+ private readonly AbpElasticsearchOptions _elasticsearchOptions;
+ private readonly IIndexNameNormalizer _indexNameNormalizer;
+ private readonly IElasticsearchClientFactory _clientFactory;
+ private readonly IAuditLogInfoToAuditLogConverter _converter;
+
+ public ILogger Logger { protected get; set; }
+
+ public ElasticsearchAuditLogManager(
+ IIndexNameNormalizer indexNameNormalizer,
+ IOptions elasticsearchOptions,
+ IElasticsearchClientFactory clientFactory,
+ IOptions auditingOptions,
+ IAuditLogInfoToAuditLogConverter converter)
+ {
+ _converter = converter;
+ _clientFactory = clientFactory;
+ _auditingOptions = auditingOptions.Value;
+ _elasticsearchOptions = elasticsearchOptions.Value;
+ _indexNameNormalizer = indexNameNormalizer;
+
+ Logger = NullLogger.Instance;
+ }
+
+
+ public virtual async Task GetCountAsync(
+ DateTime? startTime = null,
+ DateTime? endTime = null,
+ string httpMethod = null,
+ string url = null,
+ Guid? userId = null,
+ string userName = null,
+ string applicationName = null,
+ string correlationId = null,
+ string clientId = null,
+ string clientIpAddress = null,
+ int? maxExecutionDuration = null,
+ int? minExecutionDuration = null,
+ bool? hasException = null,
+ HttpStatusCode? httpStatusCode = null,
+ CancellationToken cancellationToken = default)
+ {
+ var client = _clientFactory.Create();
+
+ var querys = BuildQueryDescriptor(
+ startTime,
+ endTime,
+ httpMethod,
+ url,
+ userId,
+ userName,
+ applicationName,
+ correlationId,
+ clientId,
+ clientIpAddress,
+ maxExecutionDuration,
+ minExecutionDuration,
+ hasException,
+ httpStatusCode);
+
+ var response = await client.CountAsync(dsl =>
+ dsl.Index(CreateIndex())
+ .Query(log => log.Bool(b => b.Must(querys.ToArray()))),
+ cancellationToken);
+
+ return response.Count;
+ }
+
+ public virtual async Task> GetListAsync(
+ string sorting = null,
+ int maxResultCount = 50,
+ int skipCount = 0,
+ DateTime? startTime = null,
+ DateTime? endTime = null,
+ string httpMethod = null,
+ string url = null,
+ Guid? userId = null,
+ string userName = null,
+ string applicationName = null,
+ string correlationId = null,
+ string clientId = null,
+ string clientIpAddress = null,
+ int? maxExecutionDuration = null,
+ int? minExecutionDuration = null,
+ bool? hasException = null,
+ HttpStatusCode? httpStatusCode = null,
+ bool includeDetails = false,
+ CancellationToken cancellationToken = default)
+ {
+ var client = _clientFactory.Create();
+
+ var sortOrder = !sorting.IsNullOrWhiteSpace() && sorting.EndsWith("asc", StringComparison.InvariantCultureIgnoreCase)
+ ? SortOrder.Ascending : SortOrder.Descending;
+ sorting = !sorting.IsNullOrWhiteSpace()
+ ? sorting.Split()[0]
+ : nameof(AuditLog.ExecutionTime);
+
+ var querys = BuildQueryDescriptor(
+ startTime,
+ endTime,
+ httpMethod,
+ url,
+ userId,
+ userName,
+ applicationName,
+ correlationId,
+ clientId,
+ clientIpAddress,
+ maxExecutionDuration,
+ minExecutionDuration,
+ hasException,
+ httpStatusCode);
+
+ SourceFilterDescriptor SourceFilter(SourceFilterDescriptor selector)
+ {
+ selector.IncludeAll();
+ if (!includeDetails)
+ {
+ selector.Excludes(field =>
+ field.Field(f => f.Actions)
+ .Field(f => f.Comments)
+ .Field(f => f.Exceptions)
+ .Field(f => f.EntityChanges));
+ }
+
+ return selector;
+ }
+
+ var response = await client.SearchAsync(dsl =>
+ dsl.Index(CreateIndex())
+ .Query(log => log.Bool(b => b.Must(querys.ToArray())))
+ .Source(SourceFilter)
+ .Sort(log => log.Field(GetField(sorting), sortOrder))
+ .From(skipCount)
+ .Size(maxResultCount),
+ cancellationToken);
+
+ return response.Documents.ToList();
+ }
+
+ public virtual async Task GetAsync(
+ Guid id,
+ bool includeDetails = false,
+ CancellationToken cancellationToken = default)
+ {
+ var client = _clientFactory.Create();
+
+ var response = await client.GetAsync(
+ id,
+ dsl =>
+ dsl.Index(CreateIndex()),
+ cancellationToken);
+
+ return response.Source;
+ }
+
+ public virtual async Task DeleteAsync(Guid id, CancellationToken cancellationToken = default)
+ {
+ var client = _clientFactory.Create();
+
+ await client.DeleteAsync(
+ id,
+ dsl =>
+ dsl.Index(CreateIndex()),
+ cancellationToken);
+ }
+
+ public virtual async Task SaveAsync(
+ AuditLogInfo auditInfo,
+ CancellationToken cancellationToken = default)
+ {
+ if (!_auditingOptions.HideErrors)
+ {
+ return await SaveLogAsync(auditInfo, cancellationToken);
+ }
+
+ try
+ {
+ return await SaveLogAsync(auditInfo, cancellationToken);
+ }
+ catch (Exception ex)
+ {
+ Logger.LogWarning("Could not save the audit log object: " + Environment.NewLine + auditInfo.ToString());
+ Logger.LogException(ex, Microsoft.Extensions.Logging.LogLevel.Error);
+ }
+ return "";
+ }
+
+ protected virtual async Task SaveLogAsync(
+ AuditLogInfo auditLogInfo,
+ CancellationToken cancellationToken = default)
+ {
+ var client = _clientFactory.Create();
+
+ var auditLog = await _converter.ConvertAsync(auditLogInfo);
+
+ var response = await client.IndexAsync(
+ auditLog,
+ (x) => x.Index(CreateIndex())
+ .Id(auditLog.Id),
+ cancellationToken);
+
+ return response.Id;
+ }
+
+ protected virtual List, QueryContainer>> BuildQueryDescriptor(
+ DateTime? startTime = null,
+ DateTime? endTime = null,
+ string httpMethod = null,
+ string url = null,
+ Guid? userId = null,
+ string userName = null,
+ string applicationName = null,
+ string correlationId = null,
+ string clientId = null,
+ string clientIpAddress = null,
+ int? maxExecutionDuration = null,
+ int? minExecutionDuration = null,
+ bool? hasException = null,
+ HttpStatusCode? httpStatusCode = null)
+ {
+ var querys = new List, QueryContainer>>();
+
+ if (startTime.HasValue)
+ {
+ querys.Add((log) => log.DateRange((q) => q.Field(GetField(nameof(AuditLog.ExecutionTime))).GreaterThanOrEquals(startTime)));
+ }
+ if (endTime.HasValue)
+ {
+ querys.Add((log) => log.DateRange((q) => q.Field(GetField(nameof(AuditLog.ExecutionTime))).LessThanOrEquals(endTime)));
+ }
+ if (!httpMethod.IsNullOrWhiteSpace())
+ {
+ querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(AuditLog.HttpMethod))).Value(httpMethod)));
+ }
+ if (!url.IsNullOrWhiteSpace())
+ {
+ querys.Add((log) => log.Wildcard((q) => q.Field(GetField(nameof(AuditLog.Url))).Value($"*{url}*")));
+ }
+ if (userId.HasValue)
+ {
+ querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(AuditLog.UserId))).Value(userId)));
+ }
+ if (!userName.IsNullOrWhiteSpace())
+ {
+ querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(AuditLog.UserName))).Value(userName)));
+ }
+ if (!applicationName.IsNullOrWhiteSpace())
+ {
+ querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(AuditLog.ApplicationName))).Value(applicationName)));
+ }
+ if (!correlationId.IsNullOrWhiteSpace())
+ {
+ querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(AuditLog.CorrelationId))).Value(correlationId)));
+ }
+ if (!clientId.IsNullOrWhiteSpace())
+ {
+ querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(AuditLog.ClientId))).Value(clientId)));
+ }
+ if (!clientIpAddress.IsNullOrWhiteSpace())
+ {
+ querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(AuditLog.ClientIpAddress))).Value(clientIpAddress)));
+ }
+ if (maxExecutionDuration.HasValue)
+ {
+ querys.Add((log) => log.Range((q) => q.Field(GetField(nameof(AuditLog.ExecutionDuration))).LessThanOrEquals(maxExecutionDuration)));
+ }
+ if (minExecutionDuration.HasValue)
+ {
+ querys.Add((log) => log.Range((q) => q.Field(GetField(nameof(AuditLog.ExecutionDuration))).GreaterThanOrEquals(minExecutionDuration)));
+ }
+
+
+ if (hasException.HasValue)
+ {
+ if (hasException.Value)
+ {
+ querys.Add(
+ (q) => q.Bool(
+ (b) => b.Must(
+ (m) => m.Exists(
+ (e) => e.Field((f) => f.Exceptions)))
+ )
+ );
+ }
+ else
+ {
+ querys.Add(
+ (q) => q.Bool(
+ (b) => b.MustNot(
+ (mn) => mn.Exists(
+ (e) => e.Field(
+ (f) => f.Exceptions)))
+ )
+ );
+ }
+ }
+
+ if (httpStatusCode.HasValue)
+ {
+ querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(AuditLog.HttpStatusCode))).Value(httpStatusCode)));
+ }
+
+ return querys;
+ }
+
+ protected virtual string CreateIndex()
+ {
+ return _indexNameNormalizer.NormalizeIndex("audit-log");
+ }
+
+ private readonly static IDictionary _fieldMaps = new Dictionary(StringComparer.InvariantCultureIgnoreCase)
+ {
+ { "Id", "Id.keyword" },
+ { "ApplicationName", "ApplicationName.keyword" },
+ { "UserId", "UserId.keyword" },
+ { "UserName", "UserName.keyword" },
+ { "TenantId", "TenantId.keyword" },
+ { "TenantName", "TenantName.keyword" },
+ { "ImpersonatorUserId", "ImpersonatorUserId.keyword" },
+ { "ImpersonatorTenantId", "ImpersonatorTenantId.keyword" },
+ { "ClientName", "ClientName.keyword" },
+ { "ClientIpAddress", "ClientIpAddress.keyword" },
+ { "ClientId", "ClientId.keyword" },
+ { "CorrelationId", "CorrelationId.keyword" },
+ { "BrowserInfo", "BrowserInfo.keyword" },
+ { "HttpMethod", "HttpMethod.keyword" },
+ { "Url", "Url.keyword" },
+ { "ExecutionDuration", "ExecutionDuration" },
+ { "ExecutionTime", "ExecutionTime" },
+ { "HttpStatusCode", "HttpStatusCode" },
+ };
+ protected virtual string GetField(string field)
+ {
+ if (_fieldMaps.TryGetValue(field, out var mapField))
+ {
+ return _elasticsearchOptions.FieldCamelCase ? mapField.ToCamelCase() : mapField.ToPascalCase();
+ }
+
+ return _elasticsearchOptions.FieldCamelCase ? field.ToCamelCase() : field.ToPascalCase();
+ }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/ElasticsearchEntityChangeStore.cs b/modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/ElasticsearchEntityChangeStore.cs
new file mode 100644
index 0000000..97828c0
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/ElasticsearchEntityChangeStore.cs
@@ -0,0 +1,371 @@
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Logging.Abstractions;
+using Microsoft.Extensions.Options;
+using Nest;
+using Sanhe.Abp.Elasticsearch;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Volo.Abp.Auditing;
+using Volo.Abp.DependencyInjection;
+
+namespace Sanhe.Abp.AuditLogging.Elasticsearch;
+
+[Dependency(ReplaceServices = true)]
+public class ElasticsearchEntityChangeStore : IEntityChangeStore, ITransientDependency
+{
+ private readonly AbpElasticsearchOptions _elasticsearchOptions;
+ private readonly IIndexNameNormalizer _indexNameNormalizer;
+ private readonly IElasticsearchClientFactory _clientFactory;
+
+ public ILogger Logger { protected get; set; }
+
+ public ElasticsearchEntityChangeStore(
+ IIndexNameNormalizer indexNameNormalizer,
+ IElasticsearchClientFactory clientFactory,
+ IOptions elasticsearchOptions)
+ {
+ _clientFactory = clientFactory;
+ _indexNameNormalizer = indexNameNormalizer;
+ _elasticsearchOptions = elasticsearchOptions.Value;
+
+ Logger = NullLogger.Instance;
+ }
+
+ public async virtual Task GetAsync(
+ Guid entityChangeId,
+ CancellationToken cancellationToken = default)
+ {
+ var client = _clientFactory.Create();
+
+ var resposne = await client.SearchAsync(
+ dsl => dsl.Index(CreateIndex())
+ .Query(query =>
+ query.Bool(bo =>
+ bo.Must(m =>
+ m.Nested(n =>
+ n.InnerHits()
+ .Path("EntityChanges")
+ .Query(nq =>
+ nq.Term(nqt =>
+ nqt.Field(GetField(nameof(EntityChange.Id))).Value(entityChangeId)))))))
+ .Source(x => x.Excludes(f => f.Field("*")))
+ .Sort(entity => entity.Field("EntityChanges.ChangeTime", SortOrder.Descending))
+ .Size(1),
+ ct: cancellationToken);
+
+ if (resposne.Shards.Successful > 0)
+ {
+ var hits = resposne.Hits.FirstOrDefault();
+ if (hits.InnerHits.Count > 0)
+ {
+ return hits.InnerHits.First().Value.Documents().FirstOrDefault();
+ }
+ }
+
+ return null;
+ }
+
+ public async virtual Task GetCountAsync(
+ Guid? auditLogId = null,
+ DateTime? startTime = null,
+ DateTime? endTime = null,
+ EntityChangeType? changeType = null,
+ string entityId = null,
+ string entityTypeFullName = null,
+ CancellationToken cancellationToken = default)
+ {
+ await Task.CompletedTask;
+ return 0;
+ //var client = _clientFactory.Create();
+
+ //var querys = BuildQueryDescriptor(
+ // auditLogId,
+ // startTime,
+ // endTime,
+ // changeType,
+ // entityId,
+ // entityTypeFullName);
+
+ //Func, QueryContainer> selector = q => q.MatchAll();
+ //if (querys.Count > 0)
+ //{
+ // selector = q => q.Bool(b => b.Must(querys.ToArray()));
+ //}
+
+ //var response = await client.CountAsync(dsl =>
+ // dsl.Index(CreateIndex())
+ // .Query(q =>
+ // q.Bool(b =>
+ // b.Must(m =>
+ // m.Nested(n =>
+ // n.InnerHits(hit => hit.Source(s => s.ExcludeAll()))
+ // .Path("EntityChanges")
+ // .Query(selector)
+ // )
+ // )
+ // )
+ // ),
+ // ct: cancellationToken);
+
+ //return response.Count;
+ }
+
+ public async virtual Task> 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)
+ {
+ // TODO: 需要解决Nested格式数据返回方式
+
+ //var client = _clientFactory.Create();
+
+ //var sortOrder = !sorting.IsNullOrWhiteSpace() && sorting.EndsWith("asc", StringComparison.InvariantCultureIgnoreCase)
+ // ? SortOrder.Ascending : SortOrder.Descending;
+ //sorting = !sorting.IsNullOrWhiteSpace()
+ // ? sorting.Split()[0]
+ // : nameof(EntityChange.ChangeTime);
+
+ //var querys = BuildQueryDescriptor(
+ // auditLogId,
+ // startTime,
+ // endTime,
+ // changeType,
+ // entityId,
+ // entityTypeFullName);
+
+ //SourceFilterDescriptor SourceFilter(SourceFilterDescriptor selector)
+ //{
+ // selector.Includes(GetEntityChangeSources());
+ // if (!includeDetails)
+ // {
+ // selector.Excludes(field =>
+ // field.Field("EntityChanges.PropertyChanges")
+ // .Field("EntityChanges.ExtraProperties"));
+ // }
+
+ // return selector;
+ //}
+
+ //Func, QueryContainer> selector = q => q.MatchAll();
+ //if (querys.Count > 0)
+ //{
+ // selector = q => q.Bool(b => b.Must(querys.ToArray()));
+ //}
+
+ //var response = await client.SearchAsync(dsl =>
+ // dsl.Index(CreateIndex())
+ // .Query(q =>
+ // q.Bool(b =>
+ // b.Must(m =>
+ // m.Nested(n =>
+ // n.InnerHits(hit => hit.Source(SourceFilter))
+ // .Path("EntityChanges")
+ // .Query(selector)
+ // )
+ // )
+ // )
+ // )
+ // .Source(x => x.Excludes(f => f.Field("*")))
+ // .Sort(entity => entity.Field(GetField(sorting), sortOrder))
+ // .From(skipCount)
+ // .Size(maxResultCount),
+ // cancellationToken);
+
+ //if (response.Shards.Successful > 0)
+ //{
+ // var hits = response.Hits.FirstOrDefault();
+ // if (hits.InnerHits.Count > 0)
+ // {
+ // return hits.InnerHits.First().Value.Documents().ToList();
+ // }
+ //}
+ await Task.CompletedTask;
+ return new List();
+ }
+
+ public async virtual Task GetWithUsernameAsync(
+ Guid entityChangeId,
+ CancellationToken cancellationToken = default)
+ {
+ var client = _clientFactory.Create();
+
+ var response = await client.SearchAsync(
+ dsl => dsl.Index(CreateIndex())
+ .Query(query =>
+ query.Bool(bo =>
+ bo.Must(m =>
+ m.Nested(n =>
+ n.InnerHits()
+ .Path("EntityChanges")
+ .Query(nq =>
+ nq.Bool(nb =>
+ nb.Must(nm =>
+ nm.Term(nt =>
+ nt.Field(GetField(nameof(EntityChange.Id))).Value(entityChangeId)))))))))
+ .Source(selector => selector.Includes(field =>
+ field.Field(f => f.UserName)))
+ .Size(1),
+ ct: cancellationToken);
+
+ var auditLog = response.Documents.FirstOrDefault();
+ EntityChange entityChange = null;
+
+ if (response.Shards.Successful > 0)
+ {
+ var hits = response.Hits.FirstOrDefault();
+ if (hits.InnerHits.Count > 0)
+ {
+ entityChange = hits.InnerHits.First().Value.Documents().FirstOrDefault();
+ }
+ }
+
+ return new EntityChangeWithUsername()
+ {
+ EntityChange = entityChange,
+ UserName = auditLog?.UserName
+ };
+ }
+
+ public async virtual Task> GetWithUsernameAsync(
+ string entityId,
+ string entityTypeFullName,
+ CancellationToken cancellationToken = default)
+ {
+ var client = _clientFactory.Create();
+
+ var response = await client.SearchAsync(
+ dsl => dsl.Index(CreateIndex())
+ .Query(query =>
+ query.Bool(bo =>
+ bo.Must(m =>
+ m.Nested(n =>
+ n.InnerHits()
+ .Path("EntityChanges")
+ .Query(nq =>
+ nq.Bool(nb =>
+ nb.Must(nm =>
+ nm.Term(nt =>
+ nt.Field(GetField(nameof(EntityChange.EntityId))).Value(entityId)),
+ nm =>
+ nm.Term(nt =>
+ nt.Field(GetField(nameof(EntityChange.EntityTypeFullName))).Value(entityTypeFullName))
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ .Source(selector => selector.Includes(field =>
+ field.Field(f => f.UserName)))
+ .Sort(entity => entity.Field(f => f.ExecutionTime, SortOrder.Descending)),
+ ct: cancellationToken);
+
+ if (response.Hits.Count > 0)
+ {
+ return response.Hits.
+ Select(hit => new EntityChangeWithUsername
+ {
+ UserName = hit.Source.UserName,
+ EntityChange = hit.InnerHits.Any() ?
+ hit.InnerHits.First().Value.Documents().FirstOrDefault()
+ : null
+ })
+ .ToList();
+ }
+
+ return new List();
+ }
+
+ protected virtual List, QueryContainer>> BuildQueryDescriptor(
+ Guid? auditLogId = null,
+ DateTime? startTime = null,
+ DateTime? endTime = null,
+ EntityChangeType? changeType = null,
+ string entityId = null,
+ string entityTypeFullName = null)
+ {
+ var querys = new List, QueryContainer>>();
+
+ if (auditLogId.HasValue)
+ {
+ querys.Add(entity => entity.Term(q => q.Field(GetField(nameof(EntityChange.AuditLogId))).Value(auditLogId)));
+ }
+ if (startTime.HasValue)
+ {
+ querys.Add(entity => entity.DateRange(q => q.Field(GetField(nameof(EntityChange.ChangeTime))).GreaterThanOrEquals(startTime)));
+ }
+ if (endTime.HasValue)
+ {
+ querys.Add(entity => entity.DateRange(q => q.Field(GetField(nameof(EntityChange.ChangeTime))).LessThanOrEquals(endTime)));
+ }
+ if (changeType.HasValue)
+ {
+ querys.Add(entity => entity.Term(q => q.Field(GetField(nameof(EntityChange.ChangeType))).Value(changeType)));
+ }
+ if (!entityId.IsNullOrWhiteSpace())
+ {
+ querys.Add(entity => entity.Term(q => q.Field(GetField(nameof(EntityChange.EntityId))).Value(entityId)));
+ }
+ if (!entityTypeFullName.IsNullOrWhiteSpace())
+ {
+ querys.Add(entity => entity.Wildcard(q => q.Field(GetField(nameof(EntityChange.EntityTypeFullName))).Value($"*{entityTypeFullName}*")));
+ }
+
+ return querys;
+ }
+
+ protected virtual string CreateIndex()
+ {
+ return _indexNameNormalizer.NormalizeIndex("audit-log");
+ }
+
+ protected Func, IPromise> GetEntityChangeSources()
+ {
+ return field => field
+ .Field("EntityChanges.Id")
+ .Field("EntityChanges.AuditLogId")
+ .Field("EntityChanges.TenantId")
+ .Field("EntityChanges.ChangeTime")
+ .Field("EntityChanges.ChangeType")
+ .Field("EntityChanges.EntityTenantId")
+ .Field("EntityChanges.EntityId")
+ .Field("EntityChanges.EntityTypeFullName")
+ .Field("EntityChanges.PropertyChanges")
+ .Field("EntityChanges.ExtraProperties");
+ }
+
+ private readonly static IDictionary _fieldMaps = new Dictionary(StringComparer.InvariantCultureIgnoreCase)
+ {
+ { "Id", "EntityChanges.Id.keyword" },
+ { "AuditLogId", "EntityChanges.AuditLogId.keyword" },
+ { "TenantId", "EntityChanges.TenantId.keyword" },
+ { "EntityTenantId", "EntityChanges.EntityTenantId.keyword" },
+ { "EntityId", "EntityChanges.EntityId.keyword" },
+ { "EntityTypeFullName", "EntityChanges.EntityTypeFullName.keyword" },
+ { "PropertyChanges", "EntityChanges.PropertyChanges" },
+ { "ExtraProperties", "EntityChanges.ExtraProperties" },
+ { "ChangeType", "EntityChanges.ChangeType" },
+ { "ChangeTime", "EntityChanges.ChangeTime" },
+ };
+ protected virtual string GetField(string field)
+ {
+ if (_fieldMaps.TryGetValue(field, out var mapField))
+ {
+ return _elasticsearchOptions.FieldCamelCase ? mapField.ToCamelCase() : mapField.ToPascalCase();
+ }
+
+ return _elasticsearchOptions.FieldCamelCase ? field.ToCamelCase() : field.ToPascalCase();
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/ElasticsearchSecurityLogManager.cs b/modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/ElasticsearchSecurityLogManager.cs
new file mode 100644
index 0000000..5caea63
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/ElasticsearchSecurityLogManager.cs
@@ -0,0 +1,268 @@
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Logging.Abstractions;
+using Microsoft.Extensions.Options;
+using Nest;
+using Sanhe.Abp.Elasticsearch;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.Guids;
+using Volo.Abp.SecurityLog;
+
+namespace Sanhe.Abp.AuditLogging.Elasticsearch
+{
+ [Dependency(ReplaceServices = true)]
+ public class ElasticsearchSecurityLogManager : ISecurityLogManager, ITransientDependency
+ {
+ private readonly AbpSecurityLogOptions _securityLogOptions;
+ private readonly AbpElasticsearchOptions _elasticsearchOptions;
+ private readonly IIndexNameNormalizer _indexNameNormalizer;
+ private readonly IGuidGenerator _guidGenerator;
+ private readonly IElasticsearchClientFactory _clientFactory;
+
+ public ILogger Logger { protected get; set; }
+
+ public ElasticsearchSecurityLogManager(
+ IGuidGenerator guidGenerator,
+ IIndexNameNormalizer indexNameNormalizer,
+ IOptions securityLogOptions,
+ IOptions elasticsearchOptions,
+ IElasticsearchClientFactory clientFactory)
+ {
+ _guidGenerator = guidGenerator;
+ _clientFactory = clientFactory;
+ _indexNameNormalizer = indexNameNormalizer;
+ _securityLogOptions = securityLogOptions.Value;
+ _elasticsearchOptions = elasticsearchOptions.Value;
+
+ Logger = NullLogger.Instance;
+ }
+
+ public virtual async Task SaveAsync(
+ SecurityLogInfo securityLogInfo,
+ CancellationToken cancellationToken = default)
+ {
+ // TODO: 框架不把这玩意儿放在 ISecurityLogManager?
+ if (!_securityLogOptions.IsEnabled)
+ {
+ return;
+ }
+
+ var client = _clientFactory.Create();
+
+ var securityLog = new SecurityLog(
+ _guidGenerator.Create(),
+ securityLogInfo);
+
+ await client.IndexAsync(
+ securityLog,
+ (x) => x.Index(CreateIndex())
+ .Id(securityLog.Id),
+ cancellationToken);
+ }
+
+ public virtual async Task GetAsync(
+ Guid id,
+ bool includeDetails = false,
+ CancellationToken cancellationToken = default)
+ {
+ var client = _clientFactory.Create();
+
+ var response = await client.GetAsync(
+ id,
+ dsl =>
+ dsl.Index(CreateIndex()),
+ cancellationToken);
+
+ return response.Source;
+ }
+
+ public virtual async Task DeleteAsync(Guid id, CancellationToken cancellationToken = default)
+ {
+ var client = _clientFactory.Create();
+
+ await client.DeleteAsync(
+ id,
+ dsl =>
+ dsl.Index(CreateIndex()),
+ cancellationToken);
+ }
+
+ public virtual async Task> GetListAsync(
+ string sorting = null,
+ int maxResultCount = 50,
+ int skipCount = 0,
+ DateTime? startTime = null,
+ DateTime? endTime = null,
+ string applicationName = null,
+ string identity = null,
+ string action = null,
+ Guid? userId = null,
+ string userName = null,
+ string clientId = null,
+ string clientIpAddress = null,
+ string correlationId = null,
+ bool includeDetails = false,
+ CancellationToken cancellationToken = default)
+ {
+ var client = _clientFactory.Create();
+
+ var sortOrder = !sorting.IsNullOrWhiteSpace() && sorting.EndsWith("asc", StringComparison.InvariantCultureIgnoreCase)
+ ? SortOrder.Ascending : SortOrder.Descending;
+ sorting = !sorting.IsNullOrWhiteSpace()
+ ? sorting.Split()[0]
+ : nameof(SecurityLog.CreationTime);
+
+ var querys = BuildQueryDescriptor(
+ startTime,
+ endTime,
+ applicationName,
+ identity,
+ action,
+ userId,
+ userName,
+ clientId,
+ clientIpAddress,
+ correlationId);
+
+ var response = await client.SearchAsync(dsl =>
+ dsl.Index(CreateIndex())
+ .Query(log => log.Bool(b => b.Must(querys.ToArray())))
+ .Source(log => log.IncludeAll())
+ .Sort(log => log.Field(GetField(sorting), sortOrder))
+ .From(skipCount)
+ .Size(maxResultCount),
+ cancellationToken);
+
+ return response.Documents.ToList();
+ }
+
+
+ public virtual async Task GetCountAsync(
+ DateTime? startTime = null,
+ DateTime? endTime = null,
+ string applicationName = null,
+ string identity = null,
+ string action = null,
+ Guid? userId = null,
+ string userName = null,
+ string clientId = null,
+ string clientIpAddress = null,
+ string correlationId = null,
+ CancellationToken cancellationToken = default)
+ {
+ var client = _clientFactory.Create();
+
+ var querys = BuildQueryDescriptor(
+ startTime,
+ endTime,
+ applicationName,
+ identity,
+ action,
+ userId,
+ userName,
+ clientId,
+ clientIpAddress,
+ correlationId);
+
+ var response = await client.CountAsync(dsl =>
+ dsl.Index(CreateIndex())
+ .Query(log => log.Bool(b => b.Must(querys.ToArray()))),
+ cancellationToken);
+
+ return response.Count;
+ }
+
+ protected virtual List, QueryContainer>> BuildQueryDescriptor(
+ DateTime? startTime = null,
+ DateTime? endTime = null,
+ string applicationName = null,
+ string identity = null,
+ string action = null,
+ Guid? userId = null,
+ string userName = null,
+ string clientId = null,
+ string clientIpAddress = null,
+ string correlationId = null)
+ {
+ var querys = new List, QueryContainer>>();
+
+ if (startTime.HasValue)
+ {
+ querys.Add((log) => log.DateRange((q) => q.Field(GetField(nameof(SecurityLog.CreationTime))).GreaterThanOrEquals(startTime)));
+ }
+ if (endTime.HasValue)
+ {
+ querys.Add((log) => log.DateRange((q) => q.Field(GetField(nameof(SecurityLog.CreationTime))).LessThanOrEquals(endTime)));
+ }
+ if (!applicationName.IsNullOrWhiteSpace())
+ {
+ querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(SecurityLog.ApplicationName))).Value(applicationName)));
+ }
+ if (!identity.IsNullOrWhiteSpace())
+ {
+ querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(SecurityLog.Identity))).Value(identity)));
+ }
+ if (!action.IsNullOrWhiteSpace())
+ {
+ querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(SecurityLog.Action))).Value(action)));
+ }
+ if (userId.HasValue)
+ {
+ querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(SecurityLog.UserId))).Value(userId)));
+ }
+ if (!userName.IsNullOrWhiteSpace())
+ {
+ querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(SecurityLog.UserName))).Value(userName)));
+ }
+ if (!clientId.IsNullOrWhiteSpace())
+ {
+ querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(SecurityLog.ClientId))).Value(clientId)));
+ }
+ if (!clientIpAddress.IsNullOrWhiteSpace())
+ {
+ querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(SecurityLog.ClientIpAddress))).Value(clientIpAddress)));
+ }
+ if (!correlationId.IsNullOrWhiteSpace())
+ {
+ querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(SecurityLog.CorrelationId))).Value(correlationId)));
+ }
+
+ return querys;
+ }
+
+ protected virtual string CreateIndex()
+ {
+ return _indexNameNormalizer.NormalizeIndex("security-log");
+ }
+
+ private readonly static IDictionary _fieldMaps = new Dictionary(StringComparer.InvariantCultureIgnoreCase)
+ {
+ { "Id", "Id.keyword" },
+ { "ApplicationName", "ApplicationName.keyword" },
+ { "UserId", "UserId.keyword" },
+ { "UserName", "UserName.keyword" },
+ { "TenantId", "TenantId.keyword" },
+ { "TenantName", "TenantName.keyword" },
+ { "Identity", "Identity.keyword" },
+ { "Action", "Action.keyword" },
+ { "BrowserInfo", "BrowserInfo.keyword" },
+ { "ClientIpAddress", "ClientIpAddress.keyword" },
+ { "ClientId", "ClientId.keyword" },
+ { "CorrelationId", "CorrelationId.keyword" },
+ { "CreationTime", "CreationTime" },
+ };
+ protected virtual string GetField(string field)
+ {
+ if (_fieldMaps.TryGetValue(field, out var mapField))
+ {
+ return _elasticsearchOptions.FieldCamelCase ? mapField.ToCamelCase() : mapField.ToPascalCase();
+ }
+
+ return _elasticsearchOptions.FieldCamelCase ? field.ToCamelCase() : field.ToPascalCase();
+ }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/IAuditLogInfoToAuditLogConverter.cs b/modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/IAuditLogInfoToAuditLogConverter.cs
new file mode 100644
index 0000000..5e56c7b
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/IAuditLogInfoToAuditLogConverter.cs
@@ -0,0 +1,10 @@
+using System.Threading.Tasks;
+using Volo.Abp.Auditing;
+
+namespace Sanhe.Abp.AuditLogging.Elasticsearch
+{
+ public interface IAuditLogInfoToAuditLogConverter
+ {
+ Task ConvertAsync(AuditLogInfo auditLogInfo);
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/IIndexInitializer.cs b/modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/IIndexInitializer.cs
new file mode 100644
index 0000000..6828c5e
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/IIndexInitializer.cs
@@ -0,0 +1,9 @@
+using System.Threading.Tasks;
+
+namespace Sanhe.Abp.AuditLogging.Elasticsearch
+{
+ public interface IIndexInitializer
+ {
+ Task InitializeAsync();
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/IIndexNameNormalizer.cs b/modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/IIndexNameNormalizer.cs
new file mode 100644
index 0000000..d36169c
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/IIndexNameNormalizer.cs
@@ -0,0 +1,7 @@
+namespace Sanhe.Abp.AuditLogging.Elasticsearch
+{
+ public interface IIndexNameNormalizer
+ {
+ string NormalizeIndex(string index);
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/IndexInitializer.cs b/modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/IndexInitializer.cs
new file mode 100644
index 0000000..20c0633
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/IndexInitializer.cs
@@ -0,0 +1,107 @@
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Logging.Abstractions;
+using Microsoft.Extensions.Options;
+using Nest;
+using Sanhe.Abp.Elasticsearch;
+using System;
+using System.Threading.Tasks;
+using Volo.Abp.Data;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.Json;
+
+namespace Sanhe.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 Logger { protected get; set; }
+
+ public IndexInitializer(
+ IOptions jsonOptions,
+ IOptions elasticsearchOptions,
+ IIndexNameNormalizer nameNormalizer,
+ IElasticsearchClientFactory clientFactory)
+ {
+ _jsonOptions = jsonOptions.Value;
+ _elasticsearchOptions = elasticsearchOptions.Value;
+ _nameNormalizer = nameNormalizer;
+ _clientFactory = clientFactory;
+
+ Logger = NullLogger.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(map =>
+ map.AutoMap()
+ .Properties(mp =>
+ mp.Date(p => p.Name(n => n.ExecutionTime).Format(dateTimeFormat))
+ .Object(p => p.Name(n => n.ExtraProperties))
+ .Nested(n =>
+ n.AutoMap()
+ .Name(nameof(AuditLog.EntityChanges))
+ .Properties(np =>
+ np.Object(p => p.Name(n => n.ExtraProperties))
+ .Date(p => p.Name(n => n.ChangeTime).Format(dateTimeFormat))
+ .Nested(npn => npn.Name(nameof(EntityChange.PropertyChanges)))))
+ .Nested(n => n.Name(nameof(AuditLog.Actions))
+ .AutoMap()
+ .Properties(np =>
+ np.Object(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(map =>
+ map.AutoMap()
+ .Properties(mp =>
+ mp.Object(p => p.Name(n => n.ExtraProperties))
+ .Date(p => p.Name(n => n.CreationTime).Format(dateTimeFormat)))));
+ if (!indexCreateResponse.IsValid)
+ {
+ Logger.LogWarning("Failed to initialize index and security log may not be retrieved.");
+ Logger.LogWarning(indexCreateResponse.OriginalException.ToString());
+ }
+ }
+ }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/IndexInitializerService.cs b/modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/IndexInitializerService.cs
new file mode 100644
index 0000000..626823e
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/IndexInitializerService.cs
@@ -0,0 +1,21 @@
+using Microsoft.Extensions.Hosting;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Sanhe.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();
+ }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/IndexNameNormalizer.cs b/modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/IndexNameNormalizer.cs
new file mode 100644
index 0000000..ab4eaaf
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.AuditLogging.Elasticsearch/Sanhe/Abp/AuditLogging/Elasticsearch/IndexNameNormalizer.cs
@@ -0,0 +1,30 @@
+using Microsoft.Extensions.Options;
+using System;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.MultiTenancy;
+
+namespace Sanhe.Abp.AuditLogging.Elasticsearch
+{
+ public class IndexNameNormalizer : IIndexNameNormalizer, ISingletonDependency
+ {
+ private readonly ICurrentTenant _currentTenant;
+ private readonly AbpAuditLoggingElasticsearchOptions _options;
+
+ public IndexNameNormalizer(ICurrentTenant currentTenant, IOptions 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}";
+ }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.AuditLogging.EntityFrameworkCore/FodyWeavers.xml b/modules/auditing/Sanhe.Abp.AuditLogging.EntityFrameworkCore/FodyWeavers.xml
new file mode 100644
index 0000000..1715698
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.AuditLogging.EntityFrameworkCore/FodyWeavers.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/modules/auditing/Sanhe.Abp.AuditLogging.EntityFrameworkCore/README.md b/modules/auditing/Sanhe.Abp.AuditLogging.EntityFrameworkCore/README.md
new file mode 100644
index 0000000..8be6bfd
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.AuditLogging.EntityFrameworkCore/README.md
@@ -0,0 +1,32 @@
+# LINGYUN.Abp.AuditLogging.EntityFrameworkCore
+
+审计模块 EntityFrameworkCore 实现, 此模块仅作为桥梁, 具体实现交给abp官方模块
+
+AuditLogManager 实现了 IAuditLogManager, 审计日志由Volo.Abp.AuditLogging模块管理
+SecurityLogManager 实现了 ISecurityLogManager, 安全日志由Volo.Abp.Identity模块管理
+
+## 模块引用
+
+```csharp
+[DependsOn(typeof(AbpAuditLoggingEntityFrameworkCoreModule))]
+public class YouProjectModule : AbpModule
+{
+ // other
+}
+```
+
+## 配置项
+
+请遵循 Volo.Abp.AuditLogging、Volo.Abp.Identity模块中的配置
+
+## appsettings.json
+
+```json
+{
+ "ConnectionStrings": {
+ "AbpIdentity": "Server=127.0.0.1;Database=Identity;User Id=root;Password=*",
+ "AbpAuditLogging": "Server=127.0.0.1;Database=AuditLogging;User Id=root;Password=*",
+ }
+}
+
+```
\ No newline at end of file
diff --git a/modules/auditing/Sanhe.Abp.AuditLogging.EntityFrameworkCore/Sanhe.Abp.AuditLogging.EntityFrameworkCore.csproj b/modules/auditing/Sanhe.Abp.AuditLogging.EntityFrameworkCore/Sanhe.Abp.AuditLogging.EntityFrameworkCore.csproj
new file mode 100644
index 0000000..27e041c
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.AuditLogging.EntityFrameworkCore/Sanhe.Abp.AuditLogging.EntityFrameworkCore.csproj
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+ net6.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/auditing/Sanhe.Abp.AuditLogging.EntityFrameworkCore/Sanhe/Abp/AuditLogging/EntityFrameworkCore/AbpAuditLoggingEntityFrameworkCoreModule.cs b/modules/auditing/Sanhe.Abp.AuditLogging.EntityFrameworkCore/Sanhe/Abp/AuditLogging/EntityFrameworkCore/AbpAuditLoggingEntityFrameworkCoreModule.cs
new file mode 100644
index 0000000..f411be6
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.AuditLogging.EntityFrameworkCore/Sanhe/Abp/AuditLogging/EntityFrameworkCore/AbpAuditLoggingEntityFrameworkCoreModule.cs
@@ -0,0 +1,25 @@
+using Microsoft.Extensions.DependencyInjection;
+using Volo.Abp.AutoMapper;
+using Volo.Abp.Modularity;
+
+namespace Sanhe.Abp.AuditLogging.EntityFrameworkCore
+{
+ [DependsOn(
+ typeof(Volo.Abp.Identity.EntityFrameworkCore.AbpIdentityEntityFrameworkCoreModule),
+ typeof(Volo.Abp.AuditLogging.EntityFrameworkCore.AbpAuditLoggingEntityFrameworkCoreModule))]
+ [DependsOn(
+ typeof(AbpAuditLoggingModule),
+ typeof(AbpAutoMapperModule))]
+ public class AbpAuditLoggingEntityFrameworkCoreModule : AbpModule
+ {
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ context.Services.AddAutoMapperObjectMapper();
+
+ Configure(options =>
+ {
+ options.AddProfile(validate: true);
+ });
+ }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.AuditLogging.EntityFrameworkCore/Sanhe/Abp/AuditLogging/EntityFrameworkCore/AbpAuditingMapperProfile.cs b/modules/auditing/Sanhe.Abp.AuditLogging.EntityFrameworkCore/Sanhe/Abp/AuditLogging/EntityFrameworkCore/AbpAuditingMapperProfile.cs
new file mode 100644
index 0000000..c1fe363
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.AuditLogging.EntityFrameworkCore/Sanhe/Abp/AuditLogging/EntityFrameworkCore/AbpAuditingMapperProfile.cs
@@ -0,0 +1,21 @@
+using AutoMapper;
+
+namespace Sanhe.Abp.AuditLogging.EntityFrameworkCore
+{
+ public class AbpAuditingMapperProfile : Profile
+ {
+ public AbpAuditingMapperProfile()
+ {
+ CreateMap()
+ .MapExtraProperties();
+ CreateMap();
+ CreateMap()
+ .MapExtraProperties();
+ CreateMap()
+ .MapExtraProperties();
+
+ CreateMap()
+ .MapExtraProperties();
+ }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.AuditLogging.EntityFrameworkCore/Sanhe/Abp/AuditLogging/EntityFrameworkCore/AuditLogManager.cs b/modules/auditing/Sanhe.Abp.AuditLogging.EntityFrameworkCore/Sanhe/Abp/AuditLogging/EntityFrameworkCore/AuditLogManager.cs
new file mode 100644
index 0000000..659993a
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.AuditLogging.EntityFrameworkCore/Sanhe/Abp/AuditLogging/EntityFrameworkCore/AuditLogManager.cs
@@ -0,0 +1,179 @@
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Logging.Abstractions;
+using Microsoft.Extensions.Options;
+using System;
+using System.Collections.Generic;
+using System.Net;
+using System.Threading;
+using System.Threading.Tasks;
+using Volo.Abp.Auditing;
+using Volo.Abp.AuditLogging;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.ObjectMapping;
+using Volo.Abp.Uow;
+
+namespace Sanhe.Abp.AuditLogging.EntityFrameworkCore
+{
+ [Dependency(ReplaceServices = true)]
+ public class AuditLogManager : IAuditLogManager, ISingletonDependency
+ {
+ protected IObjectMapper ObjectMapper { get; }
+ protected IAuditLogRepository AuditLogRepository { get; }
+ protected IUnitOfWorkManager UnitOfWorkManager { get; }
+ protected AbpAuditingOptions Options { get; }
+ protected IAuditLogInfoToAuditLogConverter Converter { get; }
+
+ public ILogger Logger { protected get; set; }
+
+ public AuditLogManager(
+ IObjectMapper objectMapper,
+ IAuditLogRepository auditLogRepository,
+ IUnitOfWorkManager unitOfWorkManager,
+ IOptions options,
+ IAuditLogInfoToAuditLogConverter converter)
+ {
+ ObjectMapper = objectMapper;
+ AuditLogRepository = auditLogRepository;
+ UnitOfWorkManager = unitOfWorkManager;
+ Converter = converter;
+ Options = options.Value;
+
+ Logger = NullLogger.Instance;
+ }
+
+
+ public virtual async Task GetCountAsync(
+ DateTime? startTime = null,
+ DateTime? endTime = null,
+ string httpMethod = null,
+ string url = null,
+ Guid? userId = null,
+ string userName = null,
+ string applicationName = null,
+ string correlationId = null,
+ string clientId = null,
+ string clientIpAddress = null,
+ int? maxExecutionDuration = null,
+ int? minExecutionDuration = null,
+ bool? hasException = null,
+ HttpStatusCode? httpStatusCode = null,
+ CancellationToken cancellationToken = default)
+ {
+ return await AuditLogRepository.GetCountAsync(
+ startTime,
+ endTime,
+ httpMethod,
+ url,
+ userId,
+ userName,
+ applicationName,
+ clientIpAddress,
+ correlationId,
+ maxExecutionDuration,
+ minExecutionDuration,
+ hasException,
+ httpStatusCode,
+ cancellationToken);
+ }
+
+ public virtual async Task> GetListAsync(
+ string sorting = null,
+ int maxResultCount = 50,
+ int skipCount = 0,
+ DateTime? startTime = null,
+ DateTime? endTime = null,
+ string httpMethod = null,
+ string url = null,
+ Guid? userId = null,
+ string userName = null,
+ string applicationName = null,
+ string correlationId = null,
+ string clientId = null,
+ string clientIpAddress = null,
+ int? maxExecutionDuration = null,
+ int? minExecutionDuration = null,
+ bool? hasException = null,
+ HttpStatusCode? httpStatusCode = null,
+ bool includeDetails = false,
+ CancellationToken cancellationToken = default)
+ {
+ var auditLogs = await AuditLogRepository.GetListAsync(
+ sorting,
+ maxResultCount,
+ skipCount,
+ startTime,
+ endTime,
+ httpMethod,
+ url,
+ userId,
+ userName,
+ applicationName,
+ clientIpAddress,
+ correlationId,
+ maxExecutionDuration,
+ minExecutionDuration,
+ hasException,
+ httpStatusCode,
+ includeDetails,
+ cancellationToken);
+
+ return ObjectMapper.Map, List>(auditLogs);
+ }
+
+ public virtual async Task GetAsync(
+ Guid id,
+ bool includeDetails = false,
+ CancellationToken cancellationToken = default)
+ {
+ var auditLog = await AuditLogRepository.GetAsync(id, includeDetails, cancellationToken);
+
+ return ObjectMapper.Map(auditLog);
+ }
+
+ public virtual async Task DeleteAsync(Guid id, CancellationToken cancellationToken = default)
+ {
+ using (var uow = UnitOfWorkManager.Begin(true))
+ {
+ await AuditLogRepository.DeleteAsync(id);
+ await uow.CompleteAsync();
+ }
+ }
+
+ public virtual async Task SaveAsync(
+ AuditLogInfo auditInfo,
+ CancellationToken cancellationToken = default)
+ {
+ if (!Options.HideErrors)
+ {
+ return await SaveLogAsync(auditInfo, cancellationToken);
+ }
+
+ try
+ {
+ return await SaveLogAsync(auditInfo, cancellationToken);
+ }
+ catch (Exception ex)
+ {
+ Logger.LogWarning("Could not save the audit log object: " + Environment.NewLine + auditInfo.ToString());
+ Logger.LogException(ex, LogLevel.Error);
+ }
+ return "";
+ }
+
+ protected virtual async Task SaveLogAsync(
+ AuditLogInfo auditInfo,
+ CancellationToken cancellationToken = default)
+ {
+ using (var uow = UnitOfWorkManager.Begin(true))
+ {
+ var auditLog = await AuditLogRepository.InsertAsync(
+ await Converter.ConvertAsync(auditInfo),
+ false,
+ cancellationToken);
+ await uow.CompleteAsync();
+
+ return auditLog.Id.ToString();
+ }
+ }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.AuditLogging.EntityFrameworkCore/Sanhe/Abp/AuditLogging/EntityFrameworkCore/SecurityLogManager.cs b/modules/auditing/Sanhe.Abp.AuditLogging.EntityFrameworkCore/Sanhe/Abp/AuditLogging/EntityFrameworkCore/SecurityLogManager.cs
new file mode 100644
index 0000000..acb9fc9
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.AuditLogging.EntityFrameworkCore/Sanhe/Abp/AuditLogging/EntityFrameworkCore/SecurityLogManager.cs
@@ -0,0 +1,144 @@
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.Guids;
+using Volo.Abp.Identity;
+using Volo.Abp.ObjectMapping;
+using Volo.Abp.SecurityLog;
+using Volo.Abp.Uow;
+
+namespace Sanhe.Abp.AuditLogging.EntityFrameworkCore
+{
+ [Dependency(ReplaceServices = true)]
+ public class SecurityLogManager : ISecurityLogManager, ISingletonDependency
+ {
+ public ILogger Logger { get; set; }
+
+ protected IObjectMapper ObjectMapper { get; }
+ protected AbpSecurityLogOptions SecurityLogOptions { get; }
+ protected IIdentitySecurityLogRepository IdentitySecurityLogRepository { get; }
+ protected IGuidGenerator GuidGenerator { get; }
+ protected IUnitOfWorkManager UnitOfWorkManager { get; }
+
+ public SecurityLogManager(
+ IObjectMapper objectMapper,
+ ILogger logger,
+ IOptions securityLogOptions,
+ IIdentitySecurityLogRepository identitySecurityLogRepository,
+ IGuidGenerator guidGenerator,
+ IUnitOfWorkManager unitOfWorkManager)
+ {
+ Logger = logger;
+ ObjectMapper = objectMapper;
+ SecurityLogOptions = securityLogOptions.Value;
+ IdentitySecurityLogRepository = identitySecurityLogRepository;
+ GuidGenerator = guidGenerator;
+ UnitOfWorkManager = unitOfWorkManager;
+ }
+
+ public virtual async Task SaveAsync(
+ SecurityLogInfo securityLogInfo,
+ CancellationToken cancellationToken = default)
+ {
+ if (!SecurityLogOptions.IsEnabled)
+ {
+ return;
+ }
+
+ using (var uow = UnitOfWorkManager.Begin(requiresNew: true))
+ {
+ await IdentitySecurityLogRepository.InsertAsync(
+ new IdentitySecurityLog(GuidGenerator, securityLogInfo),
+ false,
+ cancellationToken);
+ await uow.CompleteAsync();
+ }
+ }
+
+ public virtual async Task GetAsync(
+ Guid id,
+ bool includeDetails = false,
+ CancellationToken cancellationToken = default)
+ {
+ var securityLog = await IdentitySecurityLogRepository.GetAsync(id, includeDetails, cancellationToken);
+
+ return ObjectMapper.Map(securityLog);
+ }
+
+ public virtual async Task DeleteAsync(Guid id, CancellationToken cancellationToken = default)
+ {
+ using (var uow = UnitOfWorkManager.Begin(true))
+ {
+ await IdentitySecurityLogRepository.DeleteAsync(id);
+ await uow.CompleteAsync();
+ }
+ }
+
+ public virtual async Task> GetListAsync(
+ string sorting = null,
+ int maxResultCount = 50,
+ int skipCount = 0,
+ DateTime? startTime = null,
+ DateTime? endTime = null,
+ string applicationName = null,
+ string identity = null,
+ string action = null,
+ Guid? userId = null,
+ string userName = null,
+ string clientId = null,
+ string clientIpAddress = null,
+ string correlationId = null,
+ bool includeDetails = false,
+ CancellationToken cancellationToken = default)
+ {
+ var securityLogs = await IdentitySecurityLogRepository.GetListAsync(
+ sorting,
+ maxResultCount,
+ skipCount,
+ startTime,
+ endTime,
+ applicationName,
+ identity,
+ action,
+ userId,
+ userName,
+ clientId,
+ correlationId,
+ includeDetails,
+ cancellationToken);
+
+ return ObjectMapper.Map, List>(securityLogs);
+ }
+
+
+ public virtual async Task GetCountAsync(
+ DateTime? startTime = null,
+ DateTime? endTime = null,
+ string applicationName = null,
+ string identity = null,
+ string action = null,
+ Guid? userId = null,
+ string userName = null,
+ string clientId = null,
+ string clientIpAddress = null,
+ string correlationId = null,
+ CancellationToken cancellationToken = default)
+ {
+ return await IdentitySecurityLogRepository.GetCountAsync(
+ startTime,
+ endTime,
+ applicationName,
+ identity,
+ action,
+ userId,
+ userName,
+ clientId,
+ correlationId,
+ cancellationToken);
+ }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.AuditLogging/FodyWeavers.xml b/modules/auditing/Sanhe.Abp.AuditLogging/FodyWeavers.xml
new file mode 100644
index 0000000..1715698
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.AuditLogging/FodyWeavers.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe.Abp.AuditLogging.csproj b/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe.Abp.AuditLogging.csproj
new file mode 100644
index 0000000..0568b5c
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe.Abp.AuditLogging.csproj
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+ netstandard2.0
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/AbpAuditLoggingModule.cs b/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/AbpAuditLoggingModule.cs
new file mode 100644
index 0000000..e64abff
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/AbpAuditLoggingModule.cs
@@ -0,0 +1,15 @@
+using Volo.Abp.Auditing;
+using Volo.Abp.ExceptionHandling;
+using Volo.Abp.Guids;
+using Volo.Abp.Modularity;
+
+namespace Sanhe.Abp.AuditLogging
+{
+ [DependsOn(
+ typeof(AbpAuditingModule),
+ typeof(AbpGuidsModule),
+ typeof(AbpExceptionHandlingModule))]
+ public class AbpAuditLoggingModule : AbpModule
+ {
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/AuditLog.cs b/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/AuditLog.cs
new file mode 100644
index 0000000..778ae67
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/AuditLog.cs
@@ -0,0 +1,115 @@
+using System;
+using System.Collections.Generic;
+using Volo.Abp.Auditing;
+using Volo.Abp.Data;
+
+namespace Sanhe.Abp.AuditLogging
+{
+ [DisableAuditing]
+ public class AuditLog : IHasExtraProperties
+ {
+ public Guid Id { get; set; }
+
+ public string ApplicationName { get; set; }
+
+ public Guid? UserId { get; set; }
+
+ public string UserName { get; set; }
+
+ public Guid? TenantId { get; set; }
+
+ public string TenantName { get; set; }
+
+ public Guid? ImpersonatorUserId { get; set; }
+
+ public Guid? ImpersonatorTenantId { get; set; }
+
+ public DateTime ExecutionTime { get; set; }
+
+ public int ExecutionDuration { get; set; }
+
+ public string ClientIpAddress { get; set; }
+
+ public string ClientName { get; set; }
+
+ public string ClientId { get; set; }
+
+ public string CorrelationId { get; set; }
+
+ public string BrowserInfo { get; set; }
+
+ public string HttpMethod { get; set; }
+
+ public string Url { get; set; }
+
+ public string Exceptions { get; set; }
+
+ public string Comments { get; set; }
+
+ public int? HttpStatusCode { get; set; }
+
+ public List EntityChanges { get; set; }
+
+ public List Actions { get; set; }
+
+ public ExtraPropertyDictionary ExtraProperties { get; set; }
+
+ public AuditLog()
+ {
+ Actions = new List();
+ EntityChanges = new List();
+ ExtraProperties = new ExtraPropertyDictionary();
+ }
+
+ public AuditLog(
+ Guid id,
+ string applicationName,
+ Guid? tenantId,
+ string tenantName,
+ Guid? userId,
+ string userName,
+ DateTime executionTime,
+ int executionDuration,
+ string clientIpAddress,
+ string clientName,
+ string clientId,
+ string correlationId,
+ string browserInfo,
+ string httpMethod,
+ string url,
+ int? httpStatusCode,
+ Guid? impersonatorUserId,
+ Guid? impersonatorTenantId,
+ ExtraPropertyDictionary extraPropertyDictionary,
+ List entityChanges,
+ List actions,
+ string exceptions,
+ string comments)
+ {
+ Id = id;
+ ApplicationName = applicationName;
+ TenantId = tenantId;
+ TenantName = tenantName;
+ UserId = userId;
+ UserName = userName;
+ ExecutionTime = executionTime;
+ ExecutionDuration = executionDuration;
+ ClientIpAddress = clientIpAddress;
+ ClientName = clientName;
+ ClientId = clientId;
+ CorrelationId = correlationId;
+ BrowserInfo = browserInfo;
+ HttpMethod = httpMethod;
+ Url = url;
+ HttpStatusCode = httpStatusCode;
+ ImpersonatorUserId = impersonatorUserId;
+ ImpersonatorTenantId = impersonatorTenantId;
+
+ ExtraProperties = extraPropertyDictionary;
+ EntityChanges = entityChanges;
+ Actions = actions;
+ Exceptions = exceptions;
+ Comments = comments;
+ }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/AuditLogAction.cs b/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/AuditLogAction.cs
new file mode 100644
index 0000000..ea87620
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/AuditLogAction.cs
@@ -0,0 +1,47 @@
+using System;
+using Volo.Abp.Auditing;
+using Volo.Abp.Data;
+
+namespace Sanhe.Abp.AuditLogging
+{
+ [DisableAuditing]
+ public class AuditLogAction : IHasExtraProperties
+ {
+ public Guid Id { get; set; }
+
+ public Guid? TenantId { get; set; }
+
+ public Guid AuditLogId { get; set; }
+
+ public string ServiceName { get; set; }
+
+ public string MethodName { get; set; }
+
+ public string Parameters { get; set; }
+
+ public DateTime ExecutionTime { get; set; }
+
+ public int ExecutionDuration { get; set; }
+
+ public ExtraPropertyDictionary ExtraProperties { get; set; }
+
+ public AuditLogAction()
+ {
+ ExtraProperties = new ExtraPropertyDictionary();
+ }
+
+ public AuditLogAction(Guid id, Guid auditLogId, AuditLogActionInfo actionInfo, Guid? tenantId = null)
+ {
+
+ Id = id;
+ TenantId = tenantId;
+ AuditLogId = auditLogId;
+ ExecutionTime = actionInfo.ExecutionTime;
+ ExecutionDuration = actionInfo.ExecutionDuration;
+ ExtraProperties = new ExtraPropertyDictionary(actionInfo.ExtraProperties);
+ ServiceName = actionInfo.ServiceName;
+ MethodName = actionInfo.MethodName;
+ Parameters = actionInfo.Parameters.Length > 2000 ? "" : actionInfo.Parameters;
+ }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/AuditingStore.cs b/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/AuditingStore.cs
new file mode 100644
index 0000000..f43b765
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/AuditingStore.cs
@@ -0,0 +1,23 @@
+using System.Threading.Tasks;
+using Volo.Abp.Auditing;
+using Volo.Abp.DependencyInjection;
+
+namespace Sanhe.Abp.AuditLogging
+{
+ [Dependency(ReplaceServices = true)]
+ public class AuditingStore : IAuditingStore, ITransientDependency
+ {
+ private readonly IAuditLogManager _manager;
+
+ public AuditingStore(
+ IAuditLogManager manager)
+ {
+ _manager = manager;
+ }
+
+ public virtual async Task SaveAsync(AuditLogInfo auditInfo)
+ {
+ await _manager.SaveAsync(auditInfo);
+ }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/DefaultAuditLogManager.cs b/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/DefaultAuditLogManager.cs
new file mode 100644
index 0000000..dcead79
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/DefaultAuditLogManager.cs
@@ -0,0 +1,96 @@
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Logging.Abstractions;
+using System;
+using System.Collections.Generic;
+using System.Net;
+using System.Threading;
+using System.Threading.Tasks;
+using Volo.Abp.Auditing;
+using Volo.Abp.DependencyInjection;
+
+namespace Sanhe.Abp.AuditLogging
+{
+ [Dependency(TryRegister = true)]
+ public class DefaultAuditLogManager : IAuditLogManager, ISingletonDependency
+ {
+ public ILogger Logger { protected get; set; }
+
+ public DefaultAuditLogManager()
+ {
+ Logger = NullLogger.Instance;
+ }
+
+ public virtual Task GetCountAsync(
+ DateTime? startTime = null,
+ DateTime? endTime = null,
+ string httpMethod = null,
+ string url = null,
+ Guid? userId = null,
+ string userName = null,
+ string applicationName = null,
+ string correlationId = null,
+ string clientId = null,
+ string clientIpAddress = null,
+ int? maxExecutionDuration = null,
+ int? minExecutionDuration = null,
+ bool? hasException = null,
+ HttpStatusCode? httpStatusCode = null,
+ CancellationToken cancellationToken = default)
+ {
+ Logger.LogDebug("No audit log manager is available!");
+ return Task.FromResult(0L);
+ }
+
+ public virtual Task> GetListAsync(
+ string sorting = null,
+ int maxResultCount = 50,
+ int skipCount = 0,
+ DateTime? startTime = null,
+ DateTime? endTime = null,
+ string httpMethod = null,
+ string url = null,
+ Guid? userId = null,
+ string userName = null,
+ string applicationName = null,
+ string correlationId = null,
+ string clientId = null,
+ string clientIpAddress = null,
+ int? maxExecutionDuration = null,
+ int? minExecutionDuration = null,
+ bool? hasException = null,
+ HttpStatusCode? httpStatusCode = null,
+ bool includeDetails = false,
+ CancellationToken cancellationToken = default)
+ {
+ Logger.LogDebug("No audit log manager is available!");
+ return Task.FromResult(new List());
+ }
+
+ public virtual Task SaveAsync(
+ AuditLogInfo auditInfo,
+ CancellationToken cancellationToken = default)
+ {
+ Logger.LogDebug("No audit log manager is available and is written to the local log by default");
+ Logger.LogInformation(auditInfo.ToString());
+
+ return Task.FromResult("");
+ }
+
+ public virtual Task GetAsync(
+ Guid id,
+ bool includeDetails = false,
+ CancellationToken cancellationToken = default)
+ {
+ Logger.LogDebug("No audit log manager is available!");
+
+ AuditLog auditLog = null;
+ return Task.FromResult(auditLog);
+ }
+
+ public virtual Task DeleteAsync(Guid id, CancellationToken cancellationToken = default)
+ {
+ Logger.LogDebug("No audit log manager is available!");
+ return Task.CompletedTask;
+ }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/DefaultEntityChangeStore.cs b/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/DefaultEntityChangeStore.cs
new file mode 100644
index 0000000..c4a1785
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/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 Sanhe.Abp.AuditLogging
+{
+ [Dependency(TryRegister = true)]
+ public class DefaultEntityChangeStore : IEntityChangeStore, ISingletonDependency
+ {
+ public Task GetAsync(Guid entityChangeId, CancellationToken cancellationToken = default)
+ {
+ EntityChange entityChange = null;
+ return Task.FromResult(entityChange);
+ }
+
+ public Task 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> 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());
+ }
+
+ public Task GetWithUsernameAsync(Guid entityChangeId, CancellationToken cancellationToken = default)
+ {
+ EntityChangeWithUsername entityChange = null;
+ return Task.FromResult(entityChange);
+ }
+
+ public Task> GetWithUsernameAsync(string entityId, string entityTypeFullName, CancellationToken cancellationToken = default)
+ {
+ return Task.FromResult(new List());
+ }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/DefaultSecurityLogManager.cs b/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/DefaultSecurityLogManager.cs
new file mode 100644
index 0000000..cac7e57
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/DefaultSecurityLogManager.cs
@@ -0,0 +1,87 @@
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Logging.Abstractions;
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.SecurityLog;
+
+namespace Sanhe.Abp.AuditLogging
+{
+ [Dependency(TryRegister = true)]
+ public class DefaultSecurityLogManager : ISecurityLogManager, ISingletonDependency
+ {
+ public ILogger Logger { protected get; set; }
+
+ public DefaultSecurityLogManager()
+ {
+ Logger = NullLogger.Instance;
+ }
+
+ public Task GetCountAsync(
+ DateTime? startTime = null,
+ DateTime? endTime = null,
+ string applicationName = null,
+ string identity = null,
+ string action = null,
+ Guid? userId = null,
+ string userName = null,
+ string clientId = null,
+ string clientIpAddress = null,
+ string correlationId = null,
+ CancellationToken cancellationToken = default)
+ {
+ Logger.LogDebug("No security log manager is available!");
+ return Task.FromResult(0L);
+ }
+
+ public Task> GetListAsync(
+ string sorting = null,
+ int maxResultCount = 50,
+ int skipCount = 0,
+ DateTime? startTime = null,
+ DateTime? endTime = null,
+ string applicationName = null,
+ string identity = null,
+ string action = null,
+ Guid? userId = null,
+ string userName = null,
+ string clientId = null,
+ string clientIpAddress = null,
+ string correlationId = null,
+ bool includeDetails = false,
+ CancellationToken cancellationToken = default)
+ {
+ Logger.LogDebug("No security log manager is available!");
+ return Task.FromResult(new List());
+ }
+
+ public Task SaveAsync(
+ SecurityLogInfo securityLogInfo,
+ CancellationToken cancellationToken = default)
+ {
+ Logger.LogDebug("No security log manager is available and is written to the local log by default");
+ Logger.LogInformation(securityLogInfo.ToString());
+
+ return Task.CompletedTask;
+ }
+
+ public virtual Task GetAsync(
+ Guid id,
+ bool includeDetails = false,
+ CancellationToken cancellationToken = default)
+ {
+ Logger.LogDebug("No security log manager is available!");
+
+ SecurityLog securityLog = null;
+ return Task.FromResult(securityLog);
+ }
+
+ public virtual Task DeleteAsync(Guid id, CancellationToken cancellationToken = default)
+ {
+ Logger.LogDebug("No security log manager is available!");
+ return Task.CompletedTask;
+ }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/EntityChange.cs b/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/EntityChange.cs
new file mode 100644
index 0000000..01732c4
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/EntityChange.cs
@@ -0,0 +1,69 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Volo.Abp.Auditing;
+using Volo.Abp.Data;
+using Volo.Abp.Guids;
+
+namespace Sanhe.Abp.AuditLogging
+{
+ [DisableAuditing]
+ public class EntityChange : IHasExtraProperties
+ {
+ public Guid Id { get; set; }
+
+ public Guid AuditLogId { get; set; }
+
+ public Guid? TenantId { get; set; }
+
+ public DateTime ChangeTime { get; set; }
+
+ public EntityChangeType ChangeType { get; set; }
+
+ public Guid? EntityTenantId { get; set; }
+
+ public string EntityId { get; set; }
+
+ public string EntityTypeFullName { get; set; }
+
+ public List PropertyChanges { get; set; }
+
+ public ExtraPropertyDictionary ExtraProperties { get; set; }
+
+ public EntityChange()
+ {
+ PropertyChanges = new List();
+ ExtraProperties = new ExtraPropertyDictionary();
+ }
+
+ public EntityChange(
+ IGuidGenerator guidGenerator,
+ Guid auditLogId,
+ EntityChangeInfo entityChangeInfo,
+ Guid? tenantId = null)
+ {
+ Id = guidGenerator.Create();
+ AuditLogId = auditLogId;
+ TenantId = tenantId;
+ ChangeTime = entityChangeInfo.ChangeTime;
+ ChangeType = entityChangeInfo.ChangeType;
+ EntityId = entityChangeInfo.EntityId;
+ EntityTypeFullName = entityChangeInfo.EntityTypeFullName;
+
+ PropertyChanges = entityChangeInfo
+ .PropertyChanges?
+ .Select(p => new EntityPropertyChange(guidGenerator, Id, p, tenantId))
+ .ToList()
+ ?? new List();
+
+ ExtraProperties = new ExtraPropertyDictionary();
+ if (entityChangeInfo.ExtraProperties != null)
+ {
+ foreach (var pair in entityChangeInfo.ExtraProperties)
+ {
+ ExtraProperties.Add(pair.Key, pair.Value);
+ }
+ }
+ }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/EntityChangeWithUsername.cs b/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/EntityChangeWithUsername.cs
new file mode 100644
index 0000000..d0a80b9
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/EntityChangeWithUsername.cs
@@ -0,0 +1,9 @@
+namespace Sanhe.Abp.AuditLogging
+{
+ public class EntityChangeWithUsername
+ {
+ public EntityChange EntityChange { get; set; }
+
+ public string UserName { get; set; }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/EntityPropertyChange.cs b/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/EntityPropertyChange.cs
new file mode 100644
index 0000000..97cf661
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/EntityPropertyChange.cs
@@ -0,0 +1,43 @@
+using System;
+using Volo.Abp.Auditing;
+using Volo.Abp.Guids;
+
+namespace Sanhe.Abp.AuditLogging
+{
+ [DisableAuditing]
+ public class EntityPropertyChange
+ {
+ public Guid Id { get; set; }
+
+ public Guid? TenantId { get; set; }
+
+ public Guid EntityChangeId { get; set; }
+
+ public string NewValue { get; set; }
+
+ public string OriginalValue { get; set; }
+
+ public string PropertyName { get; set; }
+
+ public string PropertyTypeFullName { get; set; }
+
+ public EntityPropertyChange()
+ {
+ }
+
+ public EntityPropertyChange(
+ IGuidGenerator guidGenerator,
+ Guid entityChangeId,
+ EntityPropertyChangeInfo entityChangeInfo,
+ Guid? tenantId = null)
+ {
+ Id = guidGenerator.Create();
+ TenantId = tenantId;
+ EntityChangeId = entityChangeId;
+ NewValue = entityChangeInfo.NewValue;
+ OriginalValue = entityChangeInfo.OriginalValue;
+ PropertyName = entityChangeInfo.PropertyName;
+ PropertyTypeFullName = entityChangeInfo.PropertyTypeFullName;
+ }
+ }
+}
\ No newline at end of file
diff --git a/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/IAuditLogManager.cs b/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/IAuditLogManager.cs
new file mode 100644
index 0000000..606361f
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/IAuditLogManager.cs
@@ -0,0 +1,64 @@
+using System;
+using System.Collections.Generic;
+using System.Net;
+using System.Threading;
+using System.Threading.Tasks;
+using Volo.Abp.Auditing;
+
+namespace Sanhe.Abp.AuditLogging
+{
+ public interface IAuditLogManager
+ {
+ Task GetAsync(
+ Guid id,
+ bool includeDetails = false,
+ CancellationToken cancellationToken = default);
+
+ Task DeleteAsync(
+ Guid id,
+ CancellationToken cancellationToken = default);
+
+ Task SaveAsync(
+ AuditLogInfo auditInfo,
+ CancellationToken cancellationToken = default);
+
+ Task GetCountAsync(
+ DateTime? startTime = null,
+ DateTime? endTime = null,
+ string httpMethod = null,
+ string url = null,
+ Guid? userId = null,
+ string userName = null,
+ string applicationName = null,
+ string correlationId = null,
+ string clientId = null,
+ string clientIpAddress = null,
+ int? maxExecutionDuration = null,
+ int? minExecutionDuration = null,
+ bool? hasException = null,
+ HttpStatusCode? httpStatusCode = null,
+ CancellationToken cancellationToken = default);
+
+ Task> GetListAsync(
+ string sorting = null,
+ int maxResultCount = 50,
+ int skipCount = 0,
+ DateTime? startTime = null,
+ DateTime? endTime = null,
+ string httpMethod = null,
+ string url = null,
+ Guid? userId = null,
+ string userName = null,
+ string applicationName = null,
+ string correlationId = null,
+ string clientId = null,
+ string clientIpAddress = null,
+ int? maxExecutionDuration = null,
+ int? minExecutionDuration = null,
+ bool? hasException = null,
+ HttpStatusCode? httpStatusCode = null,
+ bool includeDetails = false,
+ CancellationToken cancellationToken = default);
+
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/IEntityChangeStore.cs b/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/IEntityChangeStore.cs
new file mode 100644
index 0000000..f2e45cd
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/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 Sanhe.Abp.AuditLogging
+{
+ public interface IEntityChangeStore
+ {
+ Task GetAsync(
+ Guid entityChangeId,
+ CancellationToken cancellationToken = default);
+
+ Task GetCountAsync(
+ Guid? auditLogId = null,
+ DateTime? startTime = null,
+ DateTime? endTime = null,
+ EntityChangeType? changeType = null,
+ string entityId = null,
+ string entityTypeFullName = null,
+ CancellationToken cancellationToken = default);
+
+ Task> 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 GetWithUsernameAsync(
+ Guid entityChangeId,
+ CancellationToken cancellationToken = default);
+
+ Task> GetWithUsernameAsync(
+ string entityId,
+ string entityTypeFullName,
+ CancellationToken cancellationToken = default);
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/ISecurityLogManager.cs b/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/ISecurityLogManager.cs
new file mode 100644
index 0000000..7bfa9ff
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/ISecurityLogManager.cs
@@ -0,0 +1,56 @@
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+using Volo.Abp.SecurityLog;
+
+namespace Sanhe.Abp.AuditLogging
+{
+ public interface ISecurityLogManager
+ {
+ Task GetAsync(
+ Guid id,
+ bool includeDetails = false,
+ CancellationToken cancellationToken = default);
+
+ Task DeleteAsync(
+ Guid id,
+ CancellationToken cancellationToken = default);
+
+ Task SaveAsync(
+ SecurityLogInfo securityLogInfo,
+ CancellationToken cancellationToken = default);
+
+ Task> GetListAsync(
+ string sorting = null,
+ int maxResultCount = 50,
+ int skipCount = 0,
+ DateTime? startTime = null,
+ DateTime? endTime = null,
+ string applicationName = null,
+ string identity = null,
+ string action = null,
+ Guid? userId = null,
+ string userName = null,
+ string clientId = null,
+ string clientIpAddress = null,
+ string correlationId = null,
+ bool includeDetails = false,
+ CancellationToken cancellationToken = default);
+
+
+ Task GetCountAsync(
+ DateTime? startTime = null,
+ DateTime? endTime = null,
+ string applicationName = null,
+ string identity = null,
+ string action = null,
+ Guid? userId = null,
+ string userName = null,
+ string clientId = null,
+ string clientIpAddress = null,
+ string correlationId = null,
+ CancellationToken cancellationToken = default);
+
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/SecurityLog.cs b/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/SecurityLog.cs
new file mode 100644
index 0000000..3925adf
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/SecurityLog.cs
@@ -0,0 +1,72 @@
+using System;
+using Volo.Abp.Data;
+using Volo.Abp.SecurityLog;
+
+namespace Sanhe.Abp.AuditLogging
+{
+ public class SecurityLog : IHasExtraProperties
+ {
+ public Guid Id { get; set; }
+
+ public Guid? TenantId { get; set; }
+
+ public string ApplicationName { get; set; }
+
+ public string Identity { get; set; }
+
+ public string Action { get; set; }
+
+ public Guid? UserId { get; set; }
+
+ public string UserName { get; set; }
+
+ public string TenantName { get; set; }
+
+ public string ClientId { get; set; }
+
+ public string CorrelationId { get; set; }
+
+ public string ClientIpAddress { get; set; }
+
+ public string BrowserInfo { get; set; }
+
+ public DateTime CreationTime { get; set; }
+
+ public ExtraPropertyDictionary ExtraProperties { get; set; }
+
+ public SecurityLog()
+ {
+ ExtraProperties = new ExtraPropertyDictionary();
+ }
+
+ public SecurityLog(Guid id, SecurityLogInfo securityLogInfo)
+ {
+ Id = id;
+ TenantId = securityLogInfo.TenantId;
+ TenantName = securityLogInfo.TenantName;
+
+ ApplicationName = securityLogInfo.ApplicationName;
+ Identity = securityLogInfo.Identity;
+ Action = securityLogInfo.Action;
+
+ UserId = securityLogInfo.UserId;
+ UserName = securityLogInfo.UserName;
+
+ CreationTime = securityLogInfo.CreationTime;
+
+ ClientIpAddress = securityLogInfo.ClientIpAddress;
+ ClientId = securityLogInfo.ClientId;
+ CorrelationId = securityLogInfo.CorrelationId;
+ BrowserInfo = securityLogInfo.BrowserInfo;
+
+ ExtraProperties = new ExtraPropertyDictionary();
+ if (securityLogInfo.ExtraProperties != null)
+ {
+ foreach (var pair in securityLogInfo.ExtraProperties)
+ {
+ ExtraProperties.Add(pair.Key, pair.Value);
+ }
+ }
+ }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/SecurityLogStore.cs b/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/SecurityLogStore.cs
new file mode 100644
index 0000000..6b17f0a
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.AuditLogging/Sanhe/Abp/AuditLogging/SecurityLogStore.cs
@@ -0,0 +1,23 @@
+using System.Threading.Tasks;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.SecurityLog;
+
+namespace Sanhe.Abp.AuditLogging
+{
+ [Dependency(ReplaceServices = true)]
+ public class SecurityLogStore : ISecurityLogStore, ITransientDependency
+ {
+ private readonly ISecurityLogManager _manager;
+
+ public SecurityLogStore(
+ ISecurityLogManager manager)
+ {
+ _manager = manager;
+ }
+
+ public virtual async Task SaveAsync(SecurityLogInfo securityLogInfo)
+ {
+ await _manager.SaveAsync(securityLogInfo);
+ }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/FodyWeavers.xml b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/FodyWeavers.xml
new file mode 100644
index 0000000..1715698
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/FodyWeavers.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe.Abp.Auditing.Application.Contracts.csproj b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe.Abp.Auditing.Application.Contracts.csproj
new file mode 100644
index 0000000..571fd66
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe.Abp.Auditing.Application.Contracts.csproj
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+ netstandard2.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AbpAuditingApplicationContractsModule.cs b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AbpAuditingApplicationContractsModule.cs
new file mode 100644
index 0000000..bac0ea1
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AbpAuditingApplicationContractsModule.cs
@@ -0,0 +1,34 @@
+using Volo.Abp.Application;
+using Volo.Abp.AuditLogging;
+using Volo.Abp.AuditLogging.Localization;
+using Volo.Abp.Authorization;
+using Volo.Abp.Features;
+using Volo.Abp.Localization;
+using Volo.Abp.Modularity;
+using Volo.Abp.VirtualFileSystem;
+
+namespace Sanhe.Abp.Auditing
+{
+ [DependsOn(
+ typeof(AbpFeaturesModule),
+ typeof(AbpAuthorizationModule),
+ typeof(AbpAuditLoggingDomainSharedModule),
+ typeof(AbpDddApplicationContractsModule))]
+ public class AbpAuditingApplicationContractsModule : AbpModule
+ {
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ Configure(options =>
+ {
+ options.FileSets.AddEmbedded();
+ });
+
+ Configure(options =>
+ {
+ options.Resources
+ .Get()
+ .AddVirtualJson("/Sanhe/Abp/Auditing/Localization/Resources");
+ });
+ }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AuditLogs/AuditLogActionDto.cs b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AuditLogs/AuditLogActionDto.cs
new file mode 100644
index 0000000..44799f4
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AuditLogs/AuditLogActionDto.cs
@@ -0,0 +1,18 @@
+using System;
+using Volo.Abp.Application.Dtos;
+
+namespace Sanhe.Abp.Auditing.AuditLogs
+{
+ public class AuditLogActionDto : ExtensibleEntityDto
+ {
+ public string ServiceName { get; set; }
+
+ public string MethodName { get; set; }
+
+ public string Parameters { get; set; }
+
+ public DateTime ExecutionTime { get; set; }
+
+ public int ExecutionDuration { get; set; }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AuditLogs/AuditLogDto.cs b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AuditLogs/AuditLogDto.cs
new file mode 100644
index 0000000..34b0dfc
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AuditLogs/AuditLogDto.cs
@@ -0,0 +1,55 @@
+using System;
+using System.Collections.Generic;
+using Volo.Abp.Application.Dtos;
+
+namespace Sanhe.Abp.Auditing.AuditLogs
+{
+ public class AuditLogDto : ExtensibleEntityDto
+ {
+ public string ApplicationName { get; set; }
+
+ public Guid? UserId { get; set; }
+
+ public string UserName { get; set; }
+
+ public Guid? TenantId { get; set; }
+
+ public string TenantName { get; set; }
+
+ public Guid? ImpersonatorUserId { get; set; }
+
+ public Guid? ImpersonatorTenantId { get; set; }
+
+ public DateTime ExecutionTime { get; set; }
+
+ public int ExecutionDuration { get; set; }
+
+ public string ClientIpAddress { get; set; }
+
+ public string ClientName { get; set; }
+
+ public string ClientId { get; set; }
+
+ public string CorrelationId { get; set; }
+
+ public string BrowserInfo { get; set; }
+
+ public string HttpMethod { get; set; }
+
+ public string Url { get; set; }
+
+ public string Exceptions { get; set; }
+
+ public string Comments { get; set; }
+
+ public int? HttpStatusCode { get; set; }
+ public List EntityChanges { get; set; }
+ public List Actions { get; set; }
+
+ public AuditLogDto()
+ {
+ EntityChanges = new List();
+ Actions = new List();
+ }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AuditLogs/AuditLogGetByPagedDto.cs b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AuditLogs/AuditLogGetByPagedDto.cs
new file mode 100644
index 0000000..491b4aa
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AuditLogs/AuditLogGetByPagedDto.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Net;
+using Volo.Abp.Application.Dtos;
+
+namespace Sanhe.Abp.Auditing.AuditLogs
+{
+ public class AuditLogGetByPagedDto : PagedAndSortedResultRequestDto
+ {
+ public DateTime? StartTime { get; set; }
+ public DateTime? EndTime { get; set; }
+ public string HttpMethod { get; set; }
+ public string Url { get; set; }
+ public Guid? UserId { get; set; }
+ public string UserName { get; set; }
+ public string ApplicationName { get; set; }
+ public string CorrelationId { get; set; }
+ public string ClientId { get; set; }
+ public string ClientIpAddress { get; set; }
+ public int? MaxExecutionDuration { get; set; }
+ public int? MinExecutionDuration { get; set; }
+ public bool? HasException { get; set; }
+ public HttpStatusCode? HttpStatusCode { get; set; }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AuditLogs/EntityChangeDto.cs b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AuditLogs/EntityChangeDto.cs
new file mode 100644
index 0000000..793d889
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AuditLogs/EntityChangeDto.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using Volo.Abp.Application.Dtos;
+using Volo.Abp.Auditing;
+
+namespace Sanhe.Abp.Auditing.AuditLogs
+{
+ public class EntityChangeDto : ExtensibleEntityDto
+ {
+ public DateTime ChangeTime { get; set; }
+
+ public EntityChangeType ChangeType { get; set; }
+
+ public Guid? EntityTenantId { get; set; }
+
+ public string EntityId { get; set; }
+
+ public string EntityTypeFullName { get; set; }
+
+ public List PropertyChanges { get; set; }
+
+ public EntityChangeDto()
+ {
+ PropertyChanges = new List();
+ }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AuditLogs/EntityChangeGetByPagedDto.cs b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AuditLogs/EntityChangeGetByPagedDto.cs
new file mode 100644
index 0000000..fe1ec08
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AuditLogs/EntityChangeGetByPagedDto.cs
@@ -0,0 +1,15 @@
+using System;
+using Volo.Abp.Application.Dtos;
+using Volo.Abp.Auditing;
+
+namespace Sanhe.Abp.Auditing.AuditLogs;
+
+public class EntityChangeGetByPagedDto : PagedAndSortedResultRequestDto
+{
+ public Guid? AuditLogId { get; set; }
+ public DateTime? StartTime { get; set; }
+ public DateTime? EndTime { get; set; }
+ public EntityChangeType? ChangeType { get; set; }
+ public string EntityId { get; set; }
+ public string EntityTypeFullName { get; set; }
+}
diff --git a/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AuditLogs/EntityChangeGetWithUsernameDto.cs b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AuditLogs/EntityChangeGetWithUsernameDto.cs
new file mode 100644
index 0000000..9af2eb6
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AuditLogs/EntityChangeGetWithUsernameDto.cs
@@ -0,0 +1,7 @@
+namespace Sanhe.Abp.Auditing.AuditLogs;
+
+public class EntityChangeGetWithUsernameDto
+{
+ public string EntityId { get; set; }
+ public string EntityTypeFullName { get; set; }
+}
diff --git a/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AuditLogs/EntityChangeWithUsernameDto.cs b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AuditLogs/EntityChangeWithUsernameDto.cs
new file mode 100644
index 0000000..b3ed608
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AuditLogs/EntityChangeWithUsernameDto.cs
@@ -0,0 +1,8 @@
+namespace Sanhe.Abp.Auditing.AuditLogs;
+
+public class EntityChangeWithUsernameDto
+{
+ public EntityChangeDto EntityChange { get; set; }
+
+ public string UserName { get; set; }
+}
diff --git a/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AuditLogs/EntityPropertyChangeDto.cs b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AuditLogs/EntityPropertyChangeDto.cs
new file mode 100644
index 0000000..497597d
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AuditLogs/EntityPropertyChangeDto.cs
@@ -0,0 +1,16 @@
+using System;
+using Volo.Abp.Application.Dtos;
+
+namespace Sanhe.Abp.Auditing.AuditLogs
+{
+ public class EntityPropertyChangeDto : EntityDto
+ {
+ public string NewValue { get; set; }
+
+ public string OriginalValue { get; set; }
+
+ public string PropertyName { get; set; }
+
+ public string PropertyTypeFullName { get; set; }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AuditLogs/IAuditLogAppService.cs b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AuditLogs/IAuditLogAppService.cs
new file mode 100644
index 0000000..792cfcf
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AuditLogs/IAuditLogAppService.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Threading.Tasks;
+using Volo.Abp.Application.Dtos;
+using Volo.Abp.Application.Services;
+
+namespace Sanhe.Abp.Auditing.AuditLogs
+{
+ public interface IAuditLogAppService : IApplicationService
+ {
+ Task> GetListAsync(AuditLogGetByPagedDto input);
+
+ Task GetAsync(Guid id);
+
+ Task DeleteAsync(Guid id);
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AuditLogs/IEntityChangesAppService.cs b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AuditLogs/IEntityChangesAppService.cs
new file mode 100644
index 0000000..0ffd214
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AuditLogs/IEntityChangesAppService.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Threading.Tasks;
+using Volo.Abp.Application.Dtos;
+using Volo.Abp.Application.Services;
+
+namespace Sanhe.Abp.Auditing.AuditLogs;
+
+public interface IEntityChangesAppService : IApplicationService
+{
+ Task GetAsync(Guid id);
+
+ Task GetWithUsernameAsync(Guid id);
+
+ Task> GetListAsync(EntityChangeGetByPagedDto input);
+
+ Task> GetWithUsernameAsync(EntityChangeGetWithUsernameDto input);
+}
diff --git a/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AuditingRemoteServiceConsts.cs b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AuditingRemoteServiceConsts.cs
new file mode 100644
index 0000000..8371b3d
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/AuditingRemoteServiceConsts.cs
@@ -0,0 +1,7 @@
+namespace Sanhe.Abp.Auditing
+{
+ public static class AuditingRemoteServiceConsts
+ {
+ public const string RemoteServiceName = "AbpAuditing";
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/Features/AuditingFeatureDefinitionProvider.cs b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/Features/AuditingFeatureDefinitionProvider.cs
new file mode 100644
index 0000000..562d084
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/Features/AuditingFeatureDefinitionProvider.cs
@@ -0,0 +1,43 @@
+using Volo.Abp.AuditLogging.Localization;
+using Volo.Abp.Features;
+using Volo.Abp.Localization;
+using Volo.Abp.Validation.StringValues;
+
+namespace Sanhe.Abp.Auditing.Features
+{
+ public class AuditingFeatureDefinitionProvider : FeatureDefinitionProvider
+ {
+ public override void Define(IFeatureDefinitionContext context)
+ {
+ var auditingGroup = context.AddGroup(
+ name: AuditingFeatureNames.GroupName,
+ displayName: L("Features:Auditing"));
+
+ var loggingFeature = auditingGroup.AddFeature(
+ name: AuditingFeatureNames.Logging.Default,
+ displayName: L("Features:Auditing"),
+ description: L("Features:Auditing")
+ );
+
+ loggingFeature.CreateChild(
+ name: AuditingFeatureNames.Logging.AuditLog,
+ defaultValue: true.ToString(),
+ displayName: L("Features:DisplayName:AuditLog"),
+ description: L("Features:Description:AuditLog"),
+ valueType: new ToggleStringValueType(new BooleanValueValidator())
+ );
+ loggingFeature.CreateChild(
+ name: AuditingFeatureNames.Logging.SecurityLog,
+ defaultValue: true.ToString(),
+ displayName: L("Features:DisplayName:SecurityLog"),
+ description: L("Features:Description:SecurityLog"),
+ valueType: new ToggleStringValueType(new BooleanValueValidator())
+ );
+ }
+
+ protected LocalizableString L(string name)
+ {
+ return LocalizableString.Create(name);
+ }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/Features/AuditingFeatureNames.cs b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/Features/AuditingFeatureNames.cs
new file mode 100644
index 0000000..314def1
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/Features/AuditingFeatureNames.cs
@@ -0,0 +1,15 @@
+namespace Sanhe.Abp.Auditing.Features
+{
+ public static class AuditingFeatureNames
+ {
+ public const string GroupName = "AbpAuditing";
+ public class Logging
+ {
+ public const string Default = GroupName + ".Logging";
+
+ public const string AuditLog = Default + ".AuditLog";
+
+ public const string SecurityLog = Default + ".SecurityLog";
+ }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/Localization/Resources/en.json b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/Localization/Resources/en.json
new file mode 100644
index 0000000..6e15b1e
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/Localization/Resources/en.json
@@ -0,0 +1,88 @@
+{
+ "culture": "en",
+ "texts": {
+ "Permissions:Auditing": "Auditing",
+ "Permissions:AuditLog": "Audit log",
+ "Permissions:SecurityLog": "Security log",
+ "Permissions:DeleteLog": "Delete",
+ "Features:Auditing": "Auditing",
+ "Features:DisplayName:AuditLog": "Audit log",
+ "Features:Description:AuditLog": "Whether to enable audit logging",
+ "Features:DisplayName:SecurityLog": "Security log",
+ "Features:Description:SecurityLog": "Whether to enable security logging",
+ "SecurityLog": "Security log",
+ "AuditLog": "Audit log",
+ "Logging": "System Log",
+ "Application": "Application",
+ "ApplicationName": "Application name",
+ "TenantId": "Tenant id",
+ "TenantName": "Tenant name",
+ "ImpersonatorTenantId": "Impersonator tenant",
+ "UserInfo": "User info",
+ "UserId": "User id",
+ "UserName": "User name",
+ "ImpersonatorUserId": "Impersonator user",
+ "ClientId": "Client id",
+ "ClientName": "Client name",
+ "ClientIpAddress": "Ip address",
+ "BrowserInfo": "Browser",
+ "Operation": "Operation",
+ "HttpMethod": "Http method",
+ "RequestUrl": "Request url",
+ "HttpStatusCode": "StatusCode",
+ "HasException": "Has exception",
+ "ExecutionTime": "Execution time",
+ "MinExecutionDuration": "Min execution duration(ms)",
+ "MaxExecutionDuration": "Max execution duration(ms)",
+ "ExecutionDuration": "Execution duration(ms)",
+ "Identity": "Identity",
+ "ActionName": "Action",
+ "CreationTime": "Creation time",
+ "Additional": "Additional",
+ "CorrelationId": "Correlation",
+ "StartTime": "Start time",
+ "EndTime": "End time",
+ "SelectDateTime": "Select time",
+ "InvokeMethod": "Invoke method",
+ "ServiceName": "Service",
+ "MethodName": "Method",
+ "Parameters": "Parameters",
+ "EntitiesChanged": "Entities changed",
+ "ChangeType": "Change type",
+ "EntityTypeFullName": "Entity type",
+ "EntityId": "Entity id",
+ "PropertyChanges": "Property changes",
+ "PropertyName": "Property name",
+ "NewValue": "New value",
+ "OriginalValue": "Original value",
+ "PropertyTypeFullName": "Property type",
+ "Exception": "Exception",
+ "StackTrack": "Stack track",
+ "SecrchLog": "Secrch",
+ "Created": "Created",
+ "Updated": "Updated",
+ "Deleted": "Deleted",
+ "ShowLogDialog": "Show log",
+ "DeleteLog": "Delete log",
+ "MachineName": "Machine",
+ "Environment": "Environment",
+ "Context": "Context",
+ "RequestId": "Request Id",
+ "RequestPath": "Request Path",
+ "ProcessId": "Process Id",
+ "ThreadId": "Thread Id",
+ "ActionId": "Action Id",
+ "ConnectionId": "Connection Id",
+ "Depth": "Depth",
+ "Class": "Class",
+ "Message": "Message",
+ "Source": "Source",
+ "StackTrace": "Stack Trace",
+ "HResult": "HResult",
+ "HelpURL": "Help Url",
+ "TimeStamp": "Timestamp",
+ "Level": "Level",
+ "Fields": "Fields",
+ "Exceptions": "Exceptions"
+ }
+}
\ No newline at end of file
diff --git a/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/Localization/Resources/zh-Hans.json b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/Localization/Resources/zh-Hans.json
new file mode 100644
index 0000000..4f86c82
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/Localization/Resources/zh-Hans.json
@@ -0,0 +1,88 @@
+{
+ "culture": "zh-Hans",
+ "texts": {
+ "Permissions:Auditing": "内部审计",
+ "Permissions:AuditLog": "审计日志",
+ "Permissions:SecurityLog": "安全日志",
+ "Permissions:DeleteLog": "删除日志",
+ "Features:Auditing": "内部审计",
+ "Features:DisplayName:AuditLog": "审计日志",
+ "Features:Description:AuditLog": "是否启用审计日志功能",
+ "Features:DisplayName:SecurityLog": "安全日志",
+ "Features:Description:SecurityLog": "是否启用安全日志功能",
+ "SecurityLog": "安全日志",
+ "AuditLog": "审计日志",
+ "Logging": "系统日志",
+ "Application": "应用信息",
+ "ApplicationName": "应用名称",
+ "TenantId": "租户标识",
+ "TenantName": "租户名称",
+ "ImpersonatorTenantId": "模拟租户",
+ "UserInfo": "用户信息",
+ "UserId": "用户标识",
+ "UserName": "用户名称",
+ "ImpersonatorUserId": "模拟用户",
+ "ClientId": "客户端标识",
+ "ClientName": "客户端名称",
+ "ClientIpAddress": "客户端地址",
+ "BrowserInfo": "浏览器信息",
+ "Operation": "操作信息",
+ "HttpMethod": "请求方法",
+ "RequestUrl": "请求路径",
+ "HttpStatusCode": "响应状态",
+ "HasException": "包含异常",
+ "ExecutionTime": "调用时间",
+ "MinExecutionDuration": "最短响应时间(ms)",
+ "MaxExecutionDuration": "最长响应时间(ms)",
+ "ExecutionDuration": "响应时间(ms)",
+ "Identity": "主体名称",
+ "ActionName": "方法名称",
+ "CreationTime": "创建时间",
+ "Additional": "附加信息",
+ "CorrelationId": "链路标识",
+ "StartTime": "开始时间",
+ "EndTime": "结束时间",
+ "SelectDateTime": "选择日期时间",
+ "InvokeMethod": "调用方法",
+ "ServiceName": "服务名称",
+ "MethodName": "方法名称",
+ "Parameters": "参数列表",
+ "EntitiesChanged": "实体变更",
+ "ChangeType": "变更类型",
+ "EntityTypeFullName": "实体类型",
+ "EntityId": "实体标识",
+ "PropertyChanges": "属性变更",
+ "PropertyName": "属性名称",
+ "NewValue": "当前值",
+ "OriginalValue": "原始值",
+ "PropertyTypeFullName": "属性类型",
+ "Exception": "异常信息",
+ "StackTrack": "异常堆栈",
+ "SecrchLog": "查询日志",
+ "Created": "新增",
+ "Updated": "修改",
+ "Deleted": "删除",
+ "ShowLogDialog": "查看日志",
+ "DeleteLog": "删除日志",
+ "MachineName": "机器名称",
+ "Environment": "应用环境",
+ "Context": "上下文",
+ "RequestId": "请求标识",
+ "RequestPath": "请求路径",
+ "ProcessId": "进程标识",
+ "ThreadId": "线程标识",
+ "ActionId": "方法标识",
+ "ConnectionId": "连接标识",
+ "Depth": "深度",
+ "Class": "类型",
+ "Message": "信息",
+ "Source": "来源",
+ "StackTrace": "堆栈",
+ "HResult": "代码",
+ "HelpURL": "帮助",
+ "TimeStamp": "时间戳",
+ "Level": "级别",
+ "Fields": "字段",
+ "Exceptions": "错误信息"
+ }
+}
\ No newline at end of file
diff --git a/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/Logging/Dto/LogDto.cs b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/Logging/Dto/LogDto.cs
new file mode 100644
index 0000000..4511194
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/Logging/Dto/LogDto.cs
@@ -0,0 +1,15 @@
+using Microsoft.Extensions.Logging;
+using System;
+using System.Collections.Generic;
+
+namespace Sanhe.Abp.Auditing.Logging.Dto
+{
+ public class LogDto
+ {
+ public DateTime TimeStamp { get; set; }
+ public LogLevel Level { get; set; }
+ public string Message { get; set; }
+ public LogFieldDto Fields { get; set; }
+ public List Exceptions { get; set; }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/Logging/Dto/LogExceptionDto.cs b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/Logging/Dto/LogExceptionDto.cs
new file mode 100644
index 0000000..c4632c8
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/Logging/Dto/LogExceptionDto.cs
@@ -0,0 +1,13 @@
+namespace Sanhe.Abp.Auditing.Logging.Dto
+{
+ public class LogExceptionDto
+ {
+ public int Depth { get; set; }
+ public string Class { get; set; }
+ public string Message { get; set; }
+ public string Source { get; set; }
+ public string StackTrace { get; set; }
+ public int HResult { get; set; }
+ public string HelpURL { get; set; }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/Logging/Dto/LogFieldDto.cs b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/Logging/Dto/LogFieldDto.cs
new file mode 100644
index 0000000..f23d5e6
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/Logging/Dto/LogFieldDto.cs
@@ -0,0 +1,21 @@
+namespace Sanhe.Abp.Auditing.Logging.Dto
+{
+ public class LogFieldDto
+ {
+ public string Id { get; set; }
+ public string MachineName { get; set; }
+ public string Environment { get; set; }
+ public string Application { get; set; }
+ public string Context { get; set; }
+ public string ActionId { get; set; }
+ public string ActionName { get; set; }
+ public string RequestId { get; set; }
+ public string RequestPath { get; set; }
+ public string ConnectionId { get; set; }
+ public string CorrelationId { get; set; }
+ public string ClientId { get; set; }
+ public string UserId { get; set; }
+ public int ProcessId { get; set; }
+ public int ThreadId { get; set; }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/Logging/Dto/LogGetByPagedDto.cs b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/Logging/Dto/LogGetByPagedDto.cs
new file mode 100644
index 0000000..0589eb2
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/Logging/Dto/LogGetByPagedDto.cs
@@ -0,0 +1,23 @@
+using Microsoft.Extensions.Logging;
+using System;
+using Volo.Abp.Application.Dtos;
+
+namespace Sanhe.Abp.Auditing.Logging.Dto
+{
+ public class LogGetByPagedDto : PagedAndSortedResultRequestDto
+ {
+ public DateTime? StartTime { get; set; }
+ public DateTime? EndTime { get; set; }
+ public LogLevel? Level { get; set; }
+ public string MachineName { get; set; }
+ public string Environment { get; set; }
+ public string Application { get; set; }
+ public string Context { get; set; }
+ public string RequestId { get; set; }
+ public string RequestPath { get; set; }
+ public string CorrelationId { get; set; }
+ public int? ProcessId { get; set; }
+ public int? ThreadId { get; set; }
+ public bool? HasException { get; set; }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/Logging/ILogAppService.cs b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/Logging/ILogAppService.cs
new file mode 100644
index 0000000..56b429d
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/Logging/ILogAppService.cs
@@ -0,0 +1,14 @@
+using Sanhe.Abp.Auditing.Logging.Dto;
+using System.Threading.Tasks;
+using Volo.Abp.Application.Dtos;
+using Volo.Abp.Application.Services;
+
+namespace Sanhe.Abp.Auditing.Logging
+{
+ public interface ILogAppService : IApplicationService
+ {
+ Task GetAsync(string id);
+
+ Task> GetListAsync(LogGetByPagedDto input);
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/Permissions/AuditingPermissionDefinitionProvider.cs b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/Permissions/AuditingPermissionDefinitionProvider.cs
new file mode 100644
index 0000000..f6d3e95
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/Permissions/AuditingPermissionDefinitionProvider.cs
@@ -0,0 +1,35 @@
+using Volo.Abp.AuditLogging.Localization;
+using Volo.Abp.Authorization.Permissions;
+using Volo.Abp.Localization;
+
+namespace Sanhe.Abp.Auditing.Permissions
+{
+ public class AuditingPermissionDefinitionProvider : PermissionDefinitionProvider
+ {
+ public override void Define(IPermissionDefinitionContext context)
+ {
+ var auditingGroup = context.AddGroup(
+ name: AuditingPermissionNames.GroupName,
+ displayName: L("Permissions:Auditing"));
+
+ var auditLogPermission = auditingGroup.AddPermission(
+ name: AuditingPermissionNames.AuditLog.Default,
+ displayName: L("Permissions:AuditLog"));
+ auditLogPermission.AddChild(
+ name: AuditingPermissionNames.AuditLog.Delete,
+ displayName: L("Permissions:DeleteLog"));
+
+ var securityLogPermission = auditingGroup.AddPermission(
+ name: AuditingPermissionNames.SecurityLog.Default,
+ displayName: L("Permissions:SecurityLog"));
+ securityLogPermission.AddChild(
+ name: AuditingPermissionNames.SecurityLog.Delete,
+ displayName: L("Permissions:DeleteLog"));
+ }
+
+ protected LocalizableString L(string name)
+ {
+ return LocalizableString.Create(name);
+ }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/Permissions/AuditingPermissionNames.cs b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/Permissions/AuditingPermissionNames.cs
new file mode 100644
index 0000000..0d04eaa
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/Permissions/AuditingPermissionNames.cs
@@ -0,0 +1,18 @@
+namespace Sanhe.Abp.Auditing.Permissions
+{
+ public class AuditingPermissionNames
+ {
+ public const string GroupName = "AbpAuditing";
+ public class AuditLog
+ {
+ public const string Default = GroupName + ".AuditLog";
+ public const string Delete = Default + ".Delete";
+ }
+
+ public class SecurityLog
+ {
+ public const string Default = GroupName + ".SecurityLog";
+ public const string Delete = Default + ".Delete";
+ }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/SecurityLogs/ISecurityLogAppService.cs b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/SecurityLogs/ISecurityLogAppService.cs
new file mode 100644
index 0000000..63ed3f9
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/SecurityLogs/ISecurityLogAppService.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Threading.Tasks;
+using Volo.Abp.Application.Dtos;
+using Volo.Abp.Application.Services;
+
+namespace Sanhe.Abp.Auditing.SecurityLogs
+{
+ public interface ISecurityLogAppService : IApplicationService
+ {
+ Task> GetListAsync(SecurityLogGetByPagedDto input);
+
+ Task GetAsync(Guid id);
+
+ Task DeleteAsync(Guid id);
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/SecurityLogs/SecurityLogDto.cs b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/SecurityLogs/SecurityLogDto.cs
new file mode 100644
index 0000000..f4c4a13
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/SecurityLogs/SecurityLogDto.cs
@@ -0,0 +1,30 @@
+using System;
+using Volo.Abp.Application.Dtos;
+
+namespace Sanhe.Abp.Auditing.SecurityLogs
+{
+ public class SecurityLogDto : ExtensibleEntityDto
+ {
+ public string ApplicationName { get; set; }
+
+ public string Identity { get; set; }
+
+ public string Action { get; set; }
+
+ public Guid? UserId { get; set; }
+
+ public string UserName { get; set; }
+
+ public string TenantName { get; set; }
+
+ public string ClientId { get; set; }
+
+ public string CorrelationId { get; set; }
+
+ public string ClientIpAddress { get; set; }
+
+ public string BrowserInfo { get; set; }
+
+ public DateTime CreationTime { get; set; }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/SecurityLogs/SecurityLogGetByPagedDto.cs b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/SecurityLogs/SecurityLogGetByPagedDto.cs
new file mode 100644
index 0000000..4919af7
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.Auditing.Application.Contracts/Sanhe/Abp/Auditing/SecurityLogs/SecurityLogGetByPagedDto.cs
@@ -0,0 +1,18 @@
+using System;
+using Volo.Abp.Application.Dtos;
+
+namespace Sanhe.Abp.Auditing.SecurityLogs
+{
+ public class SecurityLogGetByPagedDto : PagedAndSortedResultRequestDto
+ {
+ public DateTime? StartTime { get; set; }
+ public DateTime? EndTime { get; set; }
+ public string ApplicationName { get; set; }
+ public string Identity { get; set; }
+ public string ActionName { get; set; }
+ public Guid? UserId { get; set; }
+ public string UserName { get; set; }
+ public string ClientId { get; set; }
+ public string CorrelationId { get; set; }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.Auditing.Application/FodyWeavers.xml b/modules/auditing/Sanhe.Abp.Auditing.Application/FodyWeavers.xml
new file mode 100644
index 0000000..1715698
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.Auditing.Application/FodyWeavers.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/modules/auditing/Sanhe.Abp.Auditing.Application/Sanhe.Abp.Auditing.Application.csproj b/modules/auditing/Sanhe.Abp.Auditing.Application/Sanhe.Abp.Auditing.Application.csproj
new file mode 100644
index 0000000..44b627e
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.Auditing.Application/Sanhe.Abp.Auditing.Application.csproj
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+ netstandard2.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/auditing/Sanhe.Abp.Auditing.Application/Sanhe/Abp/Auditing/AbpAuditingApplicationModule.cs b/modules/auditing/Sanhe.Abp.Auditing.Application/Sanhe/Abp/Auditing/AbpAuditingApplicationModule.cs
new file mode 100644
index 0000000..599afac
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.Auditing.Application/Sanhe/Abp/Auditing/AbpAuditingApplicationModule.cs
@@ -0,0 +1,24 @@
+using Microsoft.Extensions.DependencyInjection;
+using Sanhe.Abp.AuditLogging;
+using Volo.Abp.AutoMapper;
+using Volo.Abp.Modularity;
+
+namespace Sanhe.Abp.Auditing
+{
+ [DependsOn(
+ typeof(AbpAutoMapperModule),
+ typeof(AbpAuditLoggingModule),
+ typeof(AbpAuditingApplicationContractsModule))]
+ public class AbpAuditingApplicationModule : AbpModule
+ {
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ context.Services.AddAutoMapperObjectMapper();
+
+ Configure(options =>
+ {
+ options.AddProfile(validate: true);
+ });
+ }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.Auditing.Application/Sanhe/Abp/Auditing/AbpAuditingMapperProfile.cs b/modules/auditing/Sanhe.Abp.Auditing.Application/Sanhe/Abp/Auditing/AbpAuditingMapperProfile.cs
new file mode 100644
index 0000000..a5b8f59
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.Auditing.Application/Sanhe/Abp/Auditing/AbpAuditingMapperProfile.cs
@@ -0,0 +1,31 @@
+using AutoMapper;
+using Sanhe.Abp.Auditing.AuditLogs;
+using Sanhe.Abp.Auditing.Logging.Dto;
+using Sanhe.Abp.Auditing.SecurityLogs;
+using Sanhe.Abp.AuditLogging;
+using Sanhe.Abp.Logging;
+
+namespace Sanhe.Abp.Auditing
+{
+ public class AbpAuditingMapperProfile : Profile
+ {
+ public AbpAuditingMapperProfile()
+ {
+ CreateMap()
+ .MapExtraProperties();
+ CreateMap();
+ CreateMap();
+ CreateMap()
+ .MapExtraProperties();
+ CreateMap()
+ .MapExtraProperties();
+
+ CreateMap()
+ .MapExtraProperties();
+
+ CreateMap();
+ CreateMap();
+ CreateMap();
+ }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.Auditing.Application/Sanhe/Abp/Auditing/AuditLogs/AuditLogAppService.cs b/modules/auditing/Sanhe.Abp.Auditing.Application/Sanhe/Abp/Auditing/AuditLogs/AuditLogAppService.cs
new file mode 100644
index 0000000..f3984fe
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.Auditing.Application/Sanhe/Abp/Auditing/AuditLogs/AuditLogAppService.cs
@@ -0,0 +1,63 @@
+using Microsoft.AspNetCore.Authorization;
+using Sanhe.Abp.Auditing.Features;
+using Sanhe.Abp.Auditing.Permissions;
+using Sanhe.Abp.AuditLogging;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Threading.Tasks;
+using Volo.Abp.Application.Dtos;
+using Volo.Abp.Features;
+
+namespace Sanhe.Abp.Auditing.AuditLogs
+{
+ [Authorize(AuditingPermissionNames.AuditLog.Default)]
+ [RequiresFeature(AuditingFeatureNames.Logging.AuditLog)]
+ public class AuditLogAppService : AuditingApplicationServiceBase, IAuditLogAppService
+ {
+ protected IAuditLogManager AuditLogManager { get; }
+
+ public AuditLogAppService(IAuditLogManager auditLogManager)
+ {
+ AuditLogManager = auditLogManager;
+ }
+
+ public virtual async Task GetAsync(Guid id)
+ {
+ var auditLog = await AuditLogManager.GetAsync(id, includeDetails: true);
+
+ return ObjectMapper.Map(auditLog);
+ }
+
+ public virtual async Task> GetListAsync(AuditLogGetByPagedDto input)
+ {
+ var auditLogCount = await AuditLogManager
+ .GetCountAsync(input.StartTime, input.EndTime,
+ input.HttpMethod, input.Url,
+ input.UserId, input.UserName,
+ input.ApplicationName, input.CorrelationId,
+ input.ClientId, input.ClientIpAddress,
+ input.MaxExecutionDuration, input.MinExecutionDuration,
+ input.HasException, input.HttpStatusCode);
+
+ var auditLogs = await AuditLogManager
+ .GetListAsync(input.Sorting, input.MaxResultCount, input.SkipCount,
+ input.StartTime, input.EndTime,
+ input.HttpMethod, input.Url,
+ input.UserId, input.UserName,
+ input.ApplicationName, input.CorrelationId,
+ input.ClientId, input.ClientIpAddress,
+ input.MaxExecutionDuration, input.MinExecutionDuration,
+ input.HasException, input.HttpStatusCode, includeDetails: false);
+
+ return new PagedResultDto(auditLogCount,
+ ObjectMapper.Map, List>(auditLogs));
+ }
+
+ [Authorize(AuditingPermissionNames.AuditLog.Delete)]
+ public virtual async Task DeleteAsync([Required] Guid id)
+ {
+ await AuditLogManager.DeleteAsync(id);
+ }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.Auditing.Application/Sanhe/Abp/Auditing/AuditLogs/EntityChangesAppService.cs b/modules/auditing/Sanhe.Abp.Auditing.Application/Sanhe/Abp/Auditing/AuditLogs/EntityChangesAppService.cs
new file mode 100644
index 0000000..f9a2ac0
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.Auditing.Application/Sanhe/Abp/Auditing/AuditLogs/EntityChangesAppService.cs
@@ -0,0 +1,61 @@
+using Microsoft.AspNetCore.Authorization;
+using Sanhe.Abp.Auditing.Features;
+using Sanhe.Abp.Auditing.Permissions;
+using Sanhe.Abp.AuditLogging;
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Volo.Abp.Application.Dtos;
+using Volo.Abp.Features;
+
+namespace Sanhe.Abp.Auditing.AuditLogs;
+
+[Authorize(AuditingPermissionNames.AuditLog.Default)]
+[RequiresFeature(AuditingFeatureNames.Logging.AuditLog)]
+public class EntityChangesAppService : AuditingApplicationServiceBase, IEntityChangesAppService
+{
+ protected IEntityChangeStore EntityChangeStore { get; }
+
+ public EntityChangesAppService(IEntityChangeStore entityChangeStore)
+ {
+ EntityChangeStore = entityChangeStore;
+ }
+
+ public async virtual Task GetAsync(Guid id)
+ {
+ var entityChange = await EntityChangeStore.GetAsync(id);
+
+ return ObjectMapper.Map(entityChange);
+ }
+
+ public async virtual Task> GetListAsync(EntityChangeGetByPagedDto input)
+ {
+ var totalCount = await EntityChangeStore.GetCountAsync(
+ input.AuditLogId, input.StartTime, input.EndTime,
+ input.ChangeType, input.EntityId, input.EntityTypeFullName);
+
+ var entityChanges = await EntityChangeStore.GetListAsync(
+ input.Sorting, input.MaxResultCount, input.SkipCount,
+ input.AuditLogId, input.StartTime, input.EndTime,
+ input.ChangeType, input.EntityId, input.EntityTypeFullName);
+
+ return new PagedResultDto(totalCount,
+ ObjectMapper.Map, List>(entityChanges));
+ }
+
+ public async virtual Task GetWithUsernameAsync(Guid id)
+ {
+ var entityChangeWithUsername = await EntityChangeStore.GetWithUsernameAsync(id);
+
+ return ObjectMapper.Map(entityChangeWithUsername);
+ }
+
+ public async virtual Task> GetWithUsernameAsync(EntityChangeGetWithUsernameDto input)
+ {
+ var entityChangeWithUsernames = await EntityChangeStore.GetWithUsernameAsync(
+ input.EntityId, input.EntityTypeFullName);
+
+ return new ListResultDto(
+ ObjectMapper.Map, List>(entityChangeWithUsernames));
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.Auditing.Application/Sanhe/Abp/Auditing/AuditingApplicationServiceBase.cs b/modules/auditing/Sanhe.Abp.Auditing.Application/Sanhe/Abp/Auditing/AuditingApplicationServiceBase.cs
new file mode 100644
index 0000000..9cf36b4
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.Auditing.Application/Sanhe/Abp/Auditing/AuditingApplicationServiceBase.cs
@@ -0,0 +1,14 @@
+using Volo.Abp.Application.Services;
+using Volo.Abp.AuditLogging.Localization;
+
+namespace Sanhe.Abp.Auditing
+{
+ public abstract class AuditingApplicationServiceBase : ApplicationService
+ {
+ protected AuditingApplicationServiceBase()
+ {
+ LocalizationResource = typeof(AuditLoggingResource);
+ ObjectMapperContext = typeof(AbpAuditingApplicationModule);
+ }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.Auditing.Application/Sanhe/Abp/Auditing/Logging/LogAppService.cs b/modules/auditing/Sanhe.Abp.Auditing.Application/Sanhe/Abp/Auditing/Logging/LogAppService.cs
new file mode 100644
index 0000000..c4a90f1
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.Auditing.Application/Sanhe/Abp/Auditing/Logging/LogAppService.cs
@@ -0,0 +1,49 @@
+using Sanhe.Abp.Auditing.Logging.Dto;
+using Sanhe.Abp.Logging;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Volo.Abp.Application.Dtos;
+
+namespace Sanhe.Abp.Auditing.Logging
+{
+ public class LogAppService : AuditingApplicationServiceBase, ILogAppService
+ {
+ private readonly ILoggingManager _manager;
+
+ public LogAppService(ILoggingManager manager)
+ {
+ _manager = manager;
+ }
+
+ public virtual async Task GetAsync(string id)
+ {
+ var log = await _manager.GetAsync(id);
+
+ return ObjectMapper.Map(log);
+ }
+
+ public virtual async Task> GetListAsync(LogGetByPagedDto input)
+ {
+ var count = await _manager.GetCountAsync(
+ input.StartTime, input.EndTime, input.Level,
+ input.MachineName, input.Environment,
+ input.Application, input.Context,
+ input.RequestId, input.RequestPath,
+ input.CorrelationId, input.ProcessId,
+ input.ThreadId, input.HasException);
+
+ var logs = await _manager.GetListAsync(
+ input.Sorting, input.MaxResultCount, input.SkipCount,
+ input.StartTime, input.EndTime, input.Level,
+ input.MachineName, input.Environment,
+ input.Application, input.Context,
+ input.RequestId, input.RequestPath,
+ input.CorrelationId, input.ProcessId,
+ input.ThreadId, input.HasException,
+ includeDetails: false);
+
+ return new PagedResultDto(count,
+ ObjectMapper.Map, List>(logs));
+ }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.Auditing.Application/Sanhe/Abp/Auditing/SecurityLogs/SecurityLogAppService.cs b/modules/auditing/Sanhe.Abp.Auditing.Application/Sanhe/Abp/Auditing/SecurityLogs/SecurityLogAppService.cs
new file mode 100644
index 0000000..49a95da
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.Auditing.Application/Sanhe/Abp/Auditing/SecurityLogs/SecurityLogAppService.cs
@@ -0,0 +1,57 @@
+using Microsoft.AspNetCore.Authorization;
+using Sanhe.Abp.Auditing.Features;
+using Sanhe.Abp.Auditing.Permissions;
+using Sanhe.Abp.AuditLogging;
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Volo.Abp.Application.Dtos;
+using Volo.Abp.Features;
+
+namespace Sanhe.Abp.Auditing.SecurityLogs
+{
+ [Authorize(AuditingPermissionNames.SecurityLog.Default)]
+ [RequiresFeature(AuditingFeatureNames.Logging.SecurityLog)]
+ public class SecurityLogAppService : AuditingApplicationServiceBase, ISecurityLogAppService
+ {
+ protected ISecurityLogManager SecurityLogManager { get; }
+
+ public SecurityLogAppService(ISecurityLogManager securityLogManager)
+ {
+ SecurityLogManager = securityLogManager;
+ }
+
+ public virtual async Task GetAsync(Guid id)
+ {
+ var securityLog = await SecurityLogManager.GetAsync(id, includeDetails: true);
+
+ return ObjectMapper.Map(securityLog);
+ }
+
+ public virtual async Task> GetListAsync(SecurityLogGetByPagedDto input)
+ {
+ var securityLogCount = await SecurityLogManager
+ .GetCountAsync(input.StartTime, input.EndTime,
+ input.ApplicationName, input.Identity, input.ActionName,
+ input.UserId, input.UserName, input.ClientId, input.CorrelationId
+ );
+
+ var securityLogs = await SecurityLogManager
+ .GetListAsync(input.Sorting, input.MaxResultCount, input.SkipCount,
+ input.StartTime, input.EndTime,
+ input.ApplicationName, input.Identity, input.ActionName,
+ input.UserId, input.UserName, input.ClientId, input.CorrelationId,
+ includeDetails: false
+ );
+
+ return new PagedResultDto(securityLogCount,
+ ObjectMapper.Map, List>(securityLogs));
+ }
+
+ [Authorize(AuditingPermissionNames.SecurityLog.Delete)]
+ public virtual async Task DeleteAsync(Guid id)
+ {
+ await SecurityLogManager.DeleteAsync(id);
+ }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.Auditing.HttpApi/FodyWeavers.xml b/modules/auditing/Sanhe.Abp.Auditing.HttpApi/FodyWeavers.xml
new file mode 100644
index 0000000..1715698
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.Auditing.HttpApi/FodyWeavers.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/modules/auditing/Sanhe.Abp.Auditing.HttpApi/Sanhe.Abp.Auditing.HttpApi.csproj b/modules/auditing/Sanhe.Abp.Auditing.HttpApi/Sanhe.Abp.Auditing.HttpApi.csproj
new file mode 100644
index 0000000..d356b6a
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.Auditing.HttpApi/Sanhe.Abp.Auditing.HttpApi.csproj
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+ net6.0
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/auditing/Sanhe.Abp.Auditing.HttpApi/Sanhe/Abp/Auditing/AbpAuditingHttpApiModule.cs b/modules/auditing/Sanhe.Abp.Auditing.HttpApi/Sanhe/Abp/Auditing/AbpAuditingHttpApiModule.cs
new file mode 100644
index 0000000..468ff15
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.Auditing.HttpApi/Sanhe/Abp/Auditing/AbpAuditingHttpApiModule.cs
@@ -0,0 +1,41 @@
+using Localization.Resources.AbpUi;
+using Microsoft.Extensions.DependencyInjection;
+using Volo.Abp.AspNetCore.Mvc;
+using Volo.Abp.AspNetCore.Mvc.Localization;
+using Volo.Abp.AuditLogging.Localization;
+using Volo.Abp.Localization;
+using Volo.Abp.Modularity;
+
+namespace Sanhe.Abp.Auditing
+{
+ [DependsOn(
+ typeof(AbpAspNetCoreMvcModule),
+ typeof(AbpAuditingApplicationContractsModule))]
+ public class AbpAuditingHttpApiModule : AbpModule
+ {
+ public override void PreConfigureServices(ServiceConfigurationContext context)
+ {
+ PreConfigure(mvcBuilder =>
+ {
+ mvcBuilder.AddApplicationPartIfNotExists(typeof(AbpAuditingHttpApiModule).Assembly);
+ });
+
+ PreConfigure(options =>
+ {
+ options.AddAssemblyResource(typeof(AuditLoggingResource), typeof(AbpAuditingApplicationContractsModule).Assembly);
+ });
+ }
+
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ Configure(options =>
+ {
+ options.Resources
+ .Get()
+ .AddBaseTypes(
+ typeof(AbpUiResource)
+ );
+ });
+ }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.Auditing.HttpApi/Sanhe/Abp/Auditing/AuditLogs/AuditLogController.cs b/modules/auditing/Sanhe.Abp.Auditing.HttpApi/Sanhe/Abp/Auditing/AuditLogs/AuditLogController.cs
new file mode 100644
index 0000000..f201572
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.Auditing.HttpApi/Sanhe/Abp/Auditing/AuditLogs/AuditLogController.cs
@@ -0,0 +1,61 @@
+using Microsoft.AspNetCore.Mvc;
+using System;
+using System.Threading.Tasks;
+using Volo.Abp;
+using Volo.Abp.Application.Dtos;
+using Volo.Abp.AspNetCore.Mvc;
+
+namespace Sanhe.Abp.Auditing.AuditLogs
+{
+ ///
+ /// 审计日志
+ ///
+ [RemoteService(Name = AuditingRemoteServiceConsts.RemoteServiceName)]
+ [Area("auditing")]
+ [ControllerName("audit-log")]
+ [Route("api/auditing/audit-log")]
+ public class AuditLogController : AbpController, IAuditLogAppService
+ {
+ protected IAuditLogAppService AuditLogAppService { get; }
+
+ public AuditLogController(IAuditLogAppService auditLogAppService)
+ {
+ AuditLogAppService = auditLogAppService;
+ }
+
+ ///
+ /// 根据Id获取
+ ///
+ ///
+ ///
+ [HttpGet]
+ [Route("{id}")]
+ public virtual Task GetAsync(Guid id)
+ {
+ return AuditLogAppService.GetAsync(id);
+ }
+
+ ///
+ /// 分页获取
+ ///
+ ///
+ ///
+ [HttpGet]
+ public virtual Task> GetListAsync(AuditLogGetByPagedDto input)
+ {
+ return AuditLogAppService.GetListAsync(input);
+ }
+
+ ///
+ /// 根据Id删除
+ ///
+ ///
+ ///
+ [HttpDelete]
+ [Route("{id}")]
+ public virtual Task DeleteAsync(Guid id)
+ {
+ return AuditLogAppService.DeleteAsync(id);
+ }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.Auditing.HttpApi/Sanhe/Abp/Auditing/AuditLogs/EntityChangesController.cs b/modules/auditing/Sanhe.Abp.Auditing.HttpApi/Sanhe/Abp/Auditing/AuditLogs/EntityChangesController.cs
new file mode 100644
index 0000000..7145ed3
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.Auditing.HttpApi/Sanhe/Abp/Auditing/AuditLogs/EntityChangesController.cs
@@ -0,0 +1,49 @@
+using Microsoft.AspNetCore.Mvc;
+using System;
+using System.Threading.Tasks;
+using Volo.Abp;
+using Volo.Abp.Application.Dtos;
+using Volo.Abp.AspNetCore.Mvc;
+
+namespace Sanhe.Abp.Auditing.AuditLogs;
+
+[RemoteService(Name = AuditingRemoteServiceConsts.RemoteServiceName)]
+[Area("auditing")]
+[ControllerName("entity-changes")]
+[Route("api/auditing/entity-changes")]
+public class EntityChangesController : AbpControllerBase, IEntityChangesAppService
+{
+ protected IEntityChangesAppService EntityChangeAppService { get; }
+
+ public EntityChangesController(IEntityChangesAppService entityChangeAppService)
+ {
+ EntityChangeAppService = entityChangeAppService;
+ }
+
+ [HttpGet]
+ [Route("{id}")]
+ public Task GetAsync(Guid id)
+ {
+ return EntityChangeAppService.GetAsync(id);
+ }
+
+ [HttpGet]
+ public Task> GetListAsync(EntityChangeGetByPagedDto input)
+ {
+ return EntityChangeAppService.GetListAsync(input);
+ }
+
+ [HttpGet]
+ [Route("with-username/{id}")]
+ public Task GetWithUsernameAsync(Guid id)
+ {
+ return EntityChangeAppService.GetWithUsernameAsync(id);
+ }
+
+ [HttpGet]
+ [Route("with-username")]
+ public Task> GetWithUsernameAsync(EntityChangeGetWithUsernameDto input)
+ {
+ return EntityChangeAppService.GetWithUsernameAsync(input);
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.Auditing.HttpApi/Sanhe/Abp/Auditing/Logging/LogController.cs b/modules/auditing/Sanhe.Abp.Auditing.HttpApi/Sanhe/Abp/Auditing/Logging/LogController.cs
new file mode 100644
index 0000000..b7bde9b
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.Auditing.HttpApi/Sanhe/Abp/Auditing/Logging/LogController.cs
@@ -0,0 +1,49 @@
+using Microsoft.AspNetCore.Mvc;
+using Sanhe.Abp.Auditing.Logging.Dto;
+using System.Threading.Tasks;
+using Volo.Abp;
+using Volo.Abp.Application.Dtos;
+using Volo.Abp.AspNetCore.Mvc;
+
+namespace Sanhe.Abp.Auditing.Logging
+{
+ ///
+ /// 日志
+ ///
+ [RemoteService(Name = AuditingRemoteServiceConsts.RemoteServiceName)]
+ [Area("auditing")]
+ [ControllerName("logging")]
+ [Route("api/auditing/logging")]
+ public class LogController : AbpController, ILogAppService
+ {
+ private readonly ILogAppService _service;
+
+ public LogController(ILogAppService service)
+ {
+ _service = service;
+ }
+
+ ///
+ /// 根据Id获取
+ ///
+ ///
+ ///
+ [HttpGet]
+ [Route("{id}")]
+ public virtual Task GetAsync(string id)
+ {
+ return _service.GetAsync(id);
+ }
+
+ ///
+ /// 分页获取
+ ///
+ ///
+ ///
+ [HttpGet]
+ public virtual Task> GetListAsync(LogGetByPagedDto input)
+ {
+ return _service.GetListAsync(input);
+ }
+ }
+}
diff --git a/modules/auditing/Sanhe.Abp.Auditing.HttpApi/Sanhe/Abp/Auditing/SecurityLogs/SecurityLogController.cs b/modules/auditing/Sanhe.Abp.Auditing.HttpApi/Sanhe/Abp/Auditing/SecurityLogs/SecurityLogController.cs
new file mode 100644
index 0000000..59332b8
--- /dev/null
+++ b/modules/auditing/Sanhe.Abp.Auditing.HttpApi/Sanhe/Abp/Auditing/SecurityLogs/SecurityLogController.cs
@@ -0,0 +1,62 @@
+using Microsoft.AspNetCore.Mvc;
+using System;
+using System.Threading.Tasks;
+using Volo.Abp;
+using Volo.Abp.Application.Dtos;
+using Volo.Abp.AspNetCore.Mvc;
+
+namespace Sanhe.Abp.Auditing.SecurityLogs
+{
+ ///
+ /// 安全日志
+ ///
+ [RemoteService(Name = AuditingRemoteServiceConsts.RemoteServiceName)]
+ [Area("auditing")]
+ [ControllerName("security-log")]
+ [Route("api/auditing/security-log")]
+ public class SecurityLogController : AbpController, ISecurityLogAppService
+ {
+ protected ISecurityLogAppService SecurityLogAppService { get; }
+
+ public SecurityLogController(ISecurityLogAppService securityLogAppService)
+ {
+ SecurityLogAppService = securityLogAppService;
+ }
+
+ ///
+ /// 根据Id获取
+ ///
+ ///
+ ///
+ [HttpGet]
+ [Route("{id}")]
+ public virtual Task GetAsync(Guid id)
+ {
+ return SecurityLogAppService.GetAsync(id);
+ }
+
+ ///
+ /// 分页获取
+ ///
+ ///
+ ///
+ [HttpGet]
+ public virtual Task> GetListAsync(SecurityLogGetByPagedDto input)
+ {
+ return SecurityLogAppService.GetListAsync(input);
+ }
+
+ ///
+ /// 根据Id删除
+ ///
+ ///
+ ///
+ [HttpDelete]
+ [Route("{id}")]
+ public virtual Task DeleteAsync(Guid id)
+ {
+ return SecurityLogAppService.DeleteAsync(id);
+ }
+
+ }
+}
diff --git a/modules/logging/Sanhe.Abp.Logging.Serilog.Elasticsearch/FodyWeavers.xml b/modules/logging/Sanhe.Abp.Logging.Serilog.Elasticsearch/FodyWeavers.xml
new file mode 100644
index 0000000..1715698
--- /dev/null
+++ b/modules/logging/Sanhe.Abp.Logging.Serilog.Elasticsearch/FodyWeavers.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/modules/logging/Sanhe.Abp.Logging.Serilog.Elasticsearch/README.md b/modules/logging/Sanhe.Abp.Logging.Serilog.Elasticsearch/README.md
new file mode 100644
index 0000000..0310e60
--- /dev/null
+++ b/modules/logging/Sanhe.Abp.Logging.Serilog.Elasticsearch/README.md
@@ -0,0 +1,32 @@
+# LINGYUN.Abp.Logging.Serilog.Elasticsearch
+
+ILoggingManager 接口的ES实现, 从ES中检索日志信息
+
+## 模块引用
+
+```csharp
+[DependsOn(typeof(AbpLoggingSerilogElasticsearchModule))]
+public class YouProjectModule : AbpModule
+{
+ // other
+}
+```
+
+## 配置项
+
+* AbpLoggingSerilogElasticsearchOptions.IndexFormat 必须和Serilog配置项中的IndexFormat相同,否则无法定位到正确的索引
+
+## appsettings.json
+
+```json
+{
+ "Logging": {
+ "Serilog": {
+ "Elasticsearch": {
+ "IndexFormat": "logstash-{0:yyyy.MM.dd}"
+ }
+ }
+ }
+}
+
+```
\ No newline at end of file
diff --git a/modules/logging/Sanhe.Abp.Logging.Serilog.Elasticsearch/Sanhe.Abp.Logging.Serilog.Elasticsearch.csproj b/modules/logging/Sanhe.Abp.Logging.Serilog.Elasticsearch/Sanhe.Abp.Logging.Serilog.Elasticsearch.csproj
new file mode 100644
index 0000000..651664e
--- /dev/null
+++ b/modules/logging/Sanhe.Abp.Logging.Serilog.Elasticsearch/Sanhe.Abp.Logging.Serilog.Elasticsearch.csproj
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+ netstandard2.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/logging/Sanhe.Abp.Logging.Serilog.Elasticsearch/Sanhe/Abp/AuditLogging/Serilog/Elasticsearch/AbpLoggingSerilogElasticsearchMapperProfile.cs b/modules/logging/Sanhe.Abp.Logging.Serilog.Elasticsearch/Sanhe/Abp/AuditLogging/Serilog/Elasticsearch/AbpLoggingSerilogElasticsearchMapperProfile.cs
new file mode 100644
index 0000000..af442aa
--- /dev/null
+++ b/modules/logging/Sanhe.Abp.Logging.Serilog.Elasticsearch/Sanhe/Abp/AuditLogging/Serilog/Elasticsearch/AbpLoggingSerilogElasticsearchMapperProfile.cs
@@ -0,0 +1,16 @@
+using AutoMapper;
+using Sanhe.Abp.Logging;
+
+namespace Sanhe.Abp.AuditLogging.Serilog.Elasticsearch
+{
+ public class AbpLoggingSerilogElasticsearchMapperProfile : Profile
+ {
+ public AbpLoggingSerilogElasticsearchMapperProfile()
+ {
+ CreateMap();
+ CreateMap()
+ .ForMember(log => log.Id, map => map.MapFrom(slog => slog.UniqueId.ToString()));
+ CreateMap();
+ }
+ }
+}
diff --git a/modules/logging/Sanhe.Abp.Logging.Serilog.Elasticsearch/Sanhe/Abp/AuditLogging/Serilog/Elasticsearch/AbpLoggingSerilogElasticsearchModule.cs b/modules/logging/Sanhe.Abp.Logging.Serilog.Elasticsearch/Sanhe/Abp/AuditLogging/Serilog/Elasticsearch/AbpLoggingSerilogElasticsearchModule.cs
new file mode 100644
index 0000000..eeaeb79
--- /dev/null
+++ b/modules/logging/Sanhe.Abp.Logging.Serilog.Elasticsearch/Sanhe/Abp/AuditLogging/Serilog/Elasticsearch/AbpLoggingSerilogElasticsearchModule.cs
@@ -0,0 +1,31 @@
+using Sanhe.Abp.Elasticsearch;
+using Microsoft.Extensions.DependencyInjection;
+using Volo.Abp.AutoMapper;
+using Volo.Abp.Json;
+using Volo.Abp.Modularity;
+using Sanhe.Abp.Logging;
+
+namespace Sanhe.Abp.AuditLogging.Serilog.Elasticsearch
+{
+ [DependsOn(
+ typeof(AbpLoggingModule),
+ typeof(AbpElasticsearchModule),
+ typeof(AbpAutoMapperModule),
+ typeof(AbpJsonModule))]
+ public class AbpLoggingSerilogElasticsearchModule : AbpModule
+ {
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ var configuration = context.Services.GetConfiguration();
+
+ Configure(configuration.GetSection("Logging:Serilog:Elasticsearch"));
+
+ context.Services.AddAutoMapperObjectMapper();
+
+ Configure(options =>
+ {
+ options.AddProfile(validate: true);
+ });
+ }
+ }
+}
diff --git a/modules/logging/Sanhe.Abp.Logging.Serilog.Elasticsearch/Sanhe/Abp/AuditLogging/Serilog/Elasticsearch/AbpLoggingSerilogElasticsearchOptions.cs b/modules/logging/Sanhe.Abp.Logging.Serilog.Elasticsearch/Sanhe/Abp/AuditLogging/Serilog/Elasticsearch/AbpLoggingSerilogElasticsearchOptions.cs
new file mode 100644
index 0000000..7a1b812
--- /dev/null
+++ b/modules/logging/Sanhe.Abp.Logging.Serilog.Elasticsearch/Sanhe/Abp/AuditLogging/Serilog/Elasticsearch/AbpLoggingSerilogElasticsearchOptions.cs
@@ -0,0 +1,12 @@
+namespace Sanhe.Abp.AuditLogging.Serilog.Elasticsearch
+{
+ public class AbpLoggingSerilogElasticsearchOptions
+ {
+ public string IndexFormat { get; set; }
+
+ public AbpLoggingSerilogElasticsearchOptions()
+ {
+ IndexFormat = "logstash-{0:yyyy.MM.dd}";
+ }
+ }
+}
diff --git a/modules/logging/Sanhe.Abp.Logging.Serilog.Elasticsearch/Sanhe/Abp/AuditLogging/Serilog/Elasticsearch/SerilogElasticsearchLoggingManager.cs b/modules/logging/Sanhe.Abp.Logging.Serilog.Elasticsearch/Sanhe/Abp/AuditLogging/Serilog/Elasticsearch/SerilogElasticsearchLoggingManager.cs
new file mode 100644
index 0000000..63b33bd
--- /dev/null
+++ b/modules/logging/Sanhe.Abp.Logging.Serilog.Elasticsearch/Sanhe/Abp/AuditLogging/Serilog/Elasticsearch/SerilogElasticsearchLoggingManager.cs
@@ -0,0 +1,412 @@
+using Sanhe.Abp.Elasticsearch;
+using Sanhe.Abp.Serilog.Enrichers.Application;
+using Sanhe.Abp.Serilog.Enrichers.UniqueId;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Logging.Abstractions;
+using Microsoft.Extensions.Options;
+using Nest;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.RegularExpressions;
+using System.Threading;
+using System.Threading.Tasks;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.MultiTenancy;
+using Volo.Abp.ObjectMapping;
+using Sanhe.Abp.Logging;
+
+namespace Sanhe.Abp.AuditLogging.Serilog.Elasticsearch
+{
+ [Dependency(ReplaceServices = true)]
+ public class SerilogElasticsearchLoggingManager : ILoggingManager, ISingletonDependency
+ {
+ private static readonly Regex IndexFormatRegex = new Regex(@"^(.*)(?:\{0\:.+\})(.*)$");
+
+ private readonly IObjectMapper _objectMapper;
+ private readonly ICurrentTenant _currentTenant;
+ private readonly AbpLoggingSerilogElasticsearchOptions _options;
+ private readonly IElasticsearchClientFactory _clientFactory;
+
+ public ILogger Logger { protected get; set; }
+
+ public SerilogElasticsearchLoggingManager(
+ IObjectMapper objectMapper,
+ ICurrentTenant currentTenant,
+ IOptions options,
+ IElasticsearchClientFactory clientFactory)
+ {
+ _objectMapper = objectMapper;
+ _currentTenant = currentTenant;
+ _clientFactory = clientFactory;
+ _options = options.Value;
+
+ Logger = NullLogger.Instance;
+ }
+
+ ///
+ ///
+ ///
+ /// 时间类型或者转换为timestamp都可以查询
+ ///
+ ///
+ public virtual async Task GetAsync(
+ string id,
+ CancellationToken cancellationToken = default)
+ {
+ var client = _clientFactory.Create();
+
+ ISearchResponse response;
+
+ if (_currentTenant.IsAvailable)
+ {
+ /*
+ "query": {
+ "bool": {
+ "must": [
+ {
+ "term": {
+ "fields.TenantId.keyword": {
+ "value": _currentTenant.GetId()
+ }
+ }
+ },
+ {
+ "term": {
+ "fields.UniqueId": {
+ "value": "1474021081433481216"
+ }
+ }
+ }
+ ]
+ }
+ }
+ */
+ response = await client.SearchAsync(
+ dsl =>
+ dsl.Index(CreateIndex())
+ .Query(
+ (q) => q.Bool(
+ (b) => b.Must(
+ (s) => s.Term(
+ (t) => t.Field(GetField(nameof(SerilogInfo.Fields.UniqueId))).Value(id)),
+ (s) => s.Term(
+ (t) => t.Field(GetField(nameof(SerilogInfo.Fields.TenantId))).Value(_currentTenant.GetId()))))),
+ cancellationToken);
+ }
+ else
+ {
+ /*
+ "query": {
+ "bool": {
+ "must": [
+ {
+ "term": {
+ "fields.UniqueId": {
+ "value": "1474021081433481216"
+ }
+ }
+ }
+ ]
+ }
+ }
+ */
+ response = await client.SearchAsync(
+ dsl =>
+ dsl.Index(CreateIndex())
+ .Query(
+ (q) => q.Bool(
+ (b) => b.Must(
+ (s) => s.Term(
+ (t) => t.Field(GetField(nameof(SerilogInfo.Fields.UniqueId))).Value(id))))),
+ cancellationToken);
+ }
+
+ return _objectMapper.Map(response.Documents.FirstOrDefault());
+ }
+
+ public virtual async Task GetCountAsync(
+ DateTime? startTime = null,
+ DateTime? endTime = null,
+ Microsoft.Extensions.Logging.LogLevel? level = null,
+ string machineName = null,
+ string environment = null,
+ string application = null,
+ string context = null,
+ string requestId = null,
+ string requestPath = null,
+ string correlationId = null,
+ int? processId = null,
+ int? threadId = null,
+ bool? hasException = null,
+ CancellationToken cancellationToken = default)
+ {
+ var client = _clientFactory.Create();
+
+ var querys = BuildQueryDescriptor(
+ startTime,
+ endTime,
+ level,
+ machineName,
+ environment,
+ application,
+ context,
+ requestId,
+ requestPath,
+ correlationId,
+ processId,
+ threadId,
+ hasException);
+
+ var response = await client.CountAsync