mirror of https://github.com/Squidex/squidex.git
10 changed files with 194 additions and 88 deletions
@ -0,0 +1,48 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using System.Threading.Tasks; |
||||
|
using Orleans; |
||||
|
using Squidex.Infrastructure.Log; |
||||
|
|
||||
|
namespace Squidex.Infrastructure.Orleans |
||||
|
{ |
||||
|
public sealed class LoggingFilter : IIncomingGrainCallFilter |
||||
|
{ |
||||
|
private readonly ISemanticLog log; |
||||
|
|
||||
|
public LoggingFilter(ISemanticLog log) |
||||
|
{ |
||||
|
Guard.NotNull(log, nameof(log)); |
||||
|
|
||||
|
this.log = log; |
||||
|
} |
||||
|
|
||||
|
public async Task Invoke(IIncomingGrainCallContext context) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
await context.Invoke(); |
||||
|
} |
||||
|
catch (DomainException) |
||||
|
{ |
||||
|
throw; |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
log.LogError(ex, w => w |
||||
|
.WriteProperty("action", "GrainInvoked") |
||||
|
.WriteProperty("status", "Failed") |
||||
|
.WriteProperty("grain", context.Grain.ToString()) |
||||
|
.WriteProperty("grainMethod", context.ImplementationMethod.ToString())); |
||||
|
|
||||
|
throw; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,61 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using System.Threading.Tasks; |
||||
|
using FakeItEasy; |
||||
|
using Orleans; |
||||
|
using Squidex.Infrastructure.Log; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Squidex.Infrastructure.Orleans |
||||
|
{ |
||||
|
public class LoggingFilterTests |
||||
|
{ |
||||
|
private readonly ISemanticLog log = A.Fake<ISemanticLog>(); |
||||
|
private readonly IIncomingGrainCallContext context = A.Fake<IIncomingGrainCallContext>(); |
||||
|
private readonly LoggingFilter sut; |
||||
|
|
||||
|
public LoggingFilterTests() |
||||
|
{ |
||||
|
sut = new LoggingFilter(log); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public async Task Should_not_log_if_no_exception_happened() |
||||
|
{ |
||||
|
await sut.Invoke(context); |
||||
|
|
||||
|
A.CallTo(() => log.Log(A<SemanticLogLevel>.Ignored, A<None>.Ignored, A<Action<None, IObjectWriter>>.Ignored)) |
||||
|
.MustNotHaveHappened(); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public async Task Should_not_log_domain_exceptions() |
||||
|
{ |
||||
|
A.CallTo(() => context.Invoke()) |
||||
|
.Throws(new ValidationException("Failed")); |
||||
|
|
||||
|
await Assert.ThrowsAsync<ValidationException>(() => sut.Invoke(context)); |
||||
|
|
||||
|
A.CallTo(() => log.Log(A<SemanticLogLevel>.Ignored, A<None>.Ignored, A<Action<None, IObjectWriter>>.Ignored)) |
||||
|
.MustNotHaveHappened(); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public async Task Should_log_exception_and_forward_it() |
||||
|
{ |
||||
|
A.CallTo(() => context.Invoke()) |
||||
|
.Throws(new InvalidOperationException()); |
||||
|
|
||||
|
await Assert.ThrowsAsync<InvalidOperationException>(() => sut.Invoke(context)); |
||||
|
|
||||
|
A.CallTo(() => log.Log(A<SemanticLogLevel>.Ignored, A<None>.Ignored, A<Action<None, IObjectWriter>>.Ignored)) |
||||
|
.MustHaveHappened(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue