Browse Source

Merge pull request #14148 from abpframework/DisableLogActionInfo

Add an option to enable/disable AuditLogActionInfo entirely.
pull/14037/head
Berkan Sasmaz 4 years ago
committed by GitHub
parent
commit
eb83f8d1c7
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      docs/en/Audit-Logging.md
  2. 1
      docs/zh-Hans/Audit-Logging.md
  3. 24
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditActionFilter.cs
  4. 24
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditPageFilter.cs
  5. 7
      framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AbpAuditingOptions.cs
  6. 30
      framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingInterceptor.cs
  7. 13
      framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Auditing/AuditTestController_Tests.cs
  8. 13
      framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Auditing/AuditTestPage_Tests.cs
  9. 63
      framework/test/Volo.Abp.Auditing.Tests/Volo/Abp/Auditing/Auditing_Tests.cs

1
docs/en/Audit-Logging.md

@ -41,6 +41,7 @@ Here, a list of the options you can configure:
* `IsEnabledForAnonymousUsers` (default: `true`): If you want to write audit logs only for the authenticated users, set this to `false`. If you save audit logs for anonymous users, you will see `null` for `UserId` values for these users.
* `AlwaysLogOnException` (default: `true`): If you set to true, it always saves the audit log on an exception/error case without checking other options (except `IsEnabled`, which completely disables the audit logging).
* `IsEnabledForGetRequests` (default: `false`): HTTP GET requests should not make any change in the database normally and audit log system doesn't save audit log objects for GET request. Set this to `true` to enable it also for the GET requests.
* `DisableLogActionInfo` (default: `false`):If you set to true, Will no longer log `AuditLogActionInfo`.
* `ApplicationName`: If multiple applications saving audit logs into a single database, set this property to your application name, so you can distinguish the logs of different applications.
* `IgnoredTypes`: A list of `Type`s to be ignored for audit logging. If this is an entity type, changes for this type of entities will not be saved. This list is also used while serializing the action parameters.
* `EntityHistorySelectors`: A list of selectors those are used to determine if an entity type is selected for saving the entity change. See the section below for details.

1
docs/zh-Hans/Audit-Logging.md

@ -42,6 +42,7 @@ Configure<AbpAuditingOptions>(options =>
* `AlwaysLogOnException`(默认值: `true`): 如果设置为 `true`,将始终在异常/错误情况下保存审计日志,不检查其他选项(`IsEnabled` 除外,它完全禁用了审计日志).
* `IsEnabledForGetRequests` (默认值: `false`): HTTP GET请求通常不应该在数据库进行任何更改,审计日志系统不会为GET请求保存审计日志对象. 将此值设置为 `true` 可为GET请求启用审计日志系统.
* `ApplicationName`: 如果有多个应用程序保存审计日志到单一的数据库,使用此属性设置为你的应用程序名称区分不同的应用程序日志.
* `DisableLogActionInfo` (默认值: `false`): 如果设置为 `true`, 将不再记录 `AuditLogActionInfo`.
* `IgnoredTypes`: 审计日志系统忽略的 `Type` 列表. 如果它是实体类型,则不会保存此类型实体的更改. 在序列化操作参数时也使用此列表.
* `EntityHistorySelectors`:选择器列表,用于确定是否选择了用于保存实体更改的实体类型. 有关详细信息请参阅下面的部分.
* `Contributors`: `AuditLogContributor` 实现的列表. 贡献者是扩展审计日志系统的一种方式. 有关详细信息请参阅下面的"审计日志贡献者"部分.

24
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditActionFilter.cs

@ -41,8 +41,12 @@ public class AbpAuditActionFilter : IAsyncActionFilter, ITransientDependency
finally
{
stopwatch.Stop();
auditLogAction.ExecutionDuration = Convert.ToInt32(stopwatch.Elapsed.TotalMilliseconds);
auditLog.Actions.Add(auditLogAction);
if (auditLogAction != null)
{
auditLogAction.ExecutionDuration = Convert.ToInt32(stopwatch.Elapsed.TotalMilliseconds);
auditLog.Actions.Add(auditLogAction);
}
}
}
}
@ -78,12 +82,16 @@ public class AbpAuditActionFilter : IAsyncActionFilter, ITransientDependency
}
auditLog = auditLogScope.Log;
auditLogAction = auditingHelper.CreateAuditLogAction(
auditLog,
context.ActionDescriptor.AsControllerActionDescriptor().ControllerTypeInfo.AsType(),
context.ActionDescriptor.AsControllerActionDescriptor().MethodInfo,
context.ActionArguments
);
if (!options.DisableLogActionInfo)
{
auditLogAction = auditingHelper.CreateAuditLogAction(
auditLog,
context.ActionDescriptor.AsControllerActionDescriptor().ControllerTypeInfo.AsType(),
context.ActionDescriptor.AsControllerActionDescriptor().MethodInfo,
context.ActionArguments
);
}
return true;
}

24
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditPageFilter.cs

@ -46,8 +46,12 @@ public class AbpAuditPageFilter : IAsyncPageFilter, ITransientDependency
finally
{
stopwatch.Stop();
auditLogAction.ExecutionDuration = Convert.ToInt32(stopwatch.Elapsed.TotalMilliseconds);
auditLog.Actions.Add(auditLogAction);
if (auditLogAction != null)
{
auditLogAction.ExecutionDuration = Convert.ToInt32(stopwatch.Elapsed.TotalMilliseconds);
auditLog.Actions.Add(auditLogAction);
}
}
}
}
@ -81,12 +85,16 @@ public class AbpAuditPageFilter : IAsyncPageFilter, ITransientDependency
}
auditLog = auditLogScope.Log;
auditLogAction = auditingHelper.CreateAuditLogAction(
auditLog,
context.HandlerMethod.MethodInfo.DeclaringType,
context.HandlerMethod.MethodInfo,
context.HandlerArguments
);
if (!options.DisableLogActionInfo)
{
auditLogAction = auditingHelper.CreateAuditLogAction(
auditLog,
context.HandlerMethod.MethodInfo.DeclaringType,
context.HandlerMethod.MethodInfo,
context.HandlerArguments
);
}
return true;
}

7
framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AbpAuditingOptions.cs

@ -37,7 +37,7 @@ public class AbpAuditingOptions
/// Default: true.
/// </summary>
public bool AlwaysLogOnException { get; set; }
/// <summary>
/// Disables/enables audit logging for integration services.
/// Default: false.
@ -58,6 +58,11 @@ public class AbpAuditingOptions
/// </summary>
public bool IsEnabledForGetRequests { get; set; }
/// <summary>
/// Default: false.
/// </summary>
public bool DisableLogActionInfo { get; set; }
public AbpAuditingOptions()
{
IsEnabled = true;

30
framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingInterceptor.cs

@ -37,7 +37,7 @@ public class AuditingInterceptor : AbpInterceptor, ITransientDependency
var auditingManager = serviceScope.ServiceProvider.GetRequiredService<IAuditingManager>();
if (auditingManager.Current != null)
{
await ProceedByLoggingAsync(invocation, auditingHelper, auditingManager.Current);
await ProceedByLoggingAsync(invocation, auditingOptions, auditingHelper, auditingManager.Current);
}
else
{
@ -74,16 +74,22 @@ public class AuditingInterceptor : AbpInterceptor, ITransientDependency
private static async Task ProceedByLoggingAsync(
IAbpMethodInvocation invocation,
AbpAuditingOptions options,
IAuditingHelper auditingHelper,
IAuditLogScope auditLogScope)
{
var auditLog = auditLogScope.Log;
var auditLogAction = auditingHelper.CreateAuditLogAction(
auditLog,
invocation.TargetObject.GetType(),
invocation.Method,
invocation.Arguments
);
AuditLogActionInfo auditLogAction = null;
if (!options.DisableLogActionInfo)
{
auditLogAction = auditingHelper.CreateAuditLogAction(
auditLog,
invocation.TargetObject.GetType(),
invocation.Method,
invocation.Arguments
);
}
var stopwatch = Stopwatch.StartNew();
@ -99,8 +105,12 @@ public class AuditingInterceptor : AbpInterceptor, ITransientDependency
finally
{
stopwatch.Stop();
auditLogAction.ExecutionDuration = Convert.ToInt32(stopwatch.Elapsed.TotalMilliseconds);
auditLog.Actions.Add(auditLogAction);
if (auditLogAction != null)
{
auditLogAction.ExecutionDuration = Convert.ToInt32(stopwatch.Elapsed.TotalMilliseconds);
auditLog.Actions.Add(auditLogAction);
}
}
}
@ -117,7 +127,7 @@ public class AuditingInterceptor : AbpInterceptor, ITransientDependency
{
try
{
await ProceedByLoggingAsync(invocation, auditingHelper, auditingManager.Current);
await ProceedByLoggingAsync(invocation, options, auditingHelper, auditingManager.Current);
Debug.Assert(auditingManager.Current != null);
if (auditingManager.Current.Log.Exceptions.Any())

13
framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Auditing/AuditTestController_Tests.cs

@ -1,10 +1,12 @@
using System.Linq;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using NSubstitute;
using System.Threading.Tasks;
using Shouldly;
using Volo.Abp.Auditing;
using Xunit;
@ -98,4 +100,13 @@ public class AuditTestController_Tests : AspNetCoreMvcTestBase
await _auditingStore.Received().SaveAsync(Arg.Is<AuditLogInfo>(x => x.Exceptions.Any()));
}
[Fact]
public async Task Should_DisableLogActionInfo()
{
_options.IsEnabledForGetRequests = true;
_options.DisableLogActionInfo = true;
await GetResponseAsync("/api/audit-test/");
await _auditingStore.Received().SaveAsync(Arg.Is<AuditLogInfo>(x => x.Actions.IsNullOrEmpty()));
}
}

13
framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Auditing/AuditTestPage_Tests.cs

@ -1,4 +1,5 @@
using System.Linq;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
@ -97,4 +98,14 @@ public class AuditTestPage_Tests : AspNetCoreMvcTestBase
await _auditingStore.Received().SaveAsync(Arg.Is<AuditLogInfo>(x => x.Exceptions.Any()));
}
[Fact]
public async Task Should_DisableLogActionInfo()
{
_options.IsEnabledForGetRequests = true;
_options.DisableLogActionInfo = true;
await GetResponseAsync("/Auditing/AuditTestPage");
await _auditingStore.Received().SaveAsync(Arg.Is<AuditLogInfo>(x => x.Actions.IsNullOrEmpty()));
}
}

63
framework/test/Volo.Abp.Auditing.Tests/Volo/Abp/Auditing/Auditing_Tests.cs

@ -16,7 +16,7 @@ namespace Volo.Abp.Auditing;
public class Auditing_Tests : AbpAuditingTestBase
{
private IAuditingStore _auditingStore;
protected IAuditingStore AuditingStore;
private IAuditingManager _auditingManager;
private IUnitOfWorkManager _unitOfWorkManager;
@ -28,8 +28,8 @@ public class Auditing_Tests : AbpAuditingTestBase
protected override void AfterAddApplication(IServiceCollection services)
{
_auditingStore = Substitute.For<IAuditingStore>();
services.Replace(ServiceDescriptor.Singleton(_auditingStore));
AuditingStore = Substitute.For<IAuditingStore>();
services.Replace(ServiceDescriptor.Singleton(AuditingStore));
}
[Fact]
@ -43,7 +43,7 @@ public class Auditing_Tests : AbpAuditingTestBase
await scope.SaveAsync();
}
await _auditingStore.Received().SaveAsync(Arg.Any<AuditLogInfo>());
await AuditingStore.Received().SaveAsync(Arg.Any<AuditLogInfo>());
}
[Fact]
@ -53,9 +53,9 @@ public class Auditing_Tests : AbpAuditingTestBase
await myAuditedObject1.DoItAsync(new InputObject { Value1 = "forty-two", Value2 = 42 });
await _auditingStore.Received().SaveAsync(Arg.Any<AuditLogInfo>());
await AuditingStore.Received().SaveAsync(Arg.Any<AuditLogInfo>());
}
[Fact]
public async Task Should_Not_Write_AuditLog_For_Classes_With_IntegrationService_Attribute()
{
@ -63,7 +63,7 @@ public class Auditing_Tests : AbpAuditingTestBase
await myAuditedObject1.DoItAsync(new InputObject { Value1 = "forty-two", Value2 = 42 });
await _auditingStore.DidNotReceive().SaveAsync(Arg.Any<AuditLogInfo>());
await AuditingStore.DidNotReceive().SaveAsync(Arg.Any<AuditLogInfo>());
}
public interface IMyAuditedObject : ITransientDependency, IAuditingEnabled
@ -82,7 +82,7 @@ public class Auditing_Tests : AbpAuditingTestBase
});
}
}
/* Integration services should not be audited by default */
[IntegrationService]
public class MyNotAuditedIntegrationService1 : IMyAuditedObject
@ -122,7 +122,7 @@ public class Auditing_Tests : AbpAuditingTestBase
}
#pragma warning disable 4014
_auditingStore.Received().SaveAsync(Arg.Any<AuditLogInfo>());
AuditingStore.Received().SaveAsync(Arg.Any<AuditLogInfo>());
#pragma warning restore 4014
}
@ -137,7 +137,7 @@ public class Auditing_Tests : AbpAuditingTestBase
}
#pragma warning disable 4014
_auditingStore.Received().SaveAsync(Arg.Is<AuditLogInfo>(x =>
AuditingStore.Received().SaveAsync(Arg.Is<AuditLogInfo>(x =>
x.EntityChanges.Count == 1 &&
!(x.EntityChanges[0].PropertyChanges.Any(p =>
p.PropertyName == nameof(AppEntityWithDisableAuditingAndPropertyHasAudited.Name2)))));
@ -155,7 +155,7 @@ public class Auditing_Tests : AbpAuditingTestBase
}
#pragma warning disable 4014
_auditingStore.Received().SaveAsync(Arg.Is<AuditLogInfo>(a => !a.EntityChanges.Any()));
AuditingStore.Received().SaveAsync(Arg.Is<AuditLogInfo>(a => !a.EntityChanges.Any()));
#pragma warning restore 4014
}
@ -170,7 +170,7 @@ public class Auditing_Tests : AbpAuditingTestBase
}
#pragma warning disable 4014
_auditingStore.Received().SaveAsync(Arg.Any<AuditLogInfo>());
AuditingStore.Received().SaveAsync(Arg.Any<AuditLogInfo>());
#pragma warning restore 4014
}
@ -185,7 +185,7 @@ public class Auditing_Tests : AbpAuditingTestBase
}
#pragma warning disable 4014
_auditingStore.Received().SaveAsync(Arg.Any<AuditLogInfo>());
AuditingStore.Received().SaveAsync(Arg.Any<AuditLogInfo>());
#pragma warning restore 4014
}
@ -200,7 +200,7 @@ public class Auditing_Tests : AbpAuditingTestBase
}
#pragma warning disable 4014
_auditingStore.Received().SaveAsync(Arg.Is<AuditLogInfo>(x =>
AuditingStore.Received().SaveAsync(Arg.Is<AuditLogInfo>(x =>
x.EntityChanges.Count == 1 && x.EntityChanges[0].PropertyChanges.Count == 2 &&
x.EntityChanges[0].PropertyChanges[0].PropertyName == nameof(AppEntityWithDisableAuditingAndPropertyHasAudited.Name) &&
x.EntityChanges[0].PropertyChanges[1].PropertyName == nameof(AppEntityWithDisableAuditingAndPropertyHasAudited.Name3)));
@ -230,7 +230,7 @@ public class Auditing_Tests : AbpAuditingTestBase
}
#pragma warning disable 4014
_auditingStore.Received().SaveAsync(Arg.Is<AuditLogInfo>(x =>
AuditingStore.Received().SaveAsync(Arg.Is<AuditLogInfo>(x =>
x.EntityChanges.Count == 1 && x.EntityChanges[0].PropertyChanges.Count == 1 &&
x.EntityChanges[0].PropertyChanges[0].PropertyName == nameof(AppEntityWithDisableAuditingAndPropertyHasAudited.Name)));
#pragma warning restore 4014
@ -245,7 +245,7 @@ public class Auditing_Tests : AbpAuditingTestBase
}
#pragma warning disable 4014
_auditingStore.Received().SaveAsync(Arg.Any<AuditLogInfo>());
AuditingStore.Received().SaveAsync(Arg.Any<AuditLogInfo>());
#pragma warning restore 4014
}
@ -274,7 +274,7 @@ public class Auditing_Tests : AbpAuditingTestBase
}
#pragma warning disable 4014
_auditingStore.Received().SaveAsync(Arg.Is<AuditLogInfo>(x => x.EntityChanges.Count == 1
AuditingStore.Received().SaveAsync(Arg.Is<AuditLogInfo>(x => x.EntityChanges.Count == 1
&& x.EntityChanges[0].PropertyChanges.Any(y =>
!GetBaseAuditPropertyNames().Contains(y.PropertyName))));
#pragma warning restore 4014
@ -300,7 +300,7 @@ public class Auditing_Tests : AbpAuditingTestBase
}
#pragma warning disable 4014
_auditingStore.Received().SaveAsync(Arg.Is<AuditLogInfo>(x => x.EntityChanges.Count == 1
AuditingStore.Received().SaveAsync(Arg.Is<AuditLogInfo>(x => x.EntityChanges.Count == 1
&& x.EntityChanges[0].PropertyChanges
.Where(y => y.PropertyName != nameof(AppEntityWithAuditedAndHasCustomAuditingProperties
.ExtraProperties))
@ -333,7 +333,7 @@ public class Auditing_Tests : AbpAuditingTestBase
}
#pragma warning disable 4014
_auditingStore.Received().SaveAsync(Arg.Is<AuditLogInfo>(x => x.EntityChanges.Count == 1
AuditingStore.Received().SaveAsync(Arg.Is<AuditLogInfo>(x => x.EntityChanges.Count == 1
&& x.EntityChanges[0].PropertyChanges.Count == 1
&& x.EntityChanges[0].PropertyChanges[0].PropertyName == nameof(AppEntityWithAudited.Name)));
#pragma warning restore 4014
@ -354,10 +354,33 @@ public class Auditing_Tests : AbpAuditingTestBase
}
#pragma warning disable 4014
_auditingStore.Received().SaveAsync(Arg.Is<AuditLogInfo>(x => x.EntityChanges.Count == 1 &&
AuditingStore.Received().SaveAsync(Arg.Is<AuditLogInfo>(x => x.EntityChanges.Count == 1 &&
x.EntityChanges[0].ChangeType == EntityChangeType.Deleted &&
x.EntityChanges[0].PropertyChanges.Count == 0));
#pragma warning restore 4014
}
}
public class Auditing_DisableLogActionInfo_Tests : Auditing_Tests
{
protected override void AfterAddApplication(IServiceCollection services)
{
services.Configure<AbpAuditingOptions>(options =>
{
options.DisableLogActionInfo = true;
});
base.AfterAddApplication(services);
}
[Fact]
public async Task Should_DisableLogActionInfo()
{
var myAuditedObject1 = GetRequiredService<MyAuditedObject1>();
await myAuditedObject1.DoItAsync(new InputObject { Value1 = "forty-two", Value2 = 42 });
await AuditingStore.Received().SaveAsync(Arg.Is<AuditLogInfo>(x => x.Actions.IsNullOrEmpty()));
}
}

Loading…
Cancel
Save