Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
a47d8ec
convert audit loggers to ILogger
PhilBastian Jun 9, 2025
047420b
revert app.config checkins
PhilBastian Jun 9, 2025
ad7cc4a
use pascal case for structured logging
PhilBastian Jun 9, 2025
3534fd2
revert accidental checkin for primary instance
PhilBastian Jun 10, 2025
aec0e48
Merge remote-tracking branch 'origin/extensions.logging_spike' into e…
PhilBastian Jun 10, 2025
b6505e6
Apply suggestions from code review
PhilBastian Jun 10, 2025
2a0db48
fix build error
PhilBastian Jun 10, 2025
573d9a2
Merge remote-tracking branch 'origin/extensions.logging_spike' into e…
PhilBastian Jun 10, 2025
1041b4e
revert setupcommand to having a parameterless constructor for activat…
PhilBastian Jun 10, 2025
4f25d49
replace NServiceBus.logging in Audit.Persistence with Microsoft.Exten…
PhilBastian Jun 12, 2025
a8c746f
convert SC transports from NServiceBus.Logging to Microsoft.Extension…
PhilBastian Jun 12, 2025
42d01e7
remove signedassembly requirement so that infrastructure can be imported
PhilBastian Jun 15, 2025
96ec124
revert previous change and instead propogate signing back to servicec…
PhilBastian Jun 15, 2025
5aaabe6
fix signature of customisation classes that are dynamically created
PhilBastian Jun 16, 2025
67920ff
add ilogger to test services and remove direct construction with logger
PhilBastian Jun 16, 2025
b3c690a
get tests to use ilogger
PhilBastian Jun 16, 2025
66aaa02
Switch to .NET logging
jasontaylordev Jun 10, 2025
e2196e6
Work in progress
jasontaylordev Jun 12, 2025
e9f287e
Remove test code
jasontaylordev Jun 13, 2025
9b97c92
Improve logging format for storage space details
jasontaylordev Jun 17, 2025
005968d
Properly shutdown NLog in Program.cs
jasontaylordev Jun 17, 2025
49ba86c
Remove Seq logging and prepare for .NET logging migration
jasontaylordev Jun 17, 2025
938c963
Update LogLevel format
jasontaylordev Jun 17, 2025
fb7f77e
Update LogLevel format in logging settings
jasontaylordev Jun 17, 2025
6c713bb
Merge branch 'master' into extensions.logging_transports
PhilBastian Jun 17, 2025
40eef99
Merge branch 'logging-spike-jt' into extensions.logging_transports
PhilBastian Jun 17, 2025
07d5606
enable adding test logging provider as part of loggerutils and create…
PhilBastian Jun 17, 2025
a843701
add ability to select logging provider from config
PhilBastian Jun 17, 2025
3e59886
handle setting not existing
PhilBastian Jun 17, 2025
ab580f6
change logmanager logger factory to the standard one now used by the …
PhilBastian Jun 17, 2025
3e16970
ensure logger for transport tests
PhilBastian Jun 18, 2025
a8a3061
Convert SC primary instance loggers to ILogger (#5019)
abparticular Jun 18, 2025
c92f803
domain events and persister loggers
PhilBastian Jun 18, 2025
dce6435
Merge branch 'master' into extensions.logging_spike
PhilBastian Jun 18, 2025
cc33a71
convert SC transports from NServiceBus.Logging to Microsoft.Extension…
PhilBastian Jun 18, 2025
416258d
Merge branch 'extensions.logging_spike' into extensions.logging_remai…
PhilBastian Jun 18, 2025
479d409
set default to nlog and pass loglevel to test context
PhilBastian Jun 19, 2025
c3c3de4
default to nLog
PhilBastian Jun 19, 2025
316516e
replace logmanager usage in persistence
PhilBastian Jun 19, 2025
6df6fd2
cleanup remaining references to LogManager
PhilBastian Jun 19, 2025
e37e282
missing files from last checkin
PhilBastian Jun 19, 2025
4485d7b
fix different dependency version test failure
PhilBastian Jun 20, 2025
4b80ba3
move loggerutil setup before first static logger usage
PhilBastian Jun 20, 2025
1200d13
Merge branch 'extensions.logging_spike' into extensions.logging_remai…
PhilBastian Jun 20, 2025
92b99b0
fix different dependency version test failure
PhilBastian Jun 20, 2025
9ab9af6
remove/refactor remaining references to LogManager (#5023)
PhilBastian Jun 20, 2025
39039ed
add logging config to all services
PhilBastian Jun 23, 2025
56a4635
enable seq url to be configured
PhilBastian Jun 24, 2025
ddb7568
allow seq url to be configured
PhilBastian Jun 24, 2025
b825edc
fix logger not being available in program.cs
PhilBastian Jun 24, 2025
7edf38f
make nlog level based on configuration again
PhilBastian Jun 24, 2025
ec9c21f
fix logging not being available during logging setup
PhilBastian Jun 25, 2025
912ef81
remove '.' from the end of log messages
PhilBastian Jun 26, 2025
e7bf499
remove unnecessary static logger
PhilBastian Jun 26, 2025
f0be16f
remove unnecessary checks since it's not around intensive log convers…
PhilBastian Jun 26, 2025
061ba55
remove unnecessary checks
PhilBastian Jun 27, 2025
22bcf4b
add opentelemetry as a logging provider option
PhilBastian Jun 27, 2025
ca52fa1
missing package reference
PhilBastian Jun 27, 2025
8b55728
Update src/ServiceControl/Monitoring/HeartbeatEndpointSettingsSyncHos…
PhilBastian Jun 27, 2025
43cc46c
Update src/ServiceControl/Monitoring/HeartbeatEndpointSettingsSyncHos…
PhilBastian Jun 27, 2025
ff85749
log text changes suggested in review
PhilBastian Jun 27, 2025
2fb0180
Merge remote-tracking branch 'origin/extensions.logging_spike' into e…
PhilBastian Jun 27, 2025
e7a28a2
Update src/ServiceControl.Infrastructure/LoggerUtil.cs
PhilBastian Jul 1, 2025
0533c6e
update method calls to match new name
PhilBastian Jul 1, 2025
2f1d97e
Enhanced `LoggerUtil` to include `DisposeLoggerFactories` for better …
jasontaylordev Jul 1, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="8.0.1" />
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="8.0.1" />
<PackageVersion Include="Microsoft.Extensions.Hosting.WindowsServices" Version="8.0.1" />
<PackageVersion Include="Microsoft.Extensions.Logging" Version="8.0.1" />
<PackageVersion Include="Microsoft.Extensions.Logging.Configuration" Version="8.0.1" />
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.3" />
<PackageVersion Include="Microsoft.Extensions.TimeProvider.Testing" Version="8.10.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
<PackageVersion Include="Microsoft-WindowsAPICodePack-Shell" Version="1.1.5" />
Expand Down Expand Up @@ -63,6 +66,7 @@
<PackageVersion Include="PublicApiGenerator" Version="11.4.6" />
<PackageVersion Include="RavenDB.Embedded" Version="6.2.6" />
<PackageVersion Include="ReactiveUI.WPF" Version="20.1.63" />
<PackageVersion Include="Seq.Extensions.Logging" Version="8.0.0" />
<PackageVersion Include="ServiceControl.Contracts" Version="5.0.0" />
<PackageVersion Include="System.Configuration.ConfigurationManager" Version="8.0.1" />
<PackageVersion Include="System.Diagnostics.PerformanceCounter" Version="8.0.1" />
Expand Down Expand Up @@ -91,4 +95,4 @@
<GlobalPackageReference Include="Microsoft.Build.CopyOnWrite" Version="1.0.334" />
<GlobalPackageReference Include="Particular.Packaging" Version="4.2.2" />
</ItemGroup>
</Project>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public class AuditThroughputCollectorHostedService(

protected override async Task ExecuteAsync(CancellationToken cancellationToken)
{
logger.LogInformation($"Starting {nameof(AuditThroughputCollectorHostedService)}");
logger.LogInformation("Starting {ServiceName}", nameof(AuditThroughputCollectorHostedService));

try
{
Expand All @@ -42,14 +42,14 @@ protected override async Task ExecuteAsync(CancellationToken cancellationToken)
}
catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested)
{
logger.LogInformation($"Stopping {nameof(AuditThroughputCollectorHostedService)}");
logger.LogInformation("Stopping {ServiceName}", nameof(AuditThroughputCollectorHostedService));
}
}

async Task GatherThroughput(CancellationToken cancellationToken)
{
var utcYesterday = DateOnly.FromDateTime(timeProvider.GetUtcNow().DateTime).AddDays(-1);
logger.LogInformation($"Gathering throughput from audit for {utcYesterday.ToShortDateString()}");
logger.LogInformation("Gathering throughput from audit for {AuditDate}", utcYesterday.ToShortDateString());

await VerifyAuditInstances(cancellationToken);

Expand All @@ -59,7 +59,7 @@ async Task GatherThroughput(CancellationToken cancellationToken)

if (!knownEndpoints.Any())
{
logger.LogWarning("No known endpoints could be found.");
logger.LogWarning("No known endpoints could be found");
}

foreach (var tuple in await dataStore.GetEndpoints([.. knownEndpointsLookup.Keys], cancellationToken))
Expand Down Expand Up @@ -115,18 +115,18 @@ async Task VerifyAuditInstances(CancellationToken cancellationToken)
{
if (remote.Status == "online" || remote.SemanticVersion is not null)
{
logger.LogInformation($"ServiceControl Audit instance at {remote.ApiUri} detected running version {remote.SemanticVersion}");
logger.LogInformation("ServiceControl Audit instance at {RemoteApiUri} detected running version {RemoteSemanticVersion}", remote.ApiUri, remote.SemanticVersion);
}
else
{
logger.LogWarning($"Unable to determine the version of one or more ServiceControl Audit instances. For the instance with URI {remote.ApiUri}, the status was '{remote.Status}' and the version string returned was '{remote.VersionString}'.");
logger.LogWarning("Unable to determine the version of one or more ServiceControl Audit instances. For the instance with URI {RemoteApiUri}, the status was '{RemoteStatus}' and the version string returned was '{RemoteVersionString}'", remote.ApiUri, remote.Status, remote.VersionString);
}
}

var allHaveAuditCounts = remotesInfo.All(auditQuery.ValidRemoteInstances);
if (!allHaveAuditCounts)
{
logger.LogWarning($"At least one ServiceControl Audit instance is either not running the required version ({auditQuery.MinAuditCountsVersion}) or is not configured for at least 2 days of retention. Audit throughput will not be available.");
logger.LogWarning("At least one ServiceControl Audit instance is either not running the required version ({RequiredAuditVersion}) or is not configured for at least 2 days of retention. Audit throughput will not be available", auditQuery.MinAuditCountsVersion);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ static ReadOnlyDictionary<string, string> LoadBrokerSettingValues(IEnumerable<Ke

if (brokerThroughputQuery.HasInitialisationErrors(out var errorMessage))
{
logger.LogError($"Could not start {nameof(BrokerThroughputCollectorHostedService)}, due to initialisation errors:\n{errorMessage}");
logger.LogError("Could not start {ServiceName}, due to initialisation errors:\n{InitializationErrors}", nameof(BrokerThroughputCollectorHostedService), errorMessage);
return;
}

logger.LogInformation($"Starting {nameof(BrokerThroughputCollectorHostedService)}");
logger.LogInformation("Starting {ServiceName}", nameof(BrokerThroughputCollectorHostedService));

try
{
Expand All @@ -55,7 +55,7 @@ static ReadOnlyDictionary<string, string> LoadBrokerSettingValues(IEnumerable<Ke
}
catch (OperationCanceledException) when (stoppingToken.IsCancellationRequested)
{
logger.LogInformation($"Stopping {nameof(BrokerThroughputCollectorHostedService)}");
logger.LogInformation("Stopping {ServiceName}", nameof(BrokerThroughputCollectorHostedService));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ async Task Handle(MessageContext message, CancellationToken cancellationToken)

public async Task StartAsync(CancellationToken cancellationToken)
{
logger.LogInformation($"Starting {nameof(MonitoringThroughputHostedService)}");
logger.LogInformation("Starting {ServiceName}", nameof(MonitoringThroughputHostedService));

transportInfrastructure = await transportCustomization.CreateTransportInfrastructure(ServiceControlSettings.ServiceControlThroughputDataQueue, transportSettings, Handle, (_, __) => Task.FromResult(ErrorHandleResult.Handled), (_, __) => Task.CompletedTask);
await transportInfrastructure.Receivers[ServiceControlSettings.ServiceControlThroughputDataQueue].StartReceive(cancellationToken);
}

public async Task StopAsync(CancellationToken cancellationToken)
{
logger.LogInformation($"Stopping {nameof(MonitoringThroughputHostedService)}");
logger.LogInformation("Stopping {ServiceName}", nameof(MonitoringThroughputHostedService));

if (transportInfrastructure != null)
{
Expand Down
12 changes: 9 additions & 3 deletions src/ServiceControl.AcceptanceTesting/DiscardMessagesBehavior.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ namespace ServiceControl.AcceptanceTesting
using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using NServiceBus;
using NServiceBus.AcceptanceTesting;
using NServiceBus.Logging;
using NServiceBus.Pipeline;
using ServiceControl.Infrastructure;

public class DiscardMessagesBehavior : IBehavior<ITransportReceiveContext, ITransportReceiveContext>
{
Expand Down Expand Up @@ -44,15 +45,20 @@ public Task Invoke(ITransportReceiveContext context, Func<ITransportReceiveConte
{
context.Message.Headers.TryGetValue(Headers.MessageId, out var originalMessageId);
context.Message.Headers.TryGetValue(Headers.EnclosedMessageTypes, out var enclosedMessageTypes);
log.Debug($"Discarding message '{context.Message.MessageId}'({originalMessageId ?? string.Empty}) because it's session id is '{session}' instead of '{currentSession}' Message Types: {enclosedMessageTypes}.");
var logger = LoggerUtil.CreateStaticLogger<DiscardMessagesBehavior>();
logger.LogDebug("Discarding message '{MessageId}'({OriginalMessageId}) because it's session id is '{MessageSessionId}' instead of '{CurrentSessionId}' Message Types: {EnclosedMessageTypes}",
context.Message.MessageId,
originalMessageId ?? string.Empty,
session,
currentSession,
enclosedMessageTypes);
return Task.CompletedTask;
}

return next(context);
}

ScenarioContext scenarioContext;
static ILog log = LogManager.GetLogger<DiscardMessagesBehavior>();

static string[] pluginMessages =
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Threading.Tasks;
using Hosting.Commands;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging.Abstractions;
using NServiceBus;
using NUnit.Framework;
using Particular.ServiceControl.Hosting;
Expand Down Expand Up @@ -57,7 +58,7 @@ public async Task CanRunMaintenanceMode()
public async Task CanRunImportFailedMessagesMode()
=> await new TestableImportFailedErrorsCommand().Execute(new HostArguments(Array.Empty<string>()), settings);

class TestableImportFailedErrorsCommand : ImportFailedErrorsCommand
class TestableImportFailedErrorsCommand() : ImportFailedErrorsCommand()
{
protected override EndpointConfiguration CreateEndpointConfiguration(Settings settings)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using AcceptanceTesting.EndpointTemplates;
using Infrastructure;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging.Abstractions;
using NServiceBus;
using NServiceBus.AcceptanceTesting;
using NServiceBus.Routing;
Expand Down Expand Up @@ -146,7 +147,7 @@ public class MyContext : ScenarioContext
public class MessageThatWillFail : ICommand;

public class FakeReturnToSender(IErrorMessageDataStore errorMessageStore, MyContext myContext)
: ReturnToSender(errorMessageStore)
: ReturnToSender(errorMessageStore, NullLogger<ReturnToSender>.Instance)
{
public override Task HandleMessage(MessageContext message, IMessageDispatcher sender, string errorQueueTransportAddress, CancellationToken cancellationToken = default)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using NLog;
using Microsoft.Extensions.Logging;
using NServiceBus;
using NServiceBus.AcceptanceTesting;
using NServiceBus.AcceptanceTesting.Support;
Expand Down Expand Up @@ -50,6 +50,7 @@ async Task InitializeServiceControl(ScenarioContext context)
var logPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
Directory.CreateDirectory(logPath);
var loggingSettings = new LoggingSettings(Settings.SettingsRootNamespace, defaultLevel: LogLevel.Debug, logPath: logPath);
LoggerUtil.ActiveLoggers = Loggers.Test;

var settings = new Settings(transportToUse.TypeName, persistenceToUse.PersistenceType, loggingSettings, forwardErrorMessages: false, errorRetentionPeriod: TimeSpan.FromDays(10))
{
Expand All @@ -65,9 +66,9 @@ async Task InitializeServiceControl(ScenarioContext context)
{
var headers = messageContext.Headers;
var id = messageContext.NativeMessageId;
var log = NServiceBus.Logging.LogManager.GetLogger<ServiceControlComponentRunner>();
var logger = LoggerUtil.CreateStaticLogger<ServiceControlComponentRunner>(loggingSettings.LogLevel);
headers.TryGetValue(Headers.MessageId, out var originalMessageId);
log.Debug($"OnMessage for message '{id}'({originalMessageId ?? string.Empty}).");
logger.LogDebug("OnMessage for message '{MessageId}'({OriginalMessageId})", id, originalMessageId ?? string.Empty);

//Do not filter out CC, SA and HB messages as they can't be stamped
if (headers.TryGetValue(Headers.EnclosedMessageTypes, out var messageTypes)
Expand All @@ -86,7 +87,7 @@ async Task InitializeServiceControl(ScenarioContext context)
var currentSession = context.TestRunId.ToString();
if (!headers.TryGetValue("SC.SessionID", out var session) || session != currentSession)
{
log.Debug($"Discarding message '{id}'({originalMessageId ?? string.Empty}) because it's session id is '{session}' instead of '{currentSession}'.");
logger.LogDebug("Discarding message '{MessageId}'({OriginalMessageId}) because it's session id is '{SessionId}' instead of '{CurrentSessionId}'", id, originalMessageId ?? string.Empty, session, currentSession);
return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ namespace ServiceControl.Audit.AcceptanceTests.TestSupport
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using NServiceBus;
using NServiceBus.AcceptanceTesting;
using NServiceBus.AcceptanceTesting.Support;
Expand All @@ -43,7 +44,8 @@ async Task InitializeServiceControl(ScenarioContext context)
var logPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
Directory.CreateDirectory(logPath);

var loggingSettings = new LoggingSettings(Settings.SettingsRootNamespace, defaultLevel: NLog.LogLevel.Debug, logPath: logPath);
var loggingSettings = new LoggingSettings(Settings.SettingsRootNamespace, defaultLevel: LogLevel.Debug, logPath: logPath);
LoggerUtil.ActiveLoggers = Loggers.Test;

settings = new Settings(transportToUse.TypeName, persistenceToUse.PersistenceType, loggingSettings)
{
Expand All @@ -55,9 +57,9 @@ async Task InitializeServiceControl(ScenarioContext context)
{
var id = messageContext.NativeMessageId;
var headers = messageContext.Headers;
var log = NServiceBus.Logging.LogManager.GetLogger<ServiceControlComponentRunner>();
var logger = LoggerUtil.CreateStaticLogger<ServiceControlComponentRunner>(loggingSettings.LogLevel);
headers.TryGetValue(Headers.MessageId, out var originalMessageId);
log.Debug($"OnMessage for message '{id}'({originalMessageId ?? string.Empty}).");
logger.LogDebug("OnMessage for message '{MessageId}'({OriginalMessageId})", id, originalMessageId ?? string.Empty);

//Do not filter out CC, SA and HB messages as they can't be stamped
if (headers.TryGetValue(Headers.EnclosedMessageTypes, out var messageTypes)
Expand All @@ -76,7 +78,7 @@ async Task InitializeServiceControl(ScenarioContext context)
var currentSession = context.TestRunId.ToString();
if (!headers.TryGetValue("SC.SessionID", out var session) || session != currentSession)
{
log.Debug($"Discarding message '{id}'({originalMessageId ?? string.Empty}) because it's session id is '{session}' instead of '{currentSession}'.");
logger.LogDebug("Discarding message '{MessageId}'({OriginalMessageId}) because it's session id is '{SessionId}' instead of '{CurrentSessionId}'", id, originalMessageId ?? string.Empty, session, currentSession);
return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,14 @@
using ServiceControl.Audit.Auditing.BodyStorage;
using ServiceControl.Audit.Persistence.UnitOfWork;

class InMemoryAuditIngestionUnitOfWorkFactory : IAuditIngestionUnitOfWorkFactory
class InMemoryAuditIngestionUnitOfWorkFactory(InMemoryAuditDataStore dataStore, BodyStorageEnricher bodyStorageEnricher) : IAuditIngestionUnitOfWorkFactory
{
public InMemoryAuditIngestionUnitOfWorkFactory(InMemoryAuditDataStore dataStore, IBodyStorage bodyStorage, PersistenceSettings settings)
{
this.dataStore = dataStore;
bodyStorageEnricher = new BodyStorageEnricher(bodyStorage, settings);
}

public ValueTask<IAuditIngestionUnitOfWork> StartNew(int batchSize, CancellationToken cancellationToken)
{
//The batchSize argument is ignored: the in-memory storage implementation doesn't support batching.
return new ValueTask<IAuditIngestionUnitOfWork>(new InMemoryAuditIngestionUnitOfWork(dataStore, bodyStorageEnricher));
}

public bool CanIngestMore() => true;

InMemoryAuditDataStore dataStore;
BodyStorageEnricher bodyStorageEnricher;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public void AddPersistence(IServiceCollection services)
services.AddSingleton<IBodyStorage, InMemoryAttachmentsBodyStorage>();
services.AddSingleton<IFailedAuditStorage, InMemoryFailedAuditStorage>();
services.AddSingleton<IAuditIngestionUnitOfWorkFactory, InMemoryAuditIngestionUnitOfWorkFactory>();
services.AddSingleton<BodyStorageEnricher>();
}

public void AddInstaller(IServiceCollection services)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,24 @@ namespace ServiceControl.Audit.Persistence.RavenDB.CustomChecks;
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using NServiceBus.CustomChecks;
using NServiceBus.Logging;

class CheckDirtyMemory(MemoryInformationRetriever memoryInformationRetriever) : CustomCheck("RavenDB dirty memory", "ServiceControl.Audit Health", TimeSpan.FromMinutes(5))
class CheckDirtyMemory(MemoryInformationRetriever memoryInformationRetriever, ILogger<CheckDirtyMemory> logger) : CustomCheck("RavenDB dirty memory", "ServiceControl.Audit Health", TimeSpan.FromMinutes(5))
{

public override async Task<CheckResult> PerformCheck(CancellationToken cancellationToken = default)
{
var (isHighDirty, dirtyMemory) = await memoryInformationRetriever.GetMemoryInformation(cancellationToken);

Log.Debug($"RavenDB dirty memory value: {dirtyMemory}.");
logger.LogDebug("RavenDB dirty memory value: {DirtyMemory}", dirtyMemory);

if (isHighDirty)
{
var message = $"There is a high level of RavenDB dirty memory ({dirtyMemory}). See https://docs.particular.net/servicecontrol/troubleshooting#ravendb-dirty-memory for guidance on how to mitigate the issue.";
Log.Warn(message);
return CheckResult.Failed(message);
logger.LogWarning("There is a high level of RavenDB dirty memory ({DirtyMemory}). See https://docs.particular.net/servicecontrol/troubleshooting#ravendb-dirty-memory for guidance on how to mitigate the issue", dirtyMemory);
return CheckResult.Failed($"There is a high level of RavenDB dirty memory ({dirtyMemory}). See https://docs.particular.net/servicecontrol/troubleshooting#ravendb-dirty-memory for guidance on how to mitigate the issue.");
}

return CheckResult.Pass;
}

static readonly ILog Log = LogManager.GetLogger<CheckDirtyMemory>();
}
Loading