Browse Source

New option to disable the request log at all.

pull/683/head
Sebastian 5 years ago
parent
commit
27013565cf
  1. 5
      backend/src/Squidex.Domain.Apps.Entities/Apps/DefaultAppLogStore.cs
  2. 29
      backend/src/Squidex.Infrastructure/Log/BackgroundRequestLogStore.cs
  3. 2
      backend/src/Squidex.Infrastructure/Log/IRequestLogStore.cs
  4. 6
      backend/src/Squidex.Infrastructure/Log/RequestLogStoreOptions.cs
  5. 5
      backend/src/Squidex/appsettings.json
  6. 15
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Apps/DefaultAppLogStoreTests.cs
  7. 33
      backend/tests/Squidex.Infrastructure.Tests/Log/BackgroundRequestLogStoreTests.cs

5
backend/src/Squidex.Domain.Apps.Entities/Apps/DefaultAppLogStore.cs

@ -46,6 +46,11 @@ namespace Squidex.Domain.Apps.Entities.Apps
public Task LogAsync(DomainId appId, RequestLog request)
{
if (!requestLogStore.IsEnabled)
{
return Task.CompletedTask;
}
var storedRequest = new Request
{
Key = appId.ToString(),

29
backend/src/Squidex.Infrastructure/Log/BackgroundRequestLogStore.cs

@ -10,6 +10,7 @@ using System.Collections.Concurrent;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Options;
using Squidex.Infrastructure.Timers;
using Squidex.Log;
@ -17,23 +18,30 @@ namespace Squidex.Infrastructure.Log
{
public sealed class BackgroundRequestLogStore : DisposableObjectBase, IRequestLogStore
{
private const int Intervall = 10 * 1000;
private const int BatchSize = 1000;
private readonly IRequestLogRepository logRepository;
private readonly ISemanticLog log;
private readonly CompletionTimer timer;
private readonly RequestLogStoreOptions options;
private ConcurrentQueue<Request> jobs = new ConcurrentQueue<Request>();
public BackgroundRequestLogStore(IRequestLogRepository logRepository, ISemanticLog log)
public bool IsEnabled
{
get => options.StoreEnabled;
}
public BackgroundRequestLogStore(IOptions<RequestLogStoreOptions> options,
IRequestLogRepository logRepository, ISemanticLog log)
{
Guard.NotNull(options, nameof(options));
Guard.NotNull(logRepository, nameof(logRepository));
Guard.NotNull(log, nameof(log));
this.logRepository = logRepository;
this.options = options.Value;
this.logRepository = logRepository;
this.log = log;
timer = new CompletionTimer(Intervall, ct => TrackAsync(), Intervall);
timer = new CompletionTimer(options.Value.WriteIntervall, ct => TrackAsync(), options.Value.WriteIntervall);
}
protected override void DisposeObject(bool disposing)
@ -53,17 +61,24 @@ namespace Squidex.Infrastructure.Log
private async Task TrackAsync()
{
if (!IsEnabled)
{
return;
}
try
{
var batchSize = options.BatchSize;
var localJobs = Interlocked.Exchange(ref jobs, new ConcurrentQueue<Request>());
if (!localJobs.IsEmpty)
{
var pages = (int)Math.Ceiling((double)localJobs.Count / BatchSize);
var pages = (int)Math.Ceiling((double)localJobs.Count / batchSize);
for (var i = 0; i < pages; i++)
{
await logRepository.InsertManyAsync(localJobs.Skip(i * BatchSize).Take(BatchSize));
await logRepository.InsertManyAsync(localJobs.Skip(i * batchSize).Take(batchSize));
}
}
}

2
backend/src/Squidex.Infrastructure/Log/IRequestLogStore.cs

@ -13,6 +13,8 @@ namespace Squidex.Infrastructure.Log
{
public interface IRequestLogStore
{
bool IsEnabled { get; }
Task LogAsync(Request request);
Task QueryAllAsync(Func<Request, Task> callback, string key, DateTime fromDate, DateTime toDate, CancellationToken ct = default);

6
backend/src/Squidex.Infrastructure/Log/RequestLogStoreOptions.cs

@ -9,6 +9,12 @@ namespace Squidex.Infrastructure.Log
{
public sealed class RequestLogStoreOptions
{
public bool StoreEnabled { get; set; }
public int StoreRetentionInDays { get; set; } = 90;
public int BatchSize { get; set; } = 1000;
public int WriteIntervall { get; set; } = 1000;
}
}

5
backend/src/Squidex/appsettings.json

@ -338,6 +338,11 @@
*/
"logProfiler": false,
/*
* False to disable the log store.
*/
"storeEnabled": true,
/*
* The number of days request log items will be stored.
*/

15
backend/tests/Squidex.Domain.Apps.Entities.Tests/Apps/DefaultAppLogStoreTests.cs

@ -27,11 +27,26 @@ namespace Squidex.Domain.Apps.Entities.Apps
sut = new DefaultAppLogStore(requestLogStore);
}
[Fact]
public async Task Should_not_forward_request_if_disabled()
{
A.CallTo(() => requestLogStore.IsEnabled)
.Returns(false);
await sut.LogAsync(DomainId.NewGuid(), default);
A.CallTo(() => requestLogStore.LogAsync(A<Request>._))
.MustNotHaveHappened();
}
[Fact]
public async Task Should_forward_request_log_to_store()
{
Request? recordedRequest = null;
A.CallTo(() => requestLogStore.IsEnabled)
.Returns(true);
A.CallTo(() => requestLogStore.LogAsync(A<Request>._))
.Invokes((Request request) => recordedRequest = request);

33
backend/tests/Squidex.Infrastructure.Tests/Log/BackgroundRequestLogStoreTests.cs

@ -9,6 +9,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using FakeItEasy;
using Microsoft.Extensions.Options;
using Squidex.Log;
using Xunit;
@ -17,11 +18,41 @@ namespace Squidex.Infrastructure.Log
public class BackgroundRequestLogStoreTests
{
private readonly IRequestLogRepository requestLogRepository = A.Fake<IRequestLogRepository>();
private readonly RequestLogStoreOptions options = new RequestLogStoreOptions();
private readonly BackgroundRequestLogStore sut;
public BackgroundRequestLogStoreTests()
{
sut = new BackgroundRequestLogStore(requestLogRepository, A.Fake<ISemanticLog>());
options.StoreEnabled = true;
sut = new BackgroundRequestLogStore(Options.Create(options), requestLogRepository, A.Fake<ISemanticLog>());
}
[Theory]
[InlineData(true)]
[InlineData(false)]
public void Should_provide_disabled_from_options(bool enabled)
{
options.StoreEnabled = enabled;
Assert.Equal(enabled, sut.IsEnabled);
}
[Fact]
public async Task Should_not_if_disabled()
{
options.StoreEnabled = false;
for (var i = 0; i < 2500; i++)
{
await sut.LogAsync(new Request { Key = i.ToString() });
}
sut.Next();
sut.Dispose();
A.CallTo(() => requestLogRepository.InsertManyAsync(A<IEnumerable<Request>>._))
.MustNotHaveHappened();
}
[Fact]

Loading…
Cancel
Save