diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props
index 60eb7072c9..16035eade5 100644
--- a/src/Directory.Packages.props
+++ b/src/Directory.Packages.props
@@ -24,6 +24,9 @@
+
+
+
@@ -63,6 +66,7 @@
+
@@ -91,4 +95,4 @@
-
+
\ No newline at end of file
diff --git a/src/Particular.LicensingComponent/AuditThroughput/AuditThroughputCollectorHostedService.cs b/src/Particular.LicensingComponent/AuditThroughput/AuditThroughputCollectorHostedService.cs
index e60a4531db..91c90dbb95 100644
--- a/src/Particular.LicensingComponent/AuditThroughput/AuditThroughputCollectorHostedService.cs
+++ b/src/Particular.LicensingComponent/AuditThroughput/AuditThroughputCollectorHostedService.cs
@@ -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
{
@@ -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);
@@ -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))
@@ -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);
}
}
diff --git a/src/Particular.LicensingComponent/BrokerThroughput/BrokerThroughputCollectorHostedService.cs b/src/Particular.LicensingComponent/BrokerThroughput/BrokerThroughputCollectorHostedService.cs
index 8bb88190fe..497f7eb2f3 100644
--- a/src/Particular.LicensingComponent/BrokerThroughput/BrokerThroughputCollectorHostedService.cs
+++ b/src/Particular.LicensingComponent/BrokerThroughput/BrokerThroughputCollectorHostedService.cs
@@ -29,11 +29,11 @@ static ReadOnlyDictionary LoadBrokerSettingValues(IEnumerable LoadBrokerSettingValues(IEnumerable Task.FromResult(ErrorHandleResult.Handled), (_, __) => Task.CompletedTask);
await transportInfrastructure.Receivers[ServiceControlSettings.ServiceControlThroughputDataQueue].StartReceive(cancellationToken);
@@ -32,7 +32,7 @@ public async Task StartAsync(CancellationToken cancellationToken)
public async Task StopAsync(CancellationToken cancellationToken)
{
- logger.LogInformation($"Stopping {nameof(MonitoringThroughputHostedService)}");
+ logger.LogInformation("Stopping {ServiceName}", nameof(MonitoringThroughputHostedService));
if (transportInfrastructure != null)
{
diff --git a/src/ServiceControl.AcceptanceTesting/DiscardMessagesBehavior.cs b/src/ServiceControl.AcceptanceTesting/DiscardMessagesBehavior.cs
index ed2fd50768..109c545e22 100644
--- a/src/ServiceControl.AcceptanceTesting/DiscardMessagesBehavior.cs
+++ b/src/ServiceControl.AcceptanceTesting/DiscardMessagesBehavior.cs
@@ -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
{
@@ -44,7 +45,13 @@ public Task Invoke(ITransportReceiveContext context, Func();
+ 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;
}
@@ -52,7 +59,6 @@ public Task Invoke(ITransportReceiveContext context, Func();
static string[] pluginMessages =
{
diff --git a/src/ServiceControl.AcceptanceTests.RavenDB/StartupModeTests.cs b/src/ServiceControl.AcceptanceTests.RavenDB/StartupModeTests.cs
index 6aef55b25e..02f868009a 100644
--- a/src/ServiceControl.AcceptanceTests.RavenDB/StartupModeTests.cs
+++ b/src/ServiceControl.AcceptanceTests.RavenDB/StartupModeTests.cs
@@ -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;
@@ -57,7 +58,7 @@ public async Task CanRunMaintenanceMode()
public async Task CanRunImportFailedMessagesMode()
=> await new TestableImportFailedErrorsCommand().Execute(new HostArguments(Array.Empty()), settings);
- class TestableImportFailedErrorsCommand : ImportFailedErrorsCommand
+ class TestableImportFailedErrorsCommand() : ImportFailedErrorsCommand()
{
protected override EndpointConfiguration CreateEndpointConfiguration(Settings settings)
{
diff --git a/src/ServiceControl.AcceptanceTests/Recoverability/MessageFailures/When_a_retry_fails_to_be_sent.cs b/src/ServiceControl.AcceptanceTests/Recoverability/MessageFailures/When_a_retry_fails_to_be_sent.cs
index ff843ecd2c..3e4e4e89cd 100644
--- a/src/ServiceControl.AcceptanceTests/Recoverability/MessageFailures/When_a_retry_fails_to_be_sent.cs
+++ b/src/ServiceControl.AcceptanceTests/Recoverability/MessageFailures/When_a_retry_fails_to_be_sent.cs
@@ -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;
@@ -146,7 +147,7 @@ public class MyContext : ScenarioContext
public class MessageThatWillFail : ICommand;
public class FakeReturnToSender(IErrorMessageDataStore errorMessageStore, MyContext myContext)
- : ReturnToSender(errorMessageStore)
+ : ReturnToSender(errorMessageStore, NullLogger.Instance)
{
public override Task HandleMessage(MessageContext message, IMessageDispatcher sender, string errorQueueTransportAddress, CancellationToken cancellationToken = default)
{
diff --git a/src/ServiceControl.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs b/src/ServiceControl.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs
index 19bbe6b57a..8ac0a4454a 100644
--- a/src/ServiceControl.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs
+++ b/src/ServiceControl.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs
@@ -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;
@@ -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))
{
@@ -65,9 +66,9 @@ async Task InitializeServiceControl(ScenarioContext context)
{
var headers = messageContext.Headers;
var id = messageContext.NativeMessageId;
- var log = NServiceBus.Logging.LogManager.GetLogger();
+ var logger = LoggerUtil.CreateStaticLogger(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)
@@ -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;
}
diff --git a/src/ServiceControl.Audit.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs b/src/ServiceControl.Audit.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs
index 0866b504db..e0b41effe6 100644
--- a/src/ServiceControl.Audit.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs
+++ b/src/ServiceControl.Audit.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs
@@ -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;
@@ -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)
{
@@ -55,9 +57,9 @@ async Task InitializeServiceControl(ScenarioContext context)
{
var id = messageContext.NativeMessageId;
var headers = messageContext.Headers;
- var log = NServiceBus.Logging.LogManager.GetLogger();
+ var logger = LoggerUtil.CreateStaticLogger(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)
@@ -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;
}
diff --git a/src/ServiceControl.Audit.Persistence.InMemory/InMemoryAuditIngestionUnitOfWorkFactory.cs b/src/ServiceControl.Audit.Persistence.InMemory/InMemoryAuditIngestionUnitOfWorkFactory.cs
index f07e7036de..fb1f3a0c66 100644
--- a/src/ServiceControl.Audit.Persistence.InMemory/InMemoryAuditIngestionUnitOfWorkFactory.cs
+++ b/src/ServiceControl.Audit.Persistence.InMemory/InMemoryAuditIngestionUnitOfWorkFactory.cs
@@ -5,14 +5,8 @@
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 StartNew(int batchSize, CancellationToken cancellationToken)
{
//The batchSize argument is ignored: the in-memory storage implementation doesn't support batching.
@@ -20,8 +14,5 @@ public ValueTask StartNew(int batchSize, Cancellation
}
public bool CanIngestMore() => true;
-
- InMemoryAuditDataStore dataStore;
- BodyStorageEnricher bodyStorageEnricher;
}
}
\ No newline at end of file
diff --git a/src/ServiceControl.Audit.Persistence.InMemory/InMemoryPersistence.cs b/src/ServiceControl.Audit.Persistence.InMemory/InMemoryPersistence.cs
index 4a5b349caa..368191f50a 100644
--- a/src/ServiceControl.Audit.Persistence.InMemory/InMemoryPersistence.cs
+++ b/src/ServiceControl.Audit.Persistence.InMemory/InMemoryPersistence.cs
@@ -14,6 +14,7 @@ public void AddPersistence(IServiceCollection services)
services.AddSingleton();
services.AddSingleton();
services.AddSingleton();
+ services.AddSingleton();
}
public void AddInstaller(IServiceCollection services)
diff --git a/src/ServiceControl.Audit.Persistence.RavenDB/CustomChecks/CheckDirtyMemory.cs b/src/ServiceControl.Audit.Persistence.RavenDB/CustomChecks/CheckDirtyMemory.cs
index 37731858d8..85b02e55c5 100644
--- a/src/ServiceControl.Audit.Persistence.RavenDB/CustomChecks/CheckDirtyMemory.cs
+++ b/src/ServiceControl.Audit.Persistence.RavenDB/CustomChecks/CheckDirtyMemory.cs
@@ -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 logger) : CustomCheck("RavenDB dirty memory", "ServiceControl.Audit Health", TimeSpan.FromMinutes(5))
{
+
public override async Task 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();
}
\ No newline at end of file
diff --git a/src/ServiceControl.Audit.Persistence.RavenDB/CustomChecks/CheckFreeDiskSpace.cs b/src/ServiceControl.Audit.Persistence.RavenDB/CustomChecks/CheckFreeDiskSpace.cs
index 18705af5b9..e7757101a2 100644
--- a/src/ServiceControl.Audit.Persistence.RavenDB/CustomChecks/CheckFreeDiskSpace.cs
+++ b/src/ServiceControl.Audit.Persistence.RavenDB/CustomChecks/CheckFreeDiskSpace.cs
@@ -5,18 +5,15 @@
using System.IO;
using System.Threading;
using System.Threading.Tasks;
+ using Microsoft.Extensions.Logging;
using NServiceBus.CustomChecks;
- using NServiceBus.Logging;
using RavenDB;
- class CheckFreeDiskSpace(DatabaseConfiguration databaseConfiguration) : CustomCheck("ServiceControl.Audit database", "Storage space", TimeSpan.FromMinutes(5))
+ class CheckFreeDiskSpace(DatabaseConfiguration databaseConfiguration, ILogger logger) : CustomCheck("ServiceControl.Audit database", "Storage space", TimeSpan.FromMinutes(5))
{
public override Task PerformCheck(CancellationToken cancellationToken = default)
{
- if (Logger.IsDebugEnabled)
- {
- Logger.Debug($"Check ServiceControl data drive space remaining custom check starting. Threshold {percentageThreshold:P0}");
- }
+ logger.LogDebug("Check ServiceControl data drive space remaining custom check starting. Threshold {PercentageThreshold:P0}", percentageThreshold);
if (!databaseConfiguration.ServerConfiguration.UseEmbeddedServer)
{
@@ -33,44 +30,36 @@ public override Task PerformCheck(CancellationToken cancellationTok
var totalSpace = (decimal)dataDriveInfo.TotalSize;
var percentRemaining = (decimal)dataDriveInfo.AvailableFreeSpace / dataDriveInfo.TotalSize;
-
- if (Logger.IsDebugEnabled)
- {
- Logger.Debug($"Free space: {availableFreeSpace:N0}B | Total: {totalSpace:N0}B | Percent remaining {percentRemaining:P1}");
- }
+ logger.LogDebug("Free space: {FreeSpaceTotalBytesFree:N0}B | Total: {FreeSpaceTotalBytesAvailable:N0}B | Remaining {PercentRemaining:P1}%", availableFreeSpace, totalSpace, percentRemaining);
return percentRemaining > percentageThreshold
? CheckResult.Pass
: CheckResult.Failed($"{percentRemaining:P0} disk space remaining on data drive '{dataDriveInfo.VolumeLabel} ({dataDriveInfo.RootDirectory})' on '{Environment.MachineName}'.");
}
- public static int Parse(IDictionary settings)
+ public static int Parse(IDictionary settings, ILogger logger)
{
if (!settings.TryGetValue(RavenPersistenceConfiguration.DataSpaceRemainingThresholdKey, out var thresholdValue))
{
thresholdValue = $"{DataSpaceRemainingThresholdDefault}";
}
- string message;
if (!int.TryParse(thresholdValue, out var threshold))
{
- message = $"{RavenPersistenceConfiguration.DataSpaceRemainingThresholdKey} must be an integer.";
- Logger.Fatal(message);
- throw new Exception(message);
+ logger.LogCritical("{RavenPersistenceConfigurationDataSpaceRemainingThresholdKey} must be an integer", RavenPersistenceConfiguration.DataSpaceRemainingThresholdKey);
+ throw new Exception($"{RavenPersistenceConfiguration.DataSpaceRemainingThresholdKey} must be an integer.");
}
if (threshold < 0)
{
- message = $"{RavenPersistenceConfiguration.DataSpaceRemainingThresholdKey} is invalid, minimum value is 0.";
- Logger.Fatal(message);
- throw new Exception(message);
+ logger.LogCritical("{RavenPersistenceConfigurationDataSpaceRemainingThresholdKey} is invalid, minimum value is 0", RavenPersistenceConfiguration.DataSpaceRemainingThresholdKey);
+ throw new Exception($"{RavenPersistenceConfiguration.DataSpaceRemainingThresholdKey} is invalid, minimum value is 0.");
}
if (threshold > 100)
{
- message = $"{RavenPersistenceConfiguration.DataSpaceRemainingThresholdKey} is invalid, maximum value is 100.";
- Logger.Fatal(message);
- throw new Exception(message);
+ logger.LogCritical("{RavenPersistenceConfigurationDataSpaceRemainingThresholdKey} is invalid, maximum value is 100", RavenPersistenceConfiguration.DataSpaceRemainingThresholdKey);
+ throw new Exception($"{RavenPersistenceConfiguration.DataSpaceRemainingThresholdKey} is invalid, maximum value is 100.");
}
return threshold;
@@ -78,8 +67,6 @@ public static int Parse(IDictionary settings)
readonly string dataPathRoot = Path.GetPathRoot(databaseConfiguration.ServerConfiguration.DbPath);
readonly decimal percentageThreshold = databaseConfiguration.DataSpaceRemainingThreshold / 100m;
-
public const int DataSpaceRemainingThresholdDefault = 20;
- static readonly ILog Logger = LogManager.GetLogger(typeof(CheckFreeDiskSpace));
}
}
\ No newline at end of file
diff --git a/src/ServiceControl.Audit.Persistence.RavenDB/CustomChecks/CheckMinimumStorageRequiredForIngestion.cs b/src/ServiceControl.Audit.Persistence.RavenDB/CustomChecks/CheckMinimumStorageRequiredForIngestion.cs
index 6d2fccbc38..58fb1ed984 100644
--- a/src/ServiceControl.Audit.Persistence.RavenDB/CustomChecks/CheckMinimumStorageRequiredForIngestion.cs
+++ b/src/ServiceControl.Audit.Persistence.RavenDB/CustomChecks/CheckMinimumStorageRequiredForIngestion.cs
@@ -5,20 +5,17 @@
using System.IO;
using System.Threading;
using System.Threading.Tasks;
+ using Microsoft.Extensions.Logging;
using NServiceBus.CustomChecks;
- using NServiceBus.Logging;
using RavenDB;
+ using ServiceControl.Infrastructure;
- class CheckMinimumStorageRequiredForIngestion(MinimumRequiredStorageState stateHolder, DatabaseConfiguration databaseConfiguration) : CustomCheck("Audit Message Ingestion Process", "ServiceControl.Audit Health", TimeSpan.FromSeconds(5))
+ class CheckMinimumStorageRequiredForIngestion(MinimumRequiredStorageState stateHolder, DatabaseConfiguration databaseConfiguration, ILogger logger) : CustomCheck("Audit Message Ingestion Process", "ServiceControl.Audit Health", TimeSpan.FromSeconds(5))
{
public override Task PerformCheck(CancellationToken cancellationToken = default)
{
var percentageThreshold = databaseConfiguration.MinimumStorageLeftRequiredForIngestion / 100m;
-
- if (Logger.IsDebugEnabled)
- {
- Logger.Debug($"Check ServiceControl data drive space starting. Threshold {percentageThreshold:P0}");
- }
+ logger.LogDebug("Check ServiceControl data drive space starting. Threshold {PercentageThreshold:P0}", percentageThreshold);
// Should be checking UseEmbeddedServer but need to check DbPath instead for the ATT hack to work
if (string.IsNullOrEmpty(databaseConfiguration.ServerConfiguration.DbPath))
@@ -34,11 +31,7 @@ public override Task PerformCheck(CancellationToken cancellationTok
var totalSpace = (decimal)dataDriveInfo.TotalSize;
var percentRemaining = (decimal)dataDriveInfo.AvailableFreeSpace / dataDriveInfo.TotalSize;
-
- if (Logger.IsDebugEnabled)
- {
- Logger.Debug($"Free space: {availableFreeSpace} | Total: {totalSpace} | Percent remaining {percentRemaining:P0}");
- }
+ logger.LogDebug("Free space: {FreeSpaceTotalBytesFree:N0}B | Total: {FreeSpaceTotalBytesAvailable:N0}B | Remaining {PercentRemaining:P0}%", availableFreeSpace, totalSpace, percentRemaining);
if (percentRemaining > percentageThreshold)
{
@@ -46,10 +39,9 @@ public override Task PerformCheck(CancellationToken cancellationTok
return SuccessResult;
}
- var message = $"Audit message ingestion stopped! {percentRemaining:P0} disk space remaining on data drive '{dataDriveInfo.VolumeLabel} ({dataDriveInfo.RootDirectory})' on '{Environment.MachineName}'. This is less than {percentageThreshold}% - the minimal required space configured. The threshold can be set using the {RavenPersistenceConfiguration.MinimumStorageLeftRequiredForIngestionKey} configuration setting.";
- Logger.Warn(message);
+ logger.LogWarning("Audit message ingestion stopped! {PercentRemaining:P0} disk space remaining on data drive '{DataDriveInfoVolumeLabel} ({DataDriveInfoRootDirectory})' on '{EnvironmentMachineName}'. This is less than {PercentageThreshold}% - the minimal required space configured. The threshold can be set using the {RavenPersistenceConfigurationMinimumStorageLeftRequiredForIngestionKey} configuration setting", percentRemaining, dataDriveInfo.VolumeLabel, dataDriveInfo.RootDirectory, Environment.MachineName, percentageThreshold, RavenPersistenceConfiguration.MinimumStorageLeftRequiredForIngestionKey);
stateHolder.CanIngestMore = false;
- return CheckResult.Failed(message);
+ return CheckResult.Failed($"Audit message ingestion stopped! {percentRemaining:P0} disk space remaining on data drive '{dataDriveInfo.VolumeLabel} ({dataDriveInfo.RootDirectory})' on '{Environment.MachineName}'. This is less than {percentageThreshold}% - the minimal required space configured. The threshold can be set using the {RavenPersistenceConfiguration.MinimumStorageLeftRequiredForIngestionKey} configuration setting.");
}
public static int Parse(IDictionary settings)
@@ -61,23 +53,20 @@ public static int Parse(IDictionary settings)
if (!int.TryParse(thresholdValue, out var threshold))
{
- var message = $"{RavenPersistenceConfiguration.MinimumStorageLeftRequiredForIngestionKey} must be an integer.";
- Logger.Fatal(message);
- throw new Exception(message);
+ Logger.LogCritical("{RavenPersistenceConfigurationMinimumStorageLeftRequiredForIngestionKey} must be an integer", RavenPersistenceConfiguration.MinimumStorageLeftRequiredForIngestionKey);
+ throw new Exception($"{RavenPersistenceConfiguration.MinimumStorageLeftRequiredForIngestionKey} must be an integer.");
}
if (threshold < 0)
{
- var message = $"{RavenPersistenceConfiguration.MinimumStorageLeftRequiredForIngestionKey} is invalid, minimum value is 0.";
- Logger.Fatal(message);
- throw new Exception(message);
+ Logger.LogCritical("{RavenPersistenceConfigurationMinimumStorageLeftRequiredForIngestionKey} is invalid, minimum value is 0", RavenPersistenceConfiguration.MinimumStorageLeftRequiredForIngestionKey);
+ throw new Exception($"{RavenPersistenceConfiguration.MinimumStorageLeftRequiredForIngestionKey} is invalid, minimum value is 0.");
}
if (threshold > 100)
{
- var message = $"{RavenPersistenceConfiguration.MinimumStorageLeftRequiredForIngestionKey} is invalid, maximum value is 100.";
- Logger.Fatal(message);
- throw new Exception(message);
+ Logger.LogCritical("{RavenPersistenceConfigurationMinimumStorageLeftRequiredForIngestionKey} is invalid, maximum value is 100", RavenPersistenceConfiguration.MinimumStorageLeftRequiredForIngestionKey);
+ throw new Exception($"{RavenPersistenceConfiguration.MinimumStorageLeftRequiredForIngestionKey} is invalid, maximum value is 100.");
}
return threshold;
@@ -85,6 +74,6 @@ public static int Parse(IDictionary settings)
public const int MinimumStorageLeftRequiredForIngestionDefault = 5;
static readonly Task SuccessResult = Task.FromResult(CheckResult.Pass);
- static readonly ILog Logger = LogManager.GetLogger(typeof(CheckMinimumStorageRequiredForIngestion));
+ static readonly ILogger Logger = LoggerUtil.CreateStaticLogger();
}
}
\ No newline at end of file
diff --git a/src/ServiceControl.Audit.Persistence.RavenDB/CustomChecks/CheckRavenDBIndexLag.cs b/src/ServiceControl.Audit.Persistence.RavenDB/CustomChecks/CheckRavenDBIndexLag.cs
index 41f4347a71..7cd6d76321 100644
--- a/src/ServiceControl.Audit.Persistence.RavenDB/CustomChecks/CheckRavenDBIndexLag.cs
+++ b/src/ServiceControl.Audit.Persistence.RavenDB/CustomChecks/CheckRavenDBIndexLag.cs
@@ -5,12 +5,12 @@
using System.Text;
using System.Threading;
using System.Threading.Tasks;
+ using Microsoft.Extensions.Logging;
using NServiceBus.CustomChecks;
- using NServiceBus.Logging;
using Raven.Client.Documents.Operations;
using ServiceControl.Audit.Persistence.RavenDB;
- class CheckRavenDBIndexLag(IRavenDocumentStoreProvider documentStoreProvider) : CustomCheck("Audit Database Index Lag", "ServiceControl.Audit Health", TimeSpan.FromMinutes(5))
+ class CheckRavenDBIndexLag(IRavenDocumentStoreProvider documentStoreProvider, ILogger logger) : CustomCheck("Audit Database Index Lag", "ServiceControl.Audit Health", TimeSpan.FromMinutes(5))
{
public override async Task PerformCheck(CancellationToken cancellationToken = default)
{
@@ -30,7 +30,7 @@ public override async Task PerformCheck(CancellationToken cancellat
return CheckResult.Pass;
}
- static int CheckAndReportIndexesWithTooMuchIndexLag(IndexInformation[] indexes)
+ int CheckAndReportIndexesWithTooMuchIndexLag(IndexInformation[] indexes)
{
int indexCountWithTooMuchLag = 0;
@@ -43,12 +43,12 @@ static int CheckAndReportIndexesWithTooMuchIndexLag(IndexInformation[] indexes)
if (indexLag > IndexLagThresholdError)
{
indexCountWithTooMuchLag++;
- Log.Error($"Index [{indexStats.Name}] IndexingLag {indexLag} is above error threshold ({IndexLagThresholdError}). Launch in maintenance mode to let indexes catch up.");
+ logger.LogError("Index [{IndexStatsName}] IndexingLag {IndexLag} is above error threshold ({IndexLagThresholdError}). Launch in maintenance mode to let indexes catch up", indexStats.Name, indexLag, IndexLagThresholdError);
}
else if (indexLag > IndexLagThresholdWarning)
{
indexCountWithTooMuchLag++;
- Log.Warn($"Index [{indexStats.Name}] IndexingLag {indexLag} is above warning threshold ({IndexLagThresholdWarning}). Launch in maintenance mode to let indexes catch up.");
+ logger.LogWarning("Index [{IndexStatsName}] IndexingLag {IndexLag} is above warning threshold ({IndexLagThresholdWarning}). Launch in maintenance mode to let indexes catch up", indexStats.Name, indexLag, IndexLagThresholdWarning);
}
}
}
@@ -56,9 +56,9 @@ static int CheckAndReportIndexesWithTooMuchIndexLag(IndexInformation[] indexes)
return indexCountWithTooMuchLag;
}
- static void CreateDiagnosticsLogEntry(DatabaseStatistics statistics, IndexInformation[] indexes)
+ void CreateDiagnosticsLogEntry(DatabaseStatistics statistics, IndexInformation[] indexes)
{
- if (!Log.IsDebugEnabled)
+ if (!logger.IsEnabled(LogLevel.Debug))
{
return;
}
@@ -72,11 +72,11 @@ static void CreateDiagnosticsLogEntry(DatabaseStatistics statistics, IndexInform
{
report.AppendLine($"- Index [{indexStats.Name,-44}] State: {indexStats.State}, Stale: {indexStats.IsStale,-5}, Priority: {indexStats.Priority,-6}, LastIndexingTime: {indexStats.LastIndexingTime:u}");
}
- Log.Debug(report.ToString());
+
+ logger.LogDebug(report.ToString());
}
static readonly TimeSpan IndexLagThresholdWarning = TimeSpan.FromMinutes(1);
static readonly TimeSpan IndexLagThresholdError = TimeSpan.FromMinutes(10);
- static readonly ILog Log = LogManager.GetLogger();
}
}
\ No newline at end of file
diff --git a/src/ServiceControl.Audit.Persistence.RavenDB/RavenEmbeddedPersistenceLifecycle.cs b/src/ServiceControl.Audit.Persistence.RavenDB/RavenEmbeddedPersistenceLifecycle.cs
index f7f1ecee16..80bf05b742 100644
--- a/src/ServiceControl.Audit.Persistence.RavenDB/RavenEmbeddedPersistenceLifecycle.cs
+++ b/src/ServiceControl.Audit.Persistence.RavenDB/RavenEmbeddedPersistenceLifecycle.cs
@@ -6,12 +6,12 @@ namespace ServiceControl.Audit.Persistence.RavenDB
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
- using NServiceBus.Logging;
+ using Microsoft.Extensions.Logging;
using Raven.Client.Documents;
using Raven.Client.Exceptions.Database;
using ServiceControl.RavenDB;
- sealed class RavenEmbeddedPersistenceLifecycle(DatabaseConfiguration databaseConfiguration, IHostApplicationLifetime lifetime) : IRavenPersistenceLifecycle, IRavenDocumentStoreProvider, IDisposable
+ sealed class RavenEmbeddedPersistenceLifecycle(DatabaseConfiguration databaseConfiguration, IHostApplicationLifetime lifetime, ILogger logger) : IRavenPersistenceLifecycle, IRavenDocumentStoreProvider, IDisposable
{
public async ValueTask GetDocumentStore(CancellationToken cancellationToken = default)
{
@@ -61,7 +61,7 @@ public async Task Initialize(CancellationToken cancellationToken = default)
}
catch (DatabaseLoadTimeoutException e)
{
- Log.Warn("Connecting to the embedded RavenDB database timed out. Retrying in 500ms...", e);
+ logger.LogWarning(e, "Connecting to the embedded RavenDB database timed out. Retrying in 500ms...");
await Task.Delay(500, cancellationToken);
}
}
@@ -83,7 +83,5 @@ public void Dispose()
IDocumentStore? documentStore;
EmbeddedDatabase? database;
readonly SemaphoreSlim initializeSemaphore = new(1, 1);
-
- static readonly ILog Log = LogManager.GetLogger(typeof(RavenEmbeddedPersistenceLifecycle));
}
}
diff --git a/src/ServiceControl.Audit.Persistence.RavenDB/RavenPersistenceConfiguration.cs b/src/ServiceControl.Audit.Persistence.RavenDB/RavenPersistenceConfiguration.cs
index b22003ceae..eced9e35b2 100644
--- a/src/ServiceControl.Audit.Persistence.RavenDB/RavenPersistenceConfiguration.cs
+++ b/src/ServiceControl.Audit.Persistence.RavenDB/RavenPersistenceConfiguration.cs
@@ -5,7 +5,8 @@
using System.IO;
using System.Reflection;
using CustomChecks;
- using NServiceBus.Logging;
+ using Microsoft.Extensions.Logging;
+ using ServiceControl.Infrastructure;
public class RavenPersistenceConfiguration : IPersistenceConfiguration
{
@@ -107,13 +108,13 @@ internal static DatabaseConfiguration GetDatabaseConfiguration(PersistenceSettin
if (settings.PersisterSpecificSettings.TryGetValue(RavenDbLogLevelKey, out var ravenDbLogLevel))
{
- logsMode = RavenDbLogLevelToLogsModeMapper.Map(ravenDbLogLevel);
+ logsMode = RavenDbLogLevelToLogsModeMapper.Map(ravenDbLogLevel, Logger);
}
serverConfiguration = new ServerConfiguration(dbPath, serverUrl, logPath, logsMode);
}
- var dataSpaceRemainingThreshold = CheckFreeDiskSpace.Parse(settings.PersisterSpecificSettings);
+ var dataSpaceRemainingThreshold = CheckFreeDiskSpace.Parse(settings.PersisterSpecificSettings, Logger);
var minimumStorageLeftRequiredForIngestion = CheckMinimumStorageRequiredForIngestion.Parse(settings.PersisterSpecificSettings);
var expirationProcessTimerInSeconds = GetExpirationProcessTimerInSeconds(settings);
@@ -141,15 +142,17 @@ static int GetExpirationProcessTimerInSeconds(PersistenceSettings settings)
expirationProcessTimerInSeconds = int.Parse(expirationProcessTimerInSecondsString);
}
+ var maxExpirationProcessTimerInSeconds = TimeSpan.FromHours(3).TotalSeconds;
+
if (expirationProcessTimerInSeconds < 0)
{
- Logger.Error($"ExpirationProcessTimerInSeconds cannot be negative. Defaulting to {ExpirationProcessTimerInSecondsDefault}");
+ Logger.LogError("ExpirationProcessTimerInSeconds cannot be negative. Defaulting to {ExpirationProcessTimerInSecondsDefault}", ExpirationProcessTimerInSecondsDefault);
return ExpirationProcessTimerInSecondsDefault;
}
- if (expirationProcessTimerInSeconds > TimeSpan.FromHours(3).TotalSeconds)
+ if (expirationProcessTimerInSeconds > maxExpirationProcessTimerInSeconds)
{
- Logger.Error($"ExpirationProcessTimerInSeconds cannot be larger than {TimeSpan.FromHours(3).TotalSeconds}. Defaulting to {ExpirationProcessTimerInSecondsDefault}");
+ Logger.LogError("ExpirationProcessTimerInSeconds cannot be larger than {MaxExpirationProcessTimerInSeconds}. Defaulting to {ExpirationProcessTimerInSecondsDefault}", maxExpirationProcessTimerInSeconds, ExpirationProcessTimerInSecondsDefault);
return ExpirationProcessTimerInSecondsDefault;
}
@@ -165,15 +168,17 @@ static int GetBulkInsertCommitTimeout(PersistenceSettings settings)
bulkInsertCommitTimeoutInSeconds = int.Parse(bulkInsertCommitTimeoutString);
}
+ var maxBulkInsertCommitTimeoutInSeconds = TimeSpan.FromHours(1).TotalSeconds;
+
if (bulkInsertCommitTimeoutInSeconds < 0)
{
- Logger.Error($"BulkInsertCommitTimeout cannot be negative. Defaulting to {BulkInsertCommitTimeoutInSecondsDefault}");
+ Logger.LogError("BulkInsertCommitTimeout cannot be negative. Defaulting to {BulkInsertCommitTimeoutInSecondsDefault}", BulkInsertCommitTimeoutInSecondsDefault);
return BulkInsertCommitTimeoutInSecondsDefault;
}
- if (bulkInsertCommitTimeoutInSeconds > TimeSpan.FromHours(1).TotalSeconds)
+ if (bulkInsertCommitTimeoutInSeconds > maxBulkInsertCommitTimeoutInSeconds)
{
- Logger.Error($"BulkInsertCommitTimeout cannot be larger than {TimeSpan.FromHours(1).TotalSeconds}. Defaulting to {BulkInsertCommitTimeoutInSecondsDefault}");
+ Logger.LogError("BulkInsertCommitTimeout cannot be larger than {MaxBulkInsertCommitTimeoutInSeconds}. Defaulting to {BulkInsertCommitTimeoutInSecondsDefault}", maxBulkInsertCommitTimeoutInSeconds, BulkInsertCommitTimeoutInSecondsDefault);
return BulkInsertCommitTimeoutInSecondsDefault;
}
@@ -193,9 +198,8 @@ static string GetLogPath(PersistenceSettings settings)
return logPath;
}
- static readonly ILog Logger = LogManager.GetLogger(typeof(RavenPersistenceConfiguration));
-
const int ExpirationProcessTimerInSecondsDefault = 600;
const int BulkInsertCommitTimeoutInSecondsDefault = 60;
+ static readonly ILogger Logger = LoggerUtil.CreateStaticLogger();
}
}
diff --git a/src/ServiceControl.Audit.Persistence.Tests.RavenDB/IndexSetupTests.cs b/src/ServiceControl.Audit.Persistence.Tests.RavenDB/IndexSetupTests.cs
index 678915f391..b31c3288a9 100644
--- a/src/ServiceControl.Audit.Persistence.Tests.RavenDB/IndexSetupTests.cs
+++ b/src/ServiceControl.Audit.Persistence.Tests.RavenDB/IndexSetupTests.cs
@@ -1,7 +1,6 @@
namespace ServiceControl.Audit.Persistence.Tests;
using System;
-using System.Threading;
using System.Threading.Tasks;
using NUnit.Framework;
using Persistence.RavenDB;
diff --git a/src/ServiceControl.Audit.Persistence/BodyStorageEnricher.cs b/src/ServiceControl.Audit.Persistence/BodyStorageEnricher.cs
index 03e4ae479f..c7794e30ba 100644
--- a/src/ServiceControl.Audit.Persistence/BodyStorageEnricher.cs
+++ b/src/ServiceControl.Audit.Persistence/BodyStorageEnricher.cs
@@ -5,12 +5,12 @@
using System.Text;
using System.Threading;
using System.Threading.Tasks;
+ using Microsoft.Extensions.Logging;
using NServiceBus;
- using NServiceBus.Logging;
using ServiceControl.Audit.Persistence;
using ServiceControl.Infrastructure;
- public class BodyStorageEnricher(IBodyStorage bodyStorage, PersistenceSettings settings)
+ public class BodyStorageEnricher(IBodyStorage bodyStorage, PersistenceSettings settings, ILogger logger)
{
public async ValueTask StoreAuditMessageBody(ReadOnlyMemory body, ProcessedMessage processedMessage, CancellationToken cancellationToken)
{
@@ -66,7 +66,7 @@ async ValueTask TryStoreBody(ReadOnlyMemory body, ProcessedMessage p
catch (DecoderFallbackException e)
{
useBodyStore = true;
- log.Info($"Body for {bodyId} could not be stored embedded, fallback to body storage ({e.Message})");
+ logger.LogInformation("Body for {BodyId} could not be stored embedded, fallback to body storage ({ErrorMessage})", bodyId, e.Message);
}
}
@@ -111,7 +111,6 @@ static bool IsBinary(IReadOnlyDictionary headers)
}
static readonly Encoding enc = new UTF8Encoding(true, true);
- static readonly ILog log = LogManager.GetLogger();
// large object heap starts above 85000 bytes and not above 85 KB!
public const int LargeObjectHeapThreshold = 85 * 1000;
diff --git a/src/ServiceControl.Audit.Persistence/PersistenceManifest.cs b/src/ServiceControl.Audit.Persistence/PersistenceManifest.cs
index 6638cda025..8ff8bcfb16 100644
--- a/src/ServiceControl.Audit.Persistence/PersistenceManifest.cs
+++ b/src/ServiceControl.Audit.Persistence/PersistenceManifest.cs
@@ -5,7 +5,8 @@
using System.IO;
using System.Linq;
using System.Text.Json;
- using NServiceBus.Logging;
+ using Microsoft.Extensions.Logging;
+ using ServiceControl.Infrastructure;
public class PersistenceManifest
{
@@ -51,7 +52,7 @@ static PersistenceManifestLibrary()
}
catch (Exception ex)
{
- logger.Warn($"Failed to load persistence manifests from {assemblyDirectory}", ex);
+ logger.LogWarning(ex, "Failed to load persistence manifests from {AssemblyDirectory}", assemblyDirectory);
}
try
@@ -66,10 +67,10 @@ static PersistenceManifestLibrary()
}
catch (Exception ex)
{
- logger.Warn($"Failed to load persistence manifests from development locations", ex);
+ logger.LogWarning(ex, "Failed to load persistence manifests from development locations");
}
- PersistenceManifests.ForEach(m => logger.Info($"Found persistence manifest for {m.DisplayName}"));
+ PersistenceManifests.ForEach(m => logger.LogInformation("Found persistence manifest for {ManifestDisplayName}", m.DisplayName));
}
static string GetAssemblyDirectory()
@@ -90,7 +91,7 @@ public static PersistenceManifest Find(string persistenceType)
return persistenceManifest;
}
- static readonly ILog logger = LogManager.GetLogger(typeof(PersistenceManifestLibrary));
+ static readonly ILogger logger = LoggerUtil.CreateStaticLogger(typeof(PersistenceManifestLibrary));
}
}
diff --git a/src/ServiceControl.Audit.UnitTests/ApprovalFiles/APIApprovals.PlatformSampleSettings.approved.txt b/src/ServiceControl.Audit.UnitTests/ApprovalFiles/APIApprovals.PlatformSampleSettings.approved.txt
index f718f461aa..7113c06339 100644
--- a/src/ServiceControl.Audit.UnitTests/ApprovalFiles/APIApprovals.PlatformSampleSettings.approved.txt
+++ b/src/ServiceControl.Audit.UnitTests/ApprovalFiles/APIApprovals.PlatformSampleSettings.approved.txt
@@ -1,9 +1,6 @@
{
"LoggingSettings": {
- "LogLevel": {
- "Name": "Info",
- "Ordinal": 2
- },
+ "LogLevel": "Information",
"LogPath": "C:\\Logs"
},
"MessageFilter": null,
diff --git a/src/ServiceControl.Audit.UnitTests/BodyStorage/BodyStorageEnricherTests.cs b/src/ServiceControl.Audit.UnitTests/BodyStorage/BodyStorageEnricherTests.cs
index 05ce6871cc..87e1bbe9db 100644
--- a/src/ServiceControl.Audit.UnitTests/BodyStorage/BodyStorageEnricherTests.cs
+++ b/src/ServiceControl.Audit.UnitTests/BodyStorage/BodyStorageEnricherTests.cs
@@ -11,6 +11,7 @@ namespace ServiceControl.UnitTests.BodyStorage
using NServiceBus;
using NUnit.Framework;
using ServiceControl.Audit.Persistence;
+ using ServiceControl.Infrastructure;
[TestFixture]
public class BodyStorageEnricherTests
@@ -21,7 +22,7 @@ public async Task Should_remove_body_when_above_threshold()
var fakeStorage = new FakeBodyStorage();
var maxBodySizeToStore = 20000;
- var enricher = new BodyStorageEnricher(fakeStorage, new PersistenceSettings(TimeSpan.FromHours(1), true, maxBodySizeToStore));
+ var enricher = new BodyStorageEnricher(fakeStorage, new PersistenceSettings(TimeSpan.FromHours(1), true, maxBodySizeToStore), LoggerUtil.CreateStaticLogger());
var body = Encoding.UTF8.GetBytes(new string('a', maxBodySizeToStore + 1));
var metadata = new Dictionary();
@@ -51,7 +52,7 @@ public async Task Should_remove_body_when_above_threshold_and_binary()
var fakeStorage = new FakeBodyStorage();
var maxBodySizeToStore = 20000;
- var enricher = new BodyStorageEnricher(fakeStorage, new PersistenceSettings(TimeSpan.FromHours(1), true, maxBodySizeToStore));
+ var enricher = new BodyStorageEnricher(fakeStorage, new PersistenceSettings(TimeSpan.FromHours(1), true, maxBodySizeToStore), LoggerUtil.CreateStaticLogger());
var body = Encoding.UTF8.GetBytes(new string('a', maxBodySizeToStore + 1));
var metadata = new Dictionary();
var headers = new Dictionary
@@ -81,7 +82,7 @@ public async Task Should_store_body_in_metadata_when_below_large_object_heap_and
var fakeStorage = new FakeBodyStorage();
var maxBodySizeToStore = 100000;
- var enricher = new BodyStorageEnricher(fakeStorage, new PersistenceSettings(TimeSpan.FromHours(1), true, maxBodySizeToStore));
+ var enricher = new BodyStorageEnricher(fakeStorage, new PersistenceSettings(TimeSpan.FromHours(1), true, maxBodySizeToStore), LoggerUtil.CreateStaticLogger());
var expectedBodySize = BodyStorageEnricher.LargeObjectHeapThreshold - 1;
var body = Encoding.UTF8.GetBytes(new string('a', expectedBodySize));
var metadata = new Dictionary();
@@ -113,7 +114,7 @@ public async Task Should_store_body_in_body_property_when_full_text_disabled_and
var fakeStorage = new FakeBodyStorage();
var maxBodySizeToStore = 100000;
- var enricher = new BodyStorageEnricher(fakeStorage, new PersistenceSettings(TimeSpan.FromHours(1), false, maxBodySizeToStore));
+ var enricher = new BodyStorageEnricher(fakeStorage, new PersistenceSettings(TimeSpan.FromHours(1), false, maxBodySizeToStore), LoggerUtil.CreateStaticLogger());
var expectedBodySize = BodyStorageEnricher.LargeObjectHeapThreshold - 1;
var body = Encoding.UTF8.GetBytes(new string('a', expectedBodySize));
var metadata = new Dictionary();
@@ -145,7 +146,7 @@ public async Task Should_store_body_in_storage_when_above_large_object_heap_but_
var fakeStorage = new FakeBodyStorage();
var maxBodySizeToStore = 100000;
- var enricher = new BodyStorageEnricher(fakeStorage, new PersistenceSettings(TimeSpan.FromHours(1), true, maxBodySizeToStore));
+ var enricher = new BodyStorageEnricher(fakeStorage, new PersistenceSettings(TimeSpan.FromHours(1), true, maxBodySizeToStore), LoggerUtil.CreateStaticLogger());
var expectedBodySize = BodyStorageEnricher.LargeObjectHeapThreshold + 1;
var body = Encoding.UTF8.GetBytes(new string('a', expectedBodySize));
var metadata = new Dictionary();
@@ -177,7 +178,7 @@ public async Task Should_store_body_in_storage_when_below_threshold_and_binary()
var fakeStorage = new FakeBodyStorage();
var maxBodySizeToStore = 100000;
- var enricher = new BodyStorageEnricher(fakeStorage, new PersistenceSettings(TimeSpan.FromHours(1), true, maxBodySizeToStore));
+ var enricher = new BodyStorageEnricher(fakeStorage, new PersistenceSettings(TimeSpan.FromHours(1), true, maxBodySizeToStore), LoggerUtil.CreateStaticLogger());
var expectedBodySize = BodyStorageEnricher.LargeObjectHeapThreshold + 1;
var body = Encoding.UTF8.GetBytes(new string('a', expectedBodySize));
var metadata = new Dictionary();
@@ -208,7 +209,7 @@ public async Task Should_store_body_in_storage_when_below_threshold()
var fakeStorage = new FakeBodyStorage();
var maxBodySizeToStore = 100000;
- var enricher = new BodyStorageEnricher(fakeStorage, new PersistenceSettings(TimeSpan.FromHours(1), true, maxBodySizeToStore));
+ var enricher = new BodyStorageEnricher(fakeStorage, new PersistenceSettings(TimeSpan.FromHours(1), true, maxBodySizeToStore), LoggerUtil.CreateStaticLogger());
var expectedBodySize = BodyStorageEnricher.LargeObjectHeapThreshold + 1;
var body = Encoding.UTF8.GetBytes(new string('a', expectedBodySize));
var metadata = new Dictionary();
@@ -239,7 +240,7 @@ public async Task Should_store_body_in_storage_when_encoding_fails()
var fakeStorage = new FakeBodyStorage();
var maxBodySizeToStore = 100000;
- var enricher = new BodyStorageEnricher(fakeStorage, new PersistenceSettings(TimeSpan.FromHours(1), true, maxBodySizeToStore));
+ var enricher = new BodyStorageEnricher(fakeStorage, new PersistenceSettings(TimeSpan.FromHours(1), true, maxBodySizeToStore), LoggerUtil.CreateStaticLogger());
var body = new byte[] { 0x00, 0xDE };
var metadata = new Dictionary();
diff --git a/src/ServiceControl.Audit/App.config b/src/ServiceControl.Audit/App.config
index 00a70ad0a2..9452cd7e00 100644
--- a/src/ServiceControl.Audit/App.config
+++ b/src/ServiceControl.Audit/App.config
@@ -21,6 +21,10 @@ These settings are only here so that we can debug ServiceControl while developin
+
+
+
+
diff --git a/src/ServiceControl.Audit/Auditing/AuditIngestion.cs b/src/ServiceControl.Audit/Auditing/AuditIngestion.cs
index e36f2036cb..ea417c25a8 100644
--- a/src/ServiceControl.Audit/Auditing/AuditIngestion.cs
+++ b/src/ServiceControl.Audit/Auditing/AuditIngestion.cs
@@ -8,8 +8,8 @@
using Infrastructure.Settings;
using Metrics;
using Microsoft.Extensions.Hosting;
+ using Microsoft.Extensions.Logging;
using NServiceBus;
- using NServiceBus.Logging;
using NServiceBus.Transport;
using Persistence;
using Persistence.UnitOfWork;
@@ -27,7 +27,8 @@ public AuditIngestion(
AuditIngestor auditIngestor,
IAuditIngestionUnitOfWorkFactory unitOfWorkFactory,
IHostApplicationLifetime applicationLifetime,
- IngestionMetrics metrics
+ IngestionMetrics metrics,
+ ILogger logger
)
{
inputEndpoint = settings.AuditQueue;
@@ -38,7 +39,7 @@ IngestionMetrics metrics
this.settings = settings;
this.applicationLifetime = applicationLifetime;
this.metrics = metrics;
-
+ this.logger = logger;
if (!transportSettings.MaxConcurrency.HasValue)
{
throw new ArgumentException("MaxConcurrency is not set in TransportSettings");
@@ -54,7 +55,7 @@ IngestionMetrics metrics
FullMode = BoundedChannelFullMode.Wait
});
- errorHandlingPolicy = new AuditIngestionFaultPolicy(failedImportsStorage, settings.LoggingSettings, OnCriticalError, metrics);
+ errorHandlingPolicy = new AuditIngestionFaultPolicy(failedImportsStorage, settings.LoggingSettings, OnCriticalError, metrics, logger);
watchdog = new Watchdog(
"audit message ingestion",
@@ -69,7 +70,7 @@ IngestionMetrics metrics
Task OnCriticalError(string failure, Exception exception)
{
- logger.Fatal($"OnCriticalError. '{failure}'", exception);
+ logger.LogCritical(exception, "OnCriticalError. '{Failure}'", failure);
return watchdog.OnFailure(failure);
}
@@ -81,7 +82,7 @@ async Task EnsureStarted(CancellationToken cancellationToken)
var canIngest = unitOfWorkFactory.CanIngestMore();
- logger.DebugFormat("Ensure started {0}", canIngest);
+ logger.LogDebug("Ensure started {CanIngest}", canIngest);
if (canIngest)
{
@@ -115,13 +116,13 @@ async Task SetUpAndStartInfrastructure(CancellationToken cancellationToken)
{
if (messageReceiver != null)
{
- logger.Debug("Infrastructure already Started");
+ logger.LogDebug("Infrastructure already Started");
return;
}
try
{
- logger.Info("Starting infrastructure");
+ logger.LogInformation("Starting infrastructure");
transportInfrastructure = await transportCustomization.CreateTransportInfrastructure(
inputEndpoint,
transportSettings,
@@ -136,11 +137,11 @@ async Task SetUpAndStartInfrastructure(CancellationToken cancellationToken)
await auditIngestor.VerifyCanReachForwardingAddress(cancellationToken);
await messageReceiver.StartReceive(cancellationToken);
- logger.Info(LogMessages.StartedInfrastructure);
+ logger.LogInformation(LogMessages.StartedInfrastructure);
}
catch (Exception e)
{
- logger.Error("Failed to start infrastructure", e);
+ logger.LogError(e, "Failed to start infrastructure");
throw;
}
}
@@ -149,13 +150,13 @@ async Task StopAndTeardownInfrastructure(CancellationToken cancellationToken)
{
if (transportInfrastructure == null)
{
- logger.Debug("Infrastructure already Stopped");
+ logger.LogDebug("Infrastructure already Stopped");
return;
}
try
{
- logger.Info("Stopping infrastructure");
+ logger.LogInformation("Stopping infrastructure");
try
{
if (messageReceiver != null)
@@ -171,11 +172,11 @@ async Task StopAndTeardownInfrastructure(CancellationToken cancellationToken)
messageReceiver = null;
transportInfrastructure = null;
- logger.Info(LogMessages.StoppedInfrastructure);
+ logger.LogInformation(LogMessages.StoppedInfrastructure);
}
catch (Exception e)
{
- logger.Error("Failed to stop infrastructure", e);
+ logger.LogError(e, "Failed to stop infrastructure");
throw;
}
}
@@ -254,11 +255,11 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
if (e is OperationCanceledException && stoppingToken.IsCancellationRequested)
{
- logger.Info("Batch cancelled", e);
+ logger.LogInformation(e, "Batch cancelled");
break;
}
- logger.Info("Ingesting messages failed", e);
+ logger.LogInformation(e, "Ingesting messages failed");
}
finally
{
@@ -291,7 +292,7 @@ public override async Task StopAsync(CancellationToken cancellationToken)
}
catch (OperationCanceledException e) when (cancellationToken.IsCancellationRequested)
{
- logger.Info("Shutdown cancelled", e);
+ logger.LogInformation(e, "Shutdown cancelled");
}
}
}
@@ -313,8 +314,7 @@ public override async Task StopAsync(CancellationToken cancellationToken)
readonly Watchdog watchdog;
readonly IHostApplicationLifetime applicationLifetime;
readonly IngestionMetrics metrics;
-
- static readonly ILog logger = LogManager.GetLogger();
+ readonly ILogger logger;
internal static class LogMessages
{
diff --git a/src/ServiceControl.Audit/Auditing/AuditIngestionFaultPolicy.cs b/src/ServiceControl.Audit/Auditing/AuditIngestionFaultPolicy.cs
index 6ccfbedcce..02c55db1a9 100644
--- a/src/ServiceControl.Audit/Auditing/AuditIngestionFaultPolicy.cs
+++ b/src/ServiceControl.Audit/Auditing/AuditIngestionFaultPolicy.cs
@@ -7,21 +7,27 @@
using System.Runtime.Versioning;
using System.Threading;
using System.Threading.Tasks;
+using Configuration;
using Infrastructure;
-using NServiceBus.Logging;
+using Metrics;
+using Microsoft.Extensions.Logging;
using NServiceBus.Transport;
using Persistence;
-using Configuration;
-using Metrics;
using ServiceControl.Infrastructure;
class AuditIngestionFaultPolicy
{
- public AuditIngestionFaultPolicy(IFailedAuditStorage failedAuditStorage, LoggingSettings settings, Func onCriticalError, IngestionMetrics metrics)
+ public AuditIngestionFaultPolicy(
+ IFailedAuditStorage failedAuditStorage,
+ LoggingSettings settings,
+ Func onCriticalError,
+ IngestionMetrics metrics,
+ ILogger logger)
{
failureCircuitBreaker = new ImportFailureCircuitBreaker(onCriticalError);
this.failedAuditStorage = failedAuditStorage;
this.metrics = metrics;
+ this.logger = logger;
if (!AppEnvironment.RunningInContainer)
{
@@ -75,7 +81,7 @@ async Task StoreFailedMessageDocument(ErrorContext errorContext, CancellationTok
async Task DoLogging(Exception exception, FailedAuditImport failure, CancellationToken cancellationToken)
{
- log.Error("Failed importing error message", exception);
+ logger.LogError(exception, "Failed importing error message");
// Write to storage
await failedAuditStorage.SaveFailedAuditImport(failure);
@@ -83,12 +89,12 @@ async Task DoLogging(Exception exception, FailedAuditImport failure, Cancellatio
if (!AppEnvironment.RunningInContainer)
{
// Write to Log Path
- var filePath = Path.Combine(logPath, failure.Id + ".txt");
+ var filePath = Path.Combine(logPath, $"{failure.Id}.txt");
await File.WriteAllTextAsync(filePath, failure.ExceptionInfo, cancellationToken);
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
- WriteToEventLog("A message import has failed. A log file has been written to " + filePath);
+ WriteToEventLog($"A message import has failed. A log file has been written to {filePath}");
}
}
}
@@ -107,5 +113,5 @@ void WriteToEventLog(string message)
readonly string logPath;
readonly ImportFailureCircuitBreaker failureCircuitBreaker;
- static readonly ILog log = LogManager.GetLogger();
+ readonly ILogger logger;
}
\ No newline at end of file
diff --git a/src/ServiceControl.Audit/Auditing/AuditIngestor.cs b/src/ServiceControl.Audit/Auditing/AuditIngestor.cs
index bf48d23e96..af5bbdac58 100644
--- a/src/ServiceControl.Audit/Auditing/AuditIngestor.cs
+++ b/src/ServiceControl.Audit/Auditing/AuditIngestor.cs
@@ -6,9 +6,9 @@
using System.Threading;
using System.Threading.Tasks;
using Infrastructure.Settings;
+ using Microsoft.Extensions.Logging;
using Monitoring;
using NServiceBus;
- using NServiceBus.Logging;
using NServiceBus.Routing;
using NServiceBus.Transport;
using Persistence.UnitOfWork;
@@ -25,12 +25,13 @@ public AuditIngestor(
IEnumerable auditEnrichers, // allows extending message enrichers with custom enrichers registered in the DI container
IMessageSession messageSession,
Lazy messageDispatcher,
- ITransportCustomization transportCustomization
+ ITransportCustomization transportCustomization,
+ ILogger logger
)
{
this.settings = settings;
this.messageDispatcher = messageDispatcher;
-
+ this.logger = logger;
var enrichers = new IEnrichImportedAuditMessages[] { new MessageTypeEnricher(), new EnrichWithTrackingIds(), new ProcessingStatisticsEnricher(), new DetectNewEndpointsFromAuditImportsEnricher(endpointInstanceMonitoring), new DetectSuccessfulRetriesEnricher(), new SagaRelationshipsEnricher() }.Concat(auditEnrichers).ToArray();
logQueueAddress = transportCustomization.ToTransportQualifiedQueueName(settings.AuditLogQueue);
@@ -39,7 +40,8 @@ ITransportCustomization transportCustomization
unitOfWorkFactory,
enrichers,
messageSession,
- messageDispatcher
+ messageDispatcher,
+ logger
);
}
@@ -61,7 +63,7 @@ public async Task Ingest(List contexts, CancellationToken cancel
}
catch (Exception e)
{
- Log.Warn("Forwarding messages failed", e);
+ logger.LogWarning(e, "Forwarding messages failed");
// making sure to rethrow so that all messages get marked as failed
throw;
@@ -129,6 +131,6 @@ public async Task VerifyCanReachForwardingAddress(CancellationToken cancellation
readonly Lazy messageDispatcher;
readonly string logQueueAddress;
- static readonly ILog Log = LogManager.GetLogger();
+ readonly ILogger logger;
}
}
\ No newline at end of file
diff --git a/src/ServiceControl.Audit/Auditing/AuditPersister.cs b/src/ServiceControl.Audit/Auditing/AuditPersister.cs
index e50f18b086..136688919e 100644
--- a/src/ServiceControl.Audit/Auditing/AuditPersister.cs
+++ b/src/ServiceControl.Audit/Auditing/AuditPersister.cs
@@ -6,9 +6,9 @@
using System.Threading;
using System.Threading.Tasks;
using Infrastructure;
+ using Microsoft.Extensions.Logging;
using Monitoring;
using NServiceBus;
- using NServiceBus.Logging;
using NServiceBus.Transport;
using Persistence.UnitOfWork;
using ServiceControl.Audit.Persistence.Infrastructure;
@@ -20,7 +20,8 @@
class AuditPersister(IAuditIngestionUnitOfWorkFactory unitOfWorkFactory,
IEnrichImportedAuditMessages[] enrichers,
IMessageSession messageSession,
- Lazy messageDispatcher)
+ Lazy messageDispatcher,
+ ILogger logger)
{
public async Task> Persist(IReadOnlyList contexts, CancellationToken cancellationToken)
{
@@ -72,20 +73,14 @@ public async Task> Persist(IReadOnlyList> Persist(IReadOnlyList> Persist(IReadOnlyList(metadata));
- if (Logger.IsDebugEnabled)
- {
- Logger.Debug($"Emitting {commandsToEmit.Count} commands and {messagesToEmit.Count} control messages.");
- }
+ logger.LogDebug("Emitting {CommandsToEmitCount} commands and {MessagesToEmitCount} control messages", commandsToEmit.Count, messagesToEmit.Count);
foreach (var commandToEmit in commandsToEmit)
{
@@ -215,10 +198,7 @@ async Task ProcessAuditMessage(MessageContext context)
await messageDispatcher.Value.Dispatch(new TransportOperations(messagesToEmit.ToArray()),
new TransportTransaction()); //Do not hook into the incoming transaction
- if (Logger.IsDebugEnabled)
- {
- Logger.Debug($"{commandsToEmit.Count} commands and {messagesToEmit.Count} control messages emitted.");
- }
+ logger.LogDebug("{CommandsToEmitCount} commands and {MessagesToEmitCount} control messages emitted", commandsToEmit.Count, messagesToEmit.Count);
if (metadata.TryGetValue("SendingEndpoint", out var sendingEndpoint))
{
@@ -235,16 +215,11 @@ await messageDispatcher.Value.Dispatch(new TransportOperations(messagesToEmit.To
}
catch (Exception e)
{
- if (Logger.IsWarnEnabled)
- {
- Logger.Warn($"Processing of message '{messageId}' failed.", e);
- }
+ logger.LogWarning(e, "Processing of message '{MessageId}' failed", messageId);
// releasing the failed message context early so that they can be retried outside the current batch
context.GetTaskCompletionSource().TrySetException(e);
}
}
-
- static readonly ILog Logger = LogManager.GetLogger();
}
}
\ No newline at end of file
diff --git a/src/ServiceControl.Audit/Auditing/FailedAuditImportCustomCheck.cs b/src/ServiceControl.Audit/Auditing/FailedAuditImportCustomCheck.cs
index 8a914d9cd0..9f0190a051 100644
--- a/src/ServiceControl.Audit/Auditing/FailedAuditImportCustomCheck.cs
+++ b/src/ServiceControl.Audit/Auditing/FailedAuditImportCustomCheck.cs
@@ -3,16 +3,17 @@ namespace ServiceControl.Audit.Auditing
using System;
using System.Threading;
using System.Threading.Tasks;
+ using Microsoft.Extensions.Logging;
using NServiceBus.CustomChecks;
- using NServiceBus.Logging;
using ServiceControl.Audit.Persistence;
class FailedAuditImportCustomCheck : CustomCheck
{
- public FailedAuditImportCustomCheck(IFailedAuditStorage store)
+ public FailedAuditImportCustomCheck(IFailedAuditStorage store, ILogger logger)
: base("Audit Message Ingestion", "ServiceControl.Audit Health", TimeSpan.FromHours(1))
{
this.store = store;
+ this.logger = logger;
}
public override async Task PerformCheck(CancellationToken cancellationToken = default)
@@ -20,7 +21,7 @@ public override async Task PerformCheck(CancellationToken cancellat
var count = await store.GetFailedAuditsCount();
if (count > 0)
{
- Logger.Warn(message);
+ logger.LogWarning(message);
return CheckResult.Failed(message);
}
@@ -32,6 +33,6 @@ public override async Task PerformCheck(CancellationToken cancellat
const string message = @"One or more audit messages have failed to import properly into ServiceControl.Audit and have been stored in the ServiceControl.Audit database.
The import of these messages could have failed for a number of reasons and ServiceControl.Audit is not able to automatically reimport them. For guidance on how to resolve this see https://docs.particular.net/servicecontrol/import-failed-messages";
- static readonly ILog Logger = LogManager.GetLogger(typeof(FailedAuditImportCustomCheck));
+ readonly ILogger logger;
}
}
\ No newline at end of file
diff --git a/src/ServiceControl.Audit/Auditing/ImportFailedAudits.cs b/src/ServiceControl.Audit/Auditing/ImportFailedAudits.cs
index ee0f0dd6ef..07cbdebc9b 100644
--- a/src/ServiceControl.Audit/Auditing/ImportFailedAudits.cs
+++ b/src/ServiceControl.Audit/Auditing/ImportFailedAudits.cs
@@ -4,8 +4,8 @@ namespace ServiceControl.Audit.Auditing
using System.Threading;
using System.Threading.Tasks;
using Infrastructure.Settings;
+ using Microsoft.Extensions.Logging;
using NServiceBus.Extensibility;
- using NServiceBus.Logging;
using NServiceBus.Transport;
using Persistence;
@@ -14,11 +14,13 @@ public class ImportFailedAudits
public ImportFailedAudits(
IFailedAuditStorage failedAuditStore,
AuditIngestor auditIngestor,
- Settings settings)
+ Settings settings,
+ ILogger logger)
{
this.settings = settings;
this.failedAuditStore = failedAuditStore;
this.auditIngestor = auditIngestor;
+ this.logger = logger;
}
public async Task Run(CancellationToken cancellationToken = default)
@@ -50,37 +52,34 @@ await failedAuditStore.ProcessFailedMessages(
await markComplete(token);
succeeded++;
- if (Logger.IsDebugEnabled)
- {
- Logger.Debug($"Successfully re-imported failed audit message {transportMessage.Id}.");
- }
+ logger.LogDebug("Successfully re-imported failed audit message {MessageId}", transportMessage.Id);
}
catch (OperationCanceledException e) when (token.IsCancellationRequested)
{
- Logger.Info("Cancelled", e);
+ logger.LogInformation(e, "Cancelled");
}
catch (Exception e)
{
- Logger.Error($"Error while attempting to re-import failed audit message {transportMessage.Id}.", e);
+ logger.LogError(e, "Error while attempting to re-import failed audit message {MessageId}", transportMessage.Id);
failed++;
}
}, cancellationToken);
- Logger.Info($"Done re-importing failed audits. Successfully re-imported {succeeded} messages. Failed re-importing {failed} messages.");
+ logger.LogInformation("Done re-importing failed audits. Successfully re-imported {SuccessCount} messages. Failed re-importing {FailureCount} messages", succeeded, failed);
if (failed > 0)
{
- Logger.Warn($"{failed} messages could not be re-imported. This could indicate a problem with the data. Contact Particular support if you need help with recovering the messages.");
+ logger.LogWarning("{FailureCount} messages could not be re-imported. This could indicate a problem with the data. Contact Particular support if you need help with recovering the messages", failed);
}
}
readonly IFailedAuditStorage failedAuditStore;
readonly AuditIngestor auditIngestor;
readonly Settings settings;
+ readonly ILogger logger;
static readonly TransportTransaction EmptyTransaction = new TransportTransaction();
static readonly ContextBag EmptyContextBag = new ContextBag();
- static readonly ILog Logger = LogManager.GetLogger(typeof(ImportFailedAudits));
}
}
\ No newline at end of file
diff --git a/src/ServiceControl.Audit/HostApplicationBuilderExtensions.cs b/src/ServiceControl.Audit/HostApplicationBuilderExtensions.cs
index ccacf5db1c..d65a66697f 100644
--- a/src/ServiceControl.Audit/HostApplicationBuilderExtensions.cs
+++ b/src/ServiceControl.Audit/HostApplicationBuilderExtensions.cs
@@ -15,15 +15,14 @@ namespace ServiceControl.Audit;
using Microsoft.Extensions.Hosting.WindowsServices;
using Microsoft.Extensions.Logging;
using Monitoring;
-using NLog.Extensions.Logging;
using NServiceBus;
using NServiceBus.Configuration.AdvancedExtensibility;
-using NServiceBus.Logging;
using NServiceBus.Transport;
using Persistence;
using Transports;
using OpenTelemetry.Metrics;
using OpenTelemetry.Resources;
+using ServiceControl.Infrastructure;
static class HostApplicationBuilderExtensions
{
@@ -40,8 +39,7 @@ public static void AddServiceControlAudit(this IHostApplicationBuilder builder,
RecordStartup(settings, configuration, persistenceConfiguration);
builder.Logging.ClearProviders();
- builder.Logging.AddNLog();
- builder.Logging.SetMinimumLevel(settings.LoggingSettings.ToHostLogLevel());
+ builder.Logging.ConfigureLogging(settings.LoggingSettings.LogLevel);
var services = builder.Services;
var transportSettings = settings.ToTransportSettings();
@@ -120,8 +118,8 @@ public static void AddMetrics(this IHostApplicationBuilder builder, Settings set
}
});
- var logger = LogManager.GetLogger(typeof(HostApplicationBuilderExtensions));
- logger.InfoFormat("OpenTelemetry metrics exporter enabled: {0}", settings.OtlpEndpointUrl);
+ var logger = LoggerUtil.CreateStaticLogger(typeof(HostApplicationBuilderExtensions), settings.LoggingSettings.LogLevel);
+ logger.LogInformation("OpenTelemetry metrics exporter enabled: {OtlpEndpointUrl}", settings.OtlpEndpointUrl);
}
}
@@ -138,8 +136,9 @@ static void RecordStartup(Settings settings, EndpointConfiguration endpointConfi
Persistence: {persistenceConfiguration.Name}
-------------------------------------------------------------";
- var logger = LogManager.GetLogger(typeof(HostApplicationBuilderExtensions));
- logger.Info(startupMessage);
+ var logger = LoggerUtil.CreateStaticLogger(typeof(HostApplicationBuilderExtensions), settings.LoggingSettings.LogLevel);
+ logger.LogInformation(startupMessage);
endpointConfiguration.GetSettings().AddStartupDiagnosticsSection("Startup", new { Settings = settings });
}
+
}
\ No newline at end of file
diff --git a/src/ServiceControl.Audit/Infrastructure/Hosting/Commands/ImportFailedAuditsCommand.cs b/src/ServiceControl.Audit/Infrastructure/Hosting/Commands/ImportFailedAuditsCommand.cs
index 3ddc7ef055..c2b5926d58 100644
--- a/src/ServiceControl.Audit/Infrastructure/Hosting/Commands/ImportFailedAuditsCommand.cs
+++ b/src/ServiceControl.Audit/Infrastructure/Hosting/Commands/ImportFailedAuditsCommand.cs
@@ -6,14 +6,13 @@
using Auditing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
+ using Microsoft.Extensions.Logging;
using NServiceBus;
- using NServiceBus.Logging;
+ using ServiceControl.Infrastructure;
using Settings;
class ImportFailedAuditsCommand : AbstractCommand
{
- readonly ILog logger = LogManager.GetLogger();
-
public override async Task Execute(HostArguments args, Settings settings)
{
settings.IngestAuditMessages = false;
@@ -42,7 +41,7 @@ public override async Task Execute(HostArguments args, Settings settings)
}
catch (OperationCanceledException e) when (tokenSource.IsCancellationRequested)
{
- logger.Info("Cancelled", e);
+ LoggerUtil.CreateStaticLogger().LogInformation(e, "Cancelled");
}
finally
{
diff --git a/src/ServiceControl.Audit/Infrastructure/Hosting/Commands/SetupCommand.cs b/src/ServiceControl.Audit/Infrastructure/Hosting/Commands/SetupCommand.cs
index 2f03b767a8..73480e72e2 100644
--- a/src/ServiceControl.Audit/Infrastructure/Hosting/Commands/SetupCommand.cs
+++ b/src/ServiceControl.Audit/Infrastructure/Hosting/Commands/SetupCommand.cs
@@ -4,7 +4,8 @@
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
- using NServiceBus.Logging;
+ using Microsoft.Extensions.Logging;
+ using ServiceControl.Infrastructure;
using Settings;
using Transports;
@@ -16,7 +17,7 @@ public override async Task Execute(HostArguments args, Settings settings)
{
if (args.SkipQueueCreation)
{
- Logger.Info("Skipping queue creation");
+ LoggerUtil.CreateStaticLogger().LogInformation("Skipping queue creation");
}
else
{
@@ -47,7 +48,5 @@ public override async Task Execute(HostArguments args, Settings settings)
await host.StartAsync();
await host.StopAsync();
}
-
- static readonly ILog Logger = LogManager.GetLogger();
}
}
\ No newline at end of file
diff --git a/src/ServiceControl.Audit/Infrastructure/Settings/Settings.cs b/src/ServiceControl.Audit/Infrastructure/Settings/Settings.cs
index b5488c36a1..dd409f0334 100644
--- a/src/ServiceControl.Audit/Infrastructure/Settings/Settings.cs
+++ b/src/ServiceControl.Audit/Infrastructure/Settings/Settings.cs
@@ -5,8 +5,8 @@
using System.Runtime.Loader;
using System.Text.Json.Serialization;
using Configuration;
+ using Microsoft.Extensions.Logging;
using NLog.Common;
- using NServiceBus.Logging;
using NServiceBus.Transport;
using ServiceControl.Infrastructure;
using Transports;
@@ -75,14 +75,14 @@ void LoadAuditQueueInformation()
if (IngestAuditMessages == false)
{
- logger.Info("Audit ingestion disabled.");
+ logger.LogInformation("Audit ingestion disabled");
}
AuditLogQueue = SettingsReader.Read(serviceBusRootNamespace, "AuditLogQueue", null);
if (AuditLogQueue == null)
{
- logger.Info("No settings found for audit log queue to import, default name will be used");
+ logger.LogInformation("No settings found for audit log queue to import, default name will be used");
AuditLogQueue = Subscope(AuditQueue);
}
}
@@ -141,7 +141,7 @@ public int MaxBodySizeToStore
{
if (maxBodySizeToStore <= 0)
{
- logger.Error($"MaxBodySizeToStore settings is invalid, {1} is the minimum value. Defaulting to {MaxBodySizeToStoreDefault}");
+ logger.LogError("MaxBodySizeToStore settings is invalid, 1 is the minimum value. Defaulting to {MaxBodySizeToStoreDefault}", MaxBodySizeToStoreDefault);
return MaxBodySizeToStoreDefault;
}
@@ -266,6 +266,7 @@ TimeSpan GetAuditRetentionPeriod()
else
{
message = "AuditRetentionPeriod settings is invalid, please make sure it is a TimeSpan.";
+ //TODO: should these InternalLoggers (NLog) be replaced?
InternalLogger.Fatal(message);
throw new Exception(message);
}
@@ -288,7 +289,7 @@ static string Subscope(string address)
}
// logger is intentionally not static to prevent it from being initialized before LoggingConfigurator.ConfigureLogging has been called
- readonly ILog logger = LogManager.GetLogger(typeof(Settings));
+ readonly ILogger logger = LoggerUtil.CreateStaticLogger();
int maxBodySizeToStore = SettingsReader.Read(SettingsRootNamespace, "MaxBodySizeToStore", MaxBodySizeToStoreDefault);
diff --git a/src/ServiceControl.Audit/Infrastructure/WebApi/RootController.cs b/src/ServiceControl.Audit/Infrastructure/WebApi/RootController.cs
index 42c53825d3..159e8c6d49 100644
--- a/src/ServiceControl.Audit/Infrastructure/WebApi/RootController.cs
+++ b/src/ServiceControl.Audit/Infrastructure/WebApi/RootController.cs
@@ -51,7 +51,7 @@ public OkObjectResult Config()
Logging = new
{
settings.LoggingSettings.LogPath,
- LoggingLevel = settings.LoggingSettings.LogLevel.Name
+ LoggingLevel = settings.LoggingSettings.LogLevel
}
},
DataRetention = new
diff --git a/src/ServiceControl.Audit/Program.cs b/src/ServiceControl.Audit/Program.cs
index 1d9e094d8f..dbe5268e93 100644
--- a/src/ServiceControl.Audit/Program.cs
+++ b/src/ServiceControl.Audit/Program.cs
@@ -1,15 +1,21 @@
using System;
using System.Reflection;
-using NServiceBus.Logging;
+using Microsoft.Extensions.Logging;
using ServiceControl.Audit.Infrastructure.Hosting;
using ServiceControl.Audit.Infrastructure.Hosting.Commands;
using ServiceControl.Audit.Infrastructure.Settings;
using ServiceControl.Configuration;
using ServiceControl.Infrastructure;
+ILogger logger = null;
+
try
{
- AppDomain.CurrentDomain.UnhandledException += (s, e) => LogManager.GetLogger(typeof(Program)).Error("Unhandled exception was caught.", e.ExceptionObject as Exception);
+ var loggingSettings = new LoggingSettings(Settings.SettingsRootNamespace);
+ LoggingConfigurator.ConfigureLogging(loggingSettings);
+ logger = LoggerUtil.CreateStaticLogger(typeof(Program));
+
+ AppDomain.CurrentDomain.UnhandledException += (s, e) => logger.LogError(e.ExceptionObject as Exception, "Unhandled exception was caught");
// Hack: See https://github.com/Particular/ServiceControl/issues/4392
var exitCode = await IntegratedSetup.Run();
@@ -29,9 +35,6 @@
return 0;
}
- var loggingSettings = new LoggingSettings(Settings.SettingsRootNamespace);
- LoggingConfigurator.ConfigureLogging(loggingSettings);
-
var settings = new Settings(loggingSettings: loggingSettings);
await new CommandRunner(arguments.Command).Execute(arguments, settings);
@@ -40,12 +43,20 @@
}
catch (Exception ex)
{
- NLog.LogManager.GetCurrentClassLogger().Fatal(ex, "Unrecoverable error");
+ if (logger != null)
+ {
+ logger.LogCritical(ex, "Unrecoverable error");
+ }
+ else
+ {
+ LoggingConfigurator.ConfigureNLog("bootstrap.${shortdate}.txt", "./", NLog.LogLevel.Fatal);
+ NLog.LogManager.GetCurrentClassLogger().Fatal(ex, "Unrecoverable error");
+ }
throw;
}
finally
{
// The following log statement is meant to leave a trail in the logs to determine if the process was killed
- NLog.LogManager.GetCurrentClassLogger().Info("Shutdown complete");
- NLog.LogManager.Shutdown();
+ logger?.LogInformation("Shutdown complete");
+ LoggerUtil.DisposeLoggerFactories();
}
\ No newline at end of file
diff --git a/src/ServiceControl.Audit/ServiceControl.Audit.csproj b/src/ServiceControl.Audit/ServiceControl.Audit.csproj
index ba7d5110d5..7ea57b06f7 100644
--- a/src/ServiceControl.Audit/ServiceControl.Audit.csproj
+++ b/src/ServiceControl.Audit/ServiceControl.Audit.csproj
@@ -32,6 +32,7 @@
+
diff --git a/src/ServiceControl.Configuration/ServiceControl.Configuration.csproj b/src/ServiceControl.Configuration/ServiceControl.Configuration.csproj
index 2a585451b7..302ef7cbea 100644
--- a/src/ServiceControl.Configuration/ServiceControl.Configuration.csproj
+++ b/src/ServiceControl.Configuration/ServiceControl.Configuration.csproj
@@ -2,6 +2,8 @@
net8.0
+ true
+ ..\NServiceBus.snk
diff --git a/src/ServiceControl.DomainEvents/DomainEvents.cs b/src/ServiceControl.DomainEvents/DomainEvents.cs
index 5443c784d7..0367f199fb 100644
--- a/src/ServiceControl.DomainEvents/DomainEvents.cs
+++ b/src/ServiceControl.DomainEvents/DomainEvents.cs
@@ -4,15 +4,10 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
- using NServiceBus.Logging;
+ using Microsoft.Extensions.Logging;
- public class DomainEvents : IDomainEvents
+ public class DomainEvents(IServiceProvider serviceProvider, ILogger logger) : IDomainEvents
{
- static readonly ILog Log = LogManager.GetLogger();
-
- readonly IServiceProvider serviceProvider;
- public DomainEvents(IServiceProvider serviceProvider) => this.serviceProvider = serviceProvider;
-
public async Task Raise(T domainEvent, CancellationToken cancellationToken) where T : IDomainEvent
{
var handlers = serviceProvider.GetServices>();
@@ -25,7 +20,7 @@ await handler.Handle(domainEvent, cancellationToken)
}
catch (Exception e)
{
- Log.Error($"Unexpected error publishing domain event {typeof(T)}", e);
+ logger.LogError(e, "Unexpected error publishing domain event {EventType}", typeof(T));
throw;
}
}
@@ -40,7 +35,7 @@ await handler.Handle(domainEvent, cancellationToken)
}
catch (Exception e)
{
- Log.Error($"Unexpected error publishing domain event {typeof(T)}", e);
+ logger.LogError(e, "Unexpected error publishing domain event {EventType}", typeof(T));
throw;
}
}
diff --git a/src/ServiceControl.DomainEvents/ServiceControl.DomainEvents.csproj b/src/ServiceControl.DomainEvents/ServiceControl.DomainEvents.csproj
index 8b8037bc48..bb654606ec 100644
--- a/src/ServiceControl.DomainEvents/ServiceControl.DomainEvents.csproj
+++ b/src/ServiceControl.DomainEvents/ServiceControl.DomainEvents.csproj
@@ -6,6 +6,7 @@
+
diff --git a/src/ServiceControl.Infrastructure.Tests/WatchdogTests.cs b/src/ServiceControl.Infrastructure.Tests/WatchdogTests.cs
index 3a430ecc72..ea786ed314 100644
--- a/src/ServiceControl.Infrastructure.Tests/WatchdogTests.cs
+++ b/src/ServiceControl.Infrastructure.Tests/WatchdogTests.cs
@@ -3,14 +3,14 @@
using System;
using System.Threading;
using System.Threading.Tasks;
- using NServiceBus.Logging;
+ using Microsoft.Extensions.Logging;
using NUnit.Framework;
using ServiceControl.Infrastructure;
[TestFixture]
public class WatchdogTests
{
- static ILog log = LogManager.GetLogger();
+ static ILogger log = LoggerUtil.CreateStaticLogger();
[Test]
public async Task It_shuts_down_gracefully()
diff --git a/src/ServiceControl.Infrastructure/LoggerUtil.cs b/src/ServiceControl.Infrastructure/LoggerUtil.cs
new file mode 100644
index 0000000000..b00617fbe0
--- /dev/null
+++ b/src/ServiceControl.Infrastructure/LoggerUtil.cs
@@ -0,0 +1,96 @@
+namespace ServiceControl.Infrastructure
+{
+ using System;
+ using System.Collections.Concurrent;
+ using Microsoft.Extensions.DependencyInjection;
+ using Microsoft.Extensions.Logging;
+ using NLog.Extensions.Logging;
+ using OpenTelemetry.Logs;
+ using ServiceControl.Infrastructure.TestLogger;
+
+ [Flags]
+ public enum Loggers
+ {
+ None = 0,
+ Test = 1 << 0,
+ NLog = 1 << 1,
+ Seq = 1 << 2,
+ Otlp = 1 << 3,
+ }
+
+ public static class LoggerUtil
+ {
+ public static Loggers ActiveLoggers { private get; set; } = Loggers.None;
+
+ public static string SeqAddress { private get; set; }
+
+ public static bool IsLoggingTo(Loggers logger)
+ {
+ return (logger & ActiveLoggers) == logger;
+ }
+
+ public static void ConfigureLogging(this ILoggingBuilder loggingBuilder, LogLevel level)
+ {
+ loggingBuilder.SetMinimumLevel(level);
+
+ if (IsLoggingTo(Loggers.Test))
+ {
+ loggingBuilder.Services.AddSingleton(new TestContextProvider(level));
+ }
+ if (IsLoggingTo(Loggers.NLog))
+ {
+ loggingBuilder.AddNLog();
+ }
+ if (IsLoggingTo(Loggers.Seq))
+ {
+ if (!string.IsNullOrWhiteSpace(SeqAddress))
+ {
+ loggingBuilder.AddSeq(SeqAddress);
+ }
+ else
+ {
+ loggingBuilder.AddSeq();
+ }
+ }
+ if (IsLoggingTo(Loggers.Otlp))
+ {
+ loggingBuilder.AddOpenTelemetry(configure => configure.AddOtlpExporter());
+ }
+ }
+
+ static readonly ConcurrentDictionary _factories = new();
+
+ static ILoggerFactory GetOrCreateLoggerFactory(LogLevel level)
+ {
+ if (!_factories.TryGetValue(level, out var factory))
+ {
+ factory = LoggerFactory.Create(configure => configure.ConfigureLogging(level));
+ _factories[level] = factory;
+ }
+
+ return factory;
+ }
+
+ public static ILogger CreateStaticLogger(LogLevel level = LogLevel.Information)
+ {
+ var factory = GetOrCreateLoggerFactory(level);
+ return factory.CreateLogger();
+ }
+
+ public static ILogger CreateStaticLogger(Type type, LogLevel level = LogLevel.Information)
+ {
+ var factory = GetOrCreateLoggerFactory(level);
+ return factory.CreateLogger(type);
+ }
+
+ public static void DisposeLoggerFactories()
+ {
+ foreach (var factory in _factories.Values)
+ {
+ factory.Dispose();
+ }
+
+ _factories.Clear();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ServiceControl.Infrastructure/LoggingConfigurator.cs b/src/ServiceControl.Infrastructure/LoggingConfigurator.cs
index f32c84918c..f86f776bac 100644
--- a/src/ServiceControl.Infrastructure/LoggingConfigurator.cs
+++ b/src/ServiceControl.Infrastructure/LoggingConfigurator.cs
@@ -2,25 +2,39 @@ namespace ServiceControl.Infrastructure
{
using System;
using System.IO;
+ using Microsoft.Extensions.Logging;
using NLog;
using NLog.Config;
- using NLog.Extensions.Logging;
using NLog.Layouts;
using NLog.Targets;
using NServiceBus.Extensions.Logging;
using ServiceControl.Configuration;
-
using LogManager = NServiceBus.Logging.LogManager;
+ using LogLevel = NLog.LogLevel;
public static class LoggingConfigurator
{
public static void ConfigureLogging(LoggingSettings loggingSettings)
{
- if (NLog.LogManager.Configuration != null)
+ //used for loggers outside of ServiceControl (i.e. transports and core) to use the logger factory defined here
+ LogManager.UseFactory(new ExtensionsLoggerFactory(LoggerFactory.Create(configure => configure.ConfigureLogging(loggingSettings.LogLevel))));
+
+ if (!LoggerUtil.IsLoggingTo(Loggers.NLog) || NLog.LogManager.Configuration != null)
{
return;
}
+ var logLevel = loggingSettings.LogLevel.ToNLogLevel();
+ var loggingTo = ConfigureNLog("logfile.${shortdate}.txt", loggingSettings.LogPath, loggingSettings.LogLevel.ToNLogLevel());
+
+ //using LogManager here rather than LoggerUtil.CreateStaticLogger since this is exclusive to NLog
+ var logger = LogManager.GetLogger("LoggingConfiguration");
+ logger.InfoFormat("Logging to {0} with LogLevel '{1}'", loggingTo, logLevel.Name);
+ }
+
+ public static string ConfigureNLog(string logFileName, string logPath, LogLevel logLevel)
+ {
+ //configure NLog
var nlogConfig = new LoggingConfiguration();
var simpleLayout = new SimpleLayout("${longdate}|${processtime}|${threadid}|${level}|${logger}|${message}${onexception:|${exception:format=tostring}}");
@@ -28,8 +42,8 @@ public static void ConfigureLogging(LoggingSettings loggingSettings)
{
Name = "file",
ArchiveEvery = FileArchivePeriod.Day,
- FileName = Path.Combine(loggingSettings.LogPath, "logfile.${shortdate}.txt"),
- ArchiveFileName = Path.Combine(loggingSettings.LogPath, "logfile.{#}.txt"),
+ FileName = Path.Combine(logPath, logFileName),
+ ArchiveFileName = Path.Combine(logPath, "logfile.{#}.txt"),
ArchiveNumbering = ArchiveNumberingMode.DateAndSequence,
Layout = simpleLayout,
MaxArchiveFiles = 14,
@@ -60,23 +74,35 @@ public static void ConfigureLogging(LoggingSettings loggingSettings)
nlogConfig.LoggingRules.Add(aspNetCoreRule);
nlogConfig.LoggingRules.Add(httpClientRule);
- nlogConfig.LoggingRules.Add(new LoggingRule("*", loggingSettings.LogLevel, consoleTarget));
+ nlogConfig.LoggingRules.Add(new LoggingRule("*", logLevel, consoleTarget));
if (!AppEnvironment.RunningInContainer)
{
- nlogConfig.LoggingRules.Add(new LoggingRule("*", loggingSettings.LogLevel, fileTarget));
+ nlogConfig.LoggingRules.Add(new LoggingRule("*", logLevel, fileTarget));
}
NLog.LogManager.Configuration = nlogConfig;
- LogManager.UseFactory(new ExtensionsLoggerFactory(new NLogLoggerFactory()));
-
- var logger = LogManager.GetLogger("LoggingConfiguration");
var logEventInfo = new LogEventInfo { TimeStamp = DateTime.UtcNow };
- var loggingTo = AppEnvironment.RunningInContainer ? "console" : fileTarget.FileName.Render(logEventInfo);
- logger.InfoFormat("Logging to {0} with LogLevel '{1}'", loggingTo, loggingSettings.LogLevel.Name);
+ return AppEnvironment.RunningInContainer ? "console" : fileTarget.FileName.Render(logEventInfo);
+ }
+
+ static LogLevel ToNLogLevel(this Microsoft.Extensions.Logging.LogLevel level)
+ {
+ return level switch
+ {
+ Microsoft.Extensions.Logging.LogLevel.Trace => LogLevel.Trace,
+ Microsoft.Extensions.Logging.LogLevel.Debug => LogLevel.Debug,
+ Microsoft.Extensions.Logging.LogLevel.Information => LogLevel.Info,
+ Microsoft.Extensions.Logging.LogLevel.Warning => LogLevel.Warn,
+ Microsoft.Extensions.Logging.LogLevel.Error => LogLevel.Error,
+ Microsoft.Extensions.Logging.LogLevel.Critical => LogLevel.Fatal,
+ Microsoft.Extensions.Logging.LogLevel.None => LogLevel.Off,
+ _ => LogLevel.Off,
+ };
}
const long megaByte = 1024 * 1024;
+
}
}
\ No newline at end of file
diff --git a/src/ServiceControl.Infrastructure/LoggingSettings.cs b/src/ServiceControl.Infrastructure/LoggingSettings.cs
index 55282759a3..e92e29e7e5 100644
--- a/src/ServiceControl.Infrastructure/LoggingSettings.cs
+++ b/src/ServiceControl.Infrastructure/LoggingSettings.cs
@@ -1,21 +1,48 @@
namespace ServiceControl.Infrastructure;
using System;
+using System.Collections.Generic;
using System.IO;
-using NLog;
-using NLog.Common;
+using System.Linq;
+using Microsoft.Extensions.Logging;
using ServiceControl.Configuration;
-public class LoggingSettings(SettingsRootNamespace rootNamespace, LogLevel defaultLevel = null, string logPath = null)
+public class LoggingSettings
{
- public LogLevel LogLevel { get; } = InitializeLogLevel(rootNamespace, defaultLevel);
+ public LoggingSettings(SettingsRootNamespace rootNamespace, LogLevel defaultLevel = LogLevel.Information, string logPath = null)
+ {
+ var loggingProviders = (SettingsReader.Read(rootNamespace, loggingProvidersKey) ?? "").Split(",");
+ var activeLoggers = Loggers.None;
+ if (loggingProviders.Contains("NLog"))
+ {
+ activeLoggers |= Loggers.NLog;
+ }
+ if (loggingProviders.Contains("Seq"))
+ {
+ activeLoggers |= Loggers.Seq;
+ var seqAddress = SettingsReader.Read(rootNamespace, seqAddressKey);
+ if (!string.IsNullOrWhiteSpace(seqAddress))
+ {
+ LoggerUtil.SeqAddress = seqAddress;
+ }
+ }
+ if (loggingProviders.Contains("Otlp"))
+ {
+ activeLoggers |= Loggers.Otlp;
+ }
+ //this defaults to NLog because historically that was the default, and we don't want to break existing installs that don't have the config key to define loggingProviders
+ LoggerUtil.ActiveLoggers = activeLoggers == Loggers.None ? Loggers.NLog : activeLoggers;
- public string LogPath { get; } = SettingsReader.Read(rootNamespace, "LogPath", Environment.ExpandEnvironmentVariables(logPath ?? DefaultLogLocation()));
+ LogLevel = InitializeLogLevel(rootNamespace, defaultLevel);
+ LogPath = SettingsReader.Read(rootNamespace, logPathKey, Environment.ExpandEnvironmentVariables(logPath ?? DefaultLogLocation()));
+ }
+
+ public LogLevel LogLevel { get; }
+
+ public string LogPath { get; }
static LogLevel InitializeLogLevel(SettingsRootNamespace rootNamespace, LogLevel defaultLevel)
{
- defaultLevel ??= LogLevel.Info;
-
var levelText = SettingsReader.Read(rootNamespace, logLevelKey);
if (string.IsNullOrWhiteSpace(levelText))
@@ -23,31 +50,42 @@ static LogLevel InitializeLogLevel(SettingsRootNamespace rootNamespace, LogLevel
return defaultLevel;
}
- try
- {
- return LogLevel.FromString(levelText);
- }
- catch
- {
- InternalLogger.Warn($"Failed to parse {logLevelKey} setting. Defaulting to {defaultLevel.Name}.");
- return defaultLevel;
- }
+ return ParseLogLevel(levelText, defaultLevel);
}
// SC installer always populates LogPath in app.config on installation/change/upgrade so this will only be used when
// debugging or if the entry is removed manually. In those circumstances default to the folder containing the exe
static string DefaultLogLocation() => Path.Combine(AppContext.BaseDirectory, ".logs");
- public Microsoft.Extensions.Logging.LogLevel ToHostLogLevel() => LogLevel switch
+ // This is not a complete mapping of NLog levels, just the ones that are different.
+ static readonly Dictionary NLogAliases =
+ new(StringComparer.OrdinalIgnoreCase)
+ {
+ ["info"] = LogLevel.Information,
+ ["warn"] = LogLevel.Warning,
+ ["fatal"] = LogLevel.Critical,
+ ["off"] = LogLevel.None
+ };
+
+ static LogLevel ParseLogLevel(string value, LogLevel defaultLevel)
{
- _ when LogLevel == LogLevel.Trace => Microsoft.Extensions.Logging.LogLevel.Trace,
- _ when LogLevel == LogLevel.Debug => Microsoft.Extensions.Logging.LogLevel.Debug,
- _ when LogLevel == LogLevel.Info => Microsoft.Extensions.Logging.LogLevel.Information,
- _ when LogLevel == LogLevel.Warn => Microsoft.Extensions.Logging.LogLevel.Warning,
- _ when LogLevel == LogLevel.Error => Microsoft.Extensions.Logging.LogLevel.Error,
- _ when LogLevel == LogLevel.Fatal => Microsoft.Extensions.Logging.LogLevel.Critical,
- _ => Microsoft.Extensions.Logging.LogLevel.None
- };
+ if (Enum.TryParse(value, ignoreCase: true, out LogLevel parsedLevel))
+ {
+ return parsedLevel;
+ }
+
+ if (NLogAliases.TryGetValue(value.Trim(), out parsedLevel))
+ {
+ return parsedLevel;
+ }
+
+ LoggerUtil.CreateStaticLogger().LogWarning("Failed to parse {LogLevelKey} setting. Defaulting to {DefaultLevel}", logLevelKey, defaultLevel);
+
+ return defaultLevel;
+ }
const string logLevelKey = "LogLevel";
+ const string logPathKey = "LogPath";
+ const string loggingProvidersKey = "LoggingProviders";
+ const string seqAddressKey = "SeqAddress";
}
\ No newline at end of file
diff --git a/src/ServiceControl.Infrastructure/RavenDbLogLevelToLogsModeMapper.cs b/src/ServiceControl.Infrastructure/RavenDbLogLevelToLogsModeMapper.cs
index 8711bc9854..d3316ba830 100644
--- a/src/ServiceControl.Infrastructure/RavenDbLogLevelToLogsModeMapper.cs
+++ b/src/ServiceControl.Infrastructure/RavenDbLogLevelToLogsModeMapper.cs
@@ -1,12 +1,10 @@
namespace ServiceControl
{
- using NServiceBus.Logging;
+ using Microsoft.Extensions.Logging;
public class RavenDbLogLevelToLogsModeMapper
{
- static readonly ILog Logger = LogManager.GetLogger(typeof(RavenDbLogLevelToLogsModeMapper));
-
- public static string Map(string ravenDbLogLevel)
+ public static string Map(string ravenDbLogLevel, ILogger logger)
{
switch (ravenDbLogLevel.ToLower())
{
@@ -24,7 +22,7 @@ public static string Map(string ravenDbLogLevel)
case "operations":
return "Operations";
default:
- Logger.WarnFormat("Unknown log level '{0}', mapped to 'Operations'", ravenDbLogLevel);
+ logger.LogWarning("Unknown log level '{RavenDbLogLevel}', mapped to 'Operations'", ravenDbLogLevel);
return "Operations";
}
}
diff --git a/src/ServiceControl.Infrastructure/RepeatedFailuresOverTimeCircuitBreaker.cs b/src/ServiceControl.Infrastructure/RepeatedFailuresOverTimeCircuitBreaker.cs
index abd6c9a354..12e77ab01b 100644
--- a/src/ServiceControl.Infrastructure/RepeatedFailuresOverTimeCircuitBreaker.cs
+++ b/src/ServiceControl.Infrastructure/RepeatedFailuresOverTimeCircuitBreaker.cs
@@ -5,7 +5,7 @@ namespace NServiceBus;
using System;
using System.Threading;
using System.Threading.Tasks;
-using Logging;
+using Microsoft.Extensions.Logging;
///
/// A circuit breaker that is armed on a failure and disarmed on success. After in the
@@ -44,6 +44,7 @@ public RepeatedFailuresOverTimeCircuitBreaker(
string name,
TimeSpan timeToWaitBeforeTriggering,
Action triggerAction,
+ ILogger logger,
Action? armedAction = null,
Action? disarmedAction = null,
TimeSpan? timeToWaitWhenTriggered = default,
@@ -51,6 +52,7 @@ public RepeatedFailuresOverTimeCircuitBreaker(
{
this.name = name;
this.triggerAction = triggerAction;
+ this.logger = logger;
this.armedAction = armedAction ?? (static () => { });
this.disarmedAction = disarmedAction ?? (static () => { });
this.timeToWaitBeforeTriggering = timeToWaitBeforeTriggering;
@@ -82,14 +84,14 @@ public void Success()
circuitBreakerState = Disarmed;
_ = timer.Change(Timeout.Infinite, Timeout.Infinite);
- Logger.InfoFormat("The circuit breaker for '{0}' is now disarmed.", name);
+ logger.LogInformation("The circuit breaker for '{BreakerName}' is now disarmed", name);
try
{
disarmedAction();
}
catch (Exception ex)
{
- Logger.Error($"The circuit breaker for '{name}' was unable to execute the disarm action.", ex);
+ logger.LogError(ex, "The circuit breaker for '{BreakerName}' was unable to execute the disarm action", name);
throw;
}
}
@@ -130,12 +132,12 @@ public Task Failure(Exception exception, CancellationToken cancellationToken = d
}
catch (Exception ex)
{
- Logger.Error($"The circuit breaker for '{name}' was unable to execute the arm action.", new AggregateException(ex, exception));
+ logger.LogError(new AggregateException(ex, exception), "The circuit breaker for '{BreakerName}' was unable to execute the arm action", name);
throw;
}
_ = timer.Change(timeToWaitBeforeTriggering, NoPeriodicTriggering);
- Logger.WarnFormat("The circuit breaker for '{0}' is now in the armed state due to '{1}' and might trigger in '{2}' when not disarmed.", name, exception, timeToWaitBeforeTriggering);
+ logger.LogWarning("The circuit breaker for '{BreakerName}' is now in the armed state due to '{BreakerCause}' and might trigger in '{BreakerTriggerTime}' when not disarmed", name, exception, timeToWaitBeforeTriggering);
}
return Delay();
@@ -143,10 +145,7 @@ public Task Failure(Exception exception, CancellationToken cancellationToken = d
Task Delay()
{
var timeToWait = previousState == Triggered ? timeToWaitWhenTriggered : timeToWaitWhenArmed;
- if (Logger.IsDebugEnabled)
- {
- Logger.DebugFormat("The circuit breaker for '{0}' is delaying the operation by '{1}'.", name, timeToWait);
- }
+ logger.LogDebug("The circuit breaker for '{BreakerName}' is delaying the operation by '{BreakerTriggerTime}'", name, timeToWait);
return Task.Delay(timeToWait, cancellationToken);
}
}
@@ -173,7 +172,7 @@ void CircuitBreakerTriggered(object? state)
}
circuitBreakerState = Triggered;
- Logger.WarnFormat("The circuit breaker for '{0}' will now be triggered with exception '{1}'.", name, lastException);
+ logger.LogWarning("The circuit breaker for '{BreakerName}' will now be triggered with exception '{BreakerCause}'", name, lastException);
try
{
@@ -181,7 +180,7 @@ void CircuitBreakerTriggered(object? state)
}
catch (Exception ex)
{
- Logger.Fatal($"The circuit breaker for '{name}' was unable to execute the trigger action.", new AggregateException(ex, lastException!));
+ logger.LogCritical(new AggregateException(ex, lastException!), "The circuit breaker for '{BreakerName}' was unable to execute the trigger action", name);
}
}
}
@@ -204,5 +203,5 @@ void CircuitBreakerTriggered(object? state)
const int Triggered = 2;
static readonly TimeSpan NoPeriodicTriggering = TimeSpan.FromMilliseconds(-1);
- static readonly ILog Logger = LogManager.GetLogger();
+ readonly ILogger logger;
}
\ No newline at end of file
diff --git a/src/ServiceControl.Infrastructure/ServiceControl.Infrastructure.csproj b/src/ServiceControl.Infrastructure/ServiceControl.Infrastructure.csproj
index ea352f1711..225a545bd9 100644
--- a/src/ServiceControl.Infrastructure/ServiceControl.Infrastructure.csproj
+++ b/src/ServiceControl.Infrastructure/ServiceControl.Infrastructure.csproj
@@ -2,6 +2,8 @@
net8.0
+ true
+ ..\NServiceBus.snk
@@ -9,9 +11,13 @@
+
+
+
+
\ No newline at end of file
diff --git a/src/ServiceControl.Infrastructure/TestLogger/TestContextAppender.cs b/src/ServiceControl.Infrastructure/TestLogger/TestContextAppender.cs
new file mode 100644
index 0000000000..ed37368e16
--- /dev/null
+++ b/src/ServiceControl.Infrastructure/TestLogger/TestContextAppender.cs
@@ -0,0 +1,29 @@
+namespace ServiceControl.Infrastructure.TestLogger
+{
+ using System;
+ using Microsoft.Extensions.Logging;
+ using NUnit.Framework;
+
+ class TestContextAppender(string categoryName, LogLevel level) : ILogger
+ {
+ public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter)
+ {
+ if (IsEnabled(logLevel))
+ {
+ TestContext.Out.WriteLine($"{categoryName}: {formatter(state, exception)}");
+ }
+ }
+ public bool IsEnabled(LogLevel logLevel) => logLevel >= level;
+
+ public IDisposable BeginScope(TState state) where TState : notnull => Disposable.Instance;
+
+ class Disposable : IDisposable
+ {
+ public static Disposable Instance = new();
+
+ public void Dispose()
+ {
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ServiceControl.Infrastructure/TestLogger/TestContextAppenderFactory.cs b/src/ServiceControl.Infrastructure/TestLogger/TestContextAppenderFactory.cs
new file mode 100644
index 0000000000..3cac38fce7
--- /dev/null
+++ b/src/ServiceControl.Infrastructure/TestLogger/TestContextAppenderFactory.cs
@@ -0,0 +1,17 @@
+namespace ServiceControl.Infrastructure.TestLogger
+{
+ using Microsoft.Extensions.Logging;
+
+ public class TestContextAppenderFactory(LogLevel logLevel) : ILoggerFactory
+ {
+ public void AddProvider(ILoggerProvider provider)
+ {
+ }
+
+ public ILogger CreateLogger(string categoryName) => new TestContextAppender(categoryName, logLevel);
+
+ public void Dispose()
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ServiceControl.Infrastructure/TestLogger/TestContextProvider.cs b/src/ServiceControl.Infrastructure/TestLogger/TestContextProvider.cs
new file mode 100644
index 0000000000..90e2dae5d8
--- /dev/null
+++ b/src/ServiceControl.Infrastructure/TestLogger/TestContextProvider.cs
@@ -0,0 +1,21 @@
+namespace ServiceControl.Infrastructure.TestLogger
+{
+ using Microsoft.Extensions.Logging;
+
+ public class TestContextProvider : ILoggerProvider
+ {
+ readonly LogLevel level;
+
+ public TestContextProvider(LogLevel level)
+ {
+ this.level = level;
+ }
+
+ public ILogger CreateLogger(string categoryName) => new TestContextAppender(categoryName, level);
+
+ public void Dispose()
+ {
+
+ }
+ }
+}
diff --git a/src/ServiceControl.Infrastructure/Watchdog.cs b/src/ServiceControl.Infrastructure/Watchdog.cs
index 56d111cf78..443abe3b5d 100644
--- a/src/ServiceControl.Infrastructure/Watchdog.cs
+++ b/src/ServiceControl.Infrastructure/Watchdog.cs
@@ -3,7 +3,7 @@
using System;
using System.Threading;
using System.Threading.Tasks;
- using NServiceBus.Logging;
+ using Microsoft.Extensions.Logging;
public class Watchdog
{
@@ -14,7 +14,7 @@ public class Watchdog
Task watchdog;
CancellationTokenSource shutdownTokenSource = new();
TimeSpan timeToWaitBetweenStartupAttempts;
- ILog log;
+ ILogger log;
string taskName;
public Watchdog(
@@ -23,7 +23,7 @@ public Watchdog(
Func ensureStopped, Action reportFailure,
Action clearFailure,
TimeSpan timeToWaitBetweenStartupAttempts,
- ILog log
+ ILogger log
)
{
this.taskName = taskName;
@@ -45,7 +45,7 @@ public Task Start(Action onFailedOnStartup, CancellationToken cancellationToken)
{
watchdog = Task.Run(async () =>
{
- log.Debug($"Starting watching {taskName}");
+ log.LogDebug("Starting watching {TaskName}", taskName);
bool startup = true;
@@ -60,14 +60,14 @@ public Task Start(Action onFailedOnStartup, CancellationToken cancellationToken)
using var cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(shutdownTokenSource.Token);
cancellationTokenSource.CancelAfter(MaxStartDurationMs);
- log.Debug($"Ensuring {taskName} is running");
+ log.LogDebug("Ensuring {TaskName} is running", taskName);
await ensureStarted(cancellationTokenSource.Token).ConfigureAwait(false);
clearFailure();
startup = false;
}
catch (OperationCanceledException e) when (shutdownTokenSource.IsCancellationRequested)
{
- log.Debug("Cancelled", e);
+ log.LogDebug(e, "Cancelled");
return;
}
catch (Exception e)
@@ -76,12 +76,12 @@ public Task Start(Action onFailedOnStartup, CancellationToken cancellationToken)
if (startup)
{
- log.Error($"Error during initial startup attempt for {taskName}.", e);
+ log.LogError(e, "Error during initial startup attempt for {TaskName}", taskName);
onFailedOnStartup();
return;
}
- log.Error($"Error while trying to start {taskName}. Starting will be retried in {timeToWaitBetweenStartupAttempts}.", e);
+ log.LogError(e, "Error while trying to start {TaskName}. Starting will be retried in {TimeToWaitBetweenStartupAttempts}", taskName, timeToWaitBetweenStartupAttempts);
}
try
{
@@ -101,13 +101,13 @@ public async Task Stop(CancellationToken cancellationToken)
{
try
{
- log.Debug($"Stopping watching process {taskName}");
+ log.LogDebug("Starting watching {TaskName}", taskName);
await shutdownTokenSource.CancelAsync().ConfigureAwait(false);
await watchdog.ConfigureAwait(false);
}
catch (Exception e)
{
- log.Error($"Error while trying to stop {taskName}.", e);
+ log.LogError(e, "Ensuring {TaskName} is running", taskName);
throw;
}
finally
diff --git a/src/ServiceControl.Monitoring.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs b/src/ServiceControl.Monitoring.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs
index debc3ed629..00c545bd97 100644
--- a/src/ServiceControl.Monitoring.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs
+++ b/src/ServiceControl.Monitoring.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs
@@ -13,11 +13,12 @@ namespace ServiceControl.Monitoring.AcceptanceTests.TestSupport
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
+ using Microsoft.Extensions.Logging;
using Monitoring;
using NServiceBus;
using NServiceBus.AcceptanceTesting;
using NServiceBus.AcceptanceTesting.Support;
- using NServiceBus.Logging;
+ using ServiceControl.Infrastructure;
class ServiceControlComponentRunner(
ITransportIntegration transportToUse,
@@ -33,15 +34,16 @@ class ServiceControlComponentRunner(
async Task InitializeServiceControl(ScenarioContext context)
{
+ LoggerUtil.ActiveLoggers = Loggers.Test;
settings = new Settings(transportType: transportToUse.TypeName)
{
ConnectionString = transportToUse.ConnectionString,
HttpHostName = "localhost",
OnMessage = (id, headers, body, @continue) =>
{
- var log = LogManager.GetLogger();
+ var logger = LoggerUtil.CreateStaticLogger();
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)
@@ -60,7 +62,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 Task.CompletedTask;
}
@@ -91,12 +93,15 @@ async Task InitializeServiceControl(ScenarioContext context)
// Force the DI container to run the dependency resolution check to verify all dependencies can be resolved
EnvironmentName = Environments.Development
});
+ hostBuilder.Logging.ClearProviders();
+ hostBuilder.Logging.ConfigureLogging(LogLevel.Information);
+
hostBuilder.AddServiceControlMonitoring((criticalErrorContext, cancellationToken) =>
{
var logitem = new ScenarioContext.LogItem
{
Endpoint = settings.InstanceName,
- Level = LogLevel.Fatal,
+ Level = NServiceBus.Logging.LogLevel.Fatal,
LoggerName = $"{settings.InstanceName}.CriticalError",
Message = $"{criticalErrorContext.Error}{Environment.NewLine}{criticalErrorContext.Exception}"
};
diff --git a/src/ServiceControl.Monitoring.UnitTests/ApprovalFiles/SettingsTests.PlatformSampleSettings.approved.txt b/src/ServiceControl.Monitoring.UnitTests/ApprovalFiles/SettingsTests.PlatformSampleSettings.approved.txt
index 5d32f42fbb..070234384e 100644
--- a/src/ServiceControl.Monitoring.UnitTests/ApprovalFiles/SettingsTests.PlatformSampleSettings.approved.txt
+++ b/src/ServiceControl.Monitoring.UnitTests/ApprovalFiles/SettingsTests.PlatformSampleSettings.approved.txt
@@ -1,9 +1,6 @@
{
"LoggingSettings": {
- "LogLevel": {
- "Name": "Info",
- "Ordinal": 2
- },
+ "LogLevel": "Information",
"LogPath": "C:\\Logs"
},
"InstanceName": "Particular.Monitoring",
diff --git a/src/ServiceControl.Monitoring/App.config b/src/ServiceControl.Monitoring/App.config
index 8ce3bdf576..0a2fa4d478 100644
--- a/src/ServiceControl.Monitoring/App.config
+++ b/src/ServiceControl.Monitoring/App.config
@@ -19,6 +19,9 @@ These settings are only here so that we can debug ServiceControl while developin
+
+
+
diff --git a/src/ServiceControl.Monitoring/HostApplicationBuilderExtensions.cs b/src/ServiceControl.Monitoring/HostApplicationBuilderExtensions.cs
index 90adce523d..b55672e51d 100644
--- a/src/ServiceControl.Monitoring/HostApplicationBuilderExtensions.cs
+++ b/src/ServiceControl.Monitoring/HostApplicationBuilderExtensions.cs
@@ -15,13 +15,12 @@ namespace ServiceControl.Monitoring;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Hosting.WindowsServices;
-using Microsoft.Extensions.Logging;
-using NLog.Extensions.Logging;
using NServiceBus;
using NServiceBus.Configuration.AdvancedExtensibility;
using NServiceBus.Features;
using NServiceBus.Transport;
using QueueLength;
+using ServiceControl.Infrastructure;
using Timings;
using Transports;
@@ -31,9 +30,8 @@ public static void AddServiceControlMonitoring(this IHostApplicationBuilder host
Func onCriticalError, Settings settings,
EndpointConfiguration endpointConfiguration)
{
- hostBuilder.Logging.ClearProviders();
- hostBuilder.Logging.AddNLog();
- hostBuilder.Logging.SetMinimumLevel(settings.LoggingSettings.ToHostLogLevel());
+ hostBuilder.Services.AddLogging();
+ hostBuilder.Logging.ConfigureLogging(settings.LoggingSettings.LogLevel);
var services = hostBuilder.Services;
diff --git a/src/ServiceControl.Monitoring/Hosting/Commands/SetupCommand.cs b/src/ServiceControl.Monitoring/Hosting/Commands/SetupCommand.cs
index 3bd7830438..22a84b27f7 100644
--- a/src/ServiceControl.Monitoring/Hosting/Commands/SetupCommand.cs
+++ b/src/ServiceControl.Monitoring/Hosting/Commands/SetupCommand.cs
@@ -1,7 +1,8 @@
namespace ServiceControl.Monitoring
{
using System.Threading.Tasks;
- using NServiceBus.Logging;
+ using Microsoft.Extensions.Logging;
+ using ServiceControl.Infrastructure;
using Transports;
class SetupCommand : AbstractCommand
@@ -10,7 +11,7 @@ public override Task Execute(HostArguments args, Settings settings)
{
if (args.SkipQueueCreation)
{
- Logger.Info("Skipping queue creation");
+ LoggerUtil.CreateStaticLogger().LogInformation("Skipping queue creation");
return Task.CompletedTask;
}
@@ -19,7 +20,5 @@ public override Task Execute(HostArguments args, Settings settings)
var transportCustomization = TransportFactory.Create(transportSettings);
return transportCustomization.ProvisionQueues(transportSettings, []);
}
-
- static readonly ILog Logger = LogManager.GetLogger();
}
}
\ No newline at end of file
diff --git a/src/ServiceControl.Monitoring/Http/Diagrams/MonitoredEndpointMessageTypeParser.cs b/src/ServiceControl.Monitoring/Http/Diagrams/MonitoredEndpointMessageTypeParser.cs
index 3faa1e81c7..903013183a 100644
--- a/src/ServiceControl.Monitoring/Http/Diagrams/MonitoredEndpointMessageTypeParser.cs
+++ b/src/ServiceControl.Monitoring/Http/Diagrams/MonitoredEndpointMessageTypeParser.cs
@@ -3,7 +3,8 @@ namespace ServiceControl.Monitoring.Http.Diagrams
using System;
using System.Linq;
using System.Reflection;
- using NServiceBus.Logging;
+ using Microsoft.Extensions.Logging;
+ using ServiceControl.Infrastructure;
public static class MonitoredEndpointMessageTypeParser
{
@@ -40,7 +41,7 @@ public static MonitoredEndpointMessageType Parse(string typeName)
}
catch (Exception e)
{
- Logger.Warn($"Error parsing message type: {typeName}.", e);
+ LoggerUtil.CreateStaticLogger(typeof(MonitoredEndpointMessageTypeParser)).LogWarning(e, "Error parsing message type: {typeName}", typeName);
}
}
@@ -50,7 +51,5 @@ public static MonitoredEndpointMessageType Parse(string typeName)
TypeName = typeName
};
}
-
- static readonly ILog Logger = LogManager.GetLogger(typeof(MonitoredEndpointMessageTypeParser));
}
}
\ No newline at end of file
diff --git a/src/ServiceControl.Monitoring/Infrastructure/RemoveExpiredEndpointInstances.cs b/src/ServiceControl.Monitoring/Infrastructure/RemoveExpiredEndpointInstances.cs
index 991cf534e3..c563aa45b0 100644
--- a/src/ServiceControl.Monitoring/Infrastructure/RemoveExpiredEndpointInstances.cs
+++ b/src/ServiceControl.Monitoring/Infrastructure/RemoveExpiredEndpointInstances.cs
@@ -44,7 +44,7 @@ protected override async Task ExecuteAsync(CancellationToken cancellationToken)
catch (Exception ex) when (ex is not OperationCanceledException)
{
logger.LogError(ex,
- $"Error deleting expired endpoint instances, trying again in {IntervalInMinutes} minutes.");
+ $"Error deleting expired endpoint instances, trying again in {IntervalInMinutes} minutes");
}
} while (await timer.WaitForNextTickAsync(cancellationToken));
}
diff --git a/src/ServiceControl.Monitoring/Infrastructure/ReportThroughputHostedService.cs b/src/ServiceControl.Monitoring/Infrastructure/ReportThroughputHostedService.cs
index fb26a708c3..5789593d4e 100644
--- a/src/ServiceControl.Monitoring/Infrastructure/ReportThroughputHostedService.cs
+++ b/src/ServiceControl.Monitoring/Infrastructure/ReportThroughputHostedService.cs
@@ -37,7 +37,7 @@ protected override async Task ExecuteAsync(CancellationToken cancellationToken)
}
else
{
- logger.LogError(ex, $"Error obtaining throughput from Monitoring for {ReportSendingIntervalInMinutes} minutes interval.");
+ logger.LogError(ex, $"Error obtaining throughput from Monitoring for {ReportSendingIntervalInMinutes} minutes interval");
}
}
} while (await timer.WaitForNextTickAsync(cancellationToken));
diff --git a/src/ServiceControl.Monitoring/Licensing/ActiveLicense.cs b/src/ServiceControl.Monitoring/Licensing/ActiveLicense.cs
index a3a001e0ad..f5ca3be8bc 100644
--- a/src/ServiceControl.Monitoring/Licensing/ActiveLicense.cs
+++ b/src/ServiceControl.Monitoring/Licensing/ActiveLicense.cs
@@ -1,11 +1,15 @@
namespace ServiceControl.Monitoring.Licensing
{
- using global::ServiceControl.LicenseManagement;
- using NServiceBus.Logging;
+ using ServiceControl.LicenseManagement;
+ using Microsoft.Extensions.Logging;
public class ActiveLicense
{
- public ActiveLicense() => Refresh();
+ public ActiveLicense(ILogger logger)
+ {
+ this.logger = logger;
+ Refresh();
+ }
public bool IsValid { get; set; }
@@ -13,7 +17,7 @@ public class ActiveLicense
public void Refresh()
{
- Logger.Debug("Refreshing ActiveLicense");
+ logger.LogDebug("Refreshing ActiveLicense");
var detectedLicense = LicenseManager.FindLicense();
@@ -22,6 +26,6 @@ public void Refresh()
Details = detectedLicense.Details;
}
- static readonly ILog Logger = LogManager.GetLogger(typeof(ActiveLicense));
+ readonly ILogger logger;
}
}
\ No newline at end of file
diff --git a/src/ServiceControl.Monitoring/Licensing/LicenseCheckHostedService.cs b/src/ServiceControl.Monitoring/Licensing/LicenseCheckHostedService.cs
index a5b10f73b5..3bc9d0ec21 100644
--- a/src/ServiceControl.Monitoring/Licensing/LicenseCheckHostedService.cs
+++ b/src/ServiceControl.Monitoring/Licensing/LicenseCheckHostedService.cs
@@ -4,10 +4,10 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
- using NServiceBus.Logging;
+ using Microsoft.Extensions.Logging;
using ServiceControl.Infrastructure.BackgroundTasks;
- class LicenseCheckHostedService(ActiveLicense activeLicense, IAsyncTimer scheduler) : IHostedService
+ class LicenseCheckHostedService(ActiveLicense activeLicense, IAsyncTimer scheduler, ILogger logger) : IHostedService
{
public Task StartAsync(CancellationToken cancellationToken)
{
@@ -16,7 +16,7 @@ public Task StartAsync(CancellationToken cancellationToken)
{
activeLicense.Refresh();
return ScheduleNextExecutionTask;
- }, due, due, ex => Logger.Error("Unhandled error while refreshing the license.", ex));
+ }, due, due, ex => logger.LogError(ex, "Unhandled error while refreshing the license"));
return Task.CompletedTask;
}
@@ -24,7 +24,6 @@ public Task StartAsync(CancellationToken cancellationToken)
TimerJob timer;
- static readonly ILog Logger = LogManager.GetLogger();
static readonly Task ScheduleNextExecutionTask = Task.FromResult(TimerJobExecutionResult.ScheduleNextExecution);
}
}
\ No newline at end of file
diff --git a/src/ServiceControl.Monitoring/Program.cs b/src/ServiceControl.Monitoring/Program.cs
index 8620eba3cc..e8dce81512 100644
--- a/src/ServiceControl.Monitoring/Program.cs
+++ b/src/ServiceControl.Monitoring/Program.cs
@@ -1,13 +1,19 @@
using System;
using System.Reflection;
-using NServiceBus.Logging;
+using Microsoft.Extensions.Logging;
using ServiceControl.Configuration;
using ServiceControl.Infrastructure;
using ServiceControl.Monitoring;
+ILogger logger = null;
+
try
{
- AppDomain.CurrentDomain.UnhandledException += (s, e) => LogManager.GetLogger(typeof(Program)).Error("Unhandled exception was caught.", e.ExceptionObject as Exception);
+ var loggingSettings = new LoggingSettings(Settings.SettingsRootNamespace);
+ LoggingConfigurator.ConfigureLogging(loggingSettings);
+ logger = LoggerUtil.CreateStaticLogger(typeof(Program));
+
+ AppDomain.CurrentDomain.UnhandledException += (s, e) => logger.LogError(e.ExceptionObject as Exception, "Unhandled exception was caught");
// Hack: See https://github.com/Particular/ServiceControl/issues/4392
var exitCode = await IntegratedSetup.Run();
@@ -21,9 +27,6 @@
var arguments = new HostArguments(args);
- var loggingSettings = new LoggingSettings(Settings.SettingsRootNamespace);
- LoggingConfigurator.ConfigureLogging(loggingSettings);
-
var settings = new Settings(loggingSettings: loggingSettings);
await new CommandRunner(arguments.Command).Execute(arguments, settings);
@@ -32,12 +35,20 @@
}
catch (Exception ex)
{
- NLog.LogManager.GetCurrentClassLogger().Fatal(ex, "Unrecoverable error");
+ if (logger != null)
+ {
+ logger.LogCritical(ex, "Unrecoverable error");
+ }
+ else
+ {
+ LoggingConfigurator.ConfigureNLog("bootstrap.${shortdate}.txt", "./", NLog.LogLevel.Fatal);
+ NLog.LogManager.GetCurrentClassLogger().Fatal(ex, "Unrecoverable error");
+ }
throw;
}
finally
{
// The following log statement is meant to leave a trail in the logs to determine if the process was killed
- NLog.LogManager.GetCurrentClassLogger().Info("Shutdown complete");
- NLog.LogManager.Shutdown();
-}
\ No newline at end of file
+ logger?.LogInformation("Shutdown complete");
+ LoggerUtil.DisposeLoggerFactories();
+}
diff --git a/src/ServiceControl.Monitoring/QueueLength/LegacyQueueLengthReportHandler.cs b/src/ServiceControl.Monitoring/QueueLength/LegacyQueueLengthReportHandler.cs
index 82a72e4a8b..93d905558d 100644
--- a/src/ServiceControl.Monitoring/QueueLength/LegacyQueueLengthReportHandler.cs
+++ b/src/ServiceControl.Monitoring/QueueLength/LegacyQueueLengthReportHandler.cs
@@ -5,33 +5,24 @@
using System.Threading;
using System.Threading.Tasks;
using Infrastructure;
+ using Microsoft.Extensions.Logging;
using NServiceBus;
- using NServiceBus.Logging;
using NServiceBus.Metrics;
- class LegacyQueueLengthReportHandler : IHandleMessages
+ class LegacyQueueLengthReportHandler(LegacyQueueLengthReportHandler.LegacyQueueLengthEndpoints legacyEndpoints, ILogger logger) : IHandleMessages
{
- public LegacyQueueLengthReportHandler(LegacyQueueLengthEndpoints legacyEndpoints)
- {
- this.legacyEndpoints = legacyEndpoints;
- }
-
public Task Handle(MetricReport message, IMessageHandlerContext context)
{
var endpointInstanceId = EndpointInstanceId.From(context.MessageHeaders);
if (legacyEndpoints.TryAdd(endpointInstanceId.InstanceId))
{
- Logger.Warn($"Legacy queue length report received from {endpointInstanceId.InstanceName} instance of {endpointInstanceId.EndpointName}");
+ logger.LogWarning("Legacy queue length report received from {EndpointInstanceIdInstanceName} instance of {EndpointInstanceIdEndpointName}", endpointInstanceId.InstanceName, endpointInstanceId.EndpointName);
}
return Task.CompletedTask;
}
- LegacyQueueLengthEndpoints legacyEndpoints;
-
- static readonly ILog Logger = LogManager.GetLogger(typeof(LegacyQueueLengthReportHandler));
-
public class LegacyQueueLengthEndpoints
{
public bool TryAdd(string id)
diff --git a/src/ServiceControl.Monitoring/ServiceControl.Monitoring.csproj b/src/ServiceControl.Monitoring/ServiceControl.Monitoring.csproj
index 35246ea1b8..1a9b705469 100644
--- a/src/ServiceControl.Monitoring/ServiceControl.Monitoring.csproj
+++ b/src/ServiceControl.Monitoring/ServiceControl.Monitoring.csproj
@@ -24,7 +24,6 @@
-
diff --git a/src/ServiceControl.Persistence.RavenDB/CustomChecks/CheckDirtyMemory.cs b/src/ServiceControl.Persistence.RavenDB/CustomChecks/CheckDirtyMemory.cs
index 8eee53911a..2654acff11 100644
--- a/src/ServiceControl.Persistence.RavenDB/CustomChecks/CheckDirtyMemory.cs
+++ b/src/ServiceControl.Persistence.RavenDB/CustomChecks/CheckDirtyMemory.cs
@@ -3,26 +3,23 @@ namespace ServiceControl.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 Health", TimeSpan.FromMinutes(5))
+class CheckDirtyMemory(MemoryInformationRetriever memoryInformationRetriever, ILogger logger) : CustomCheck("RavenDB dirty memory", "ServiceControl Health", TimeSpan.FromMinutes(5))
{
public override async Task 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();
}
\ No newline at end of file
diff --git a/src/ServiceControl.Persistence.RavenDB/CustomChecks/CheckFreeDiskSpace.cs b/src/ServiceControl.Persistence.RavenDB/CustomChecks/CheckFreeDiskSpace.cs
index c90bce9807..cbfcfbcf8f 100644
--- a/src/ServiceControl.Persistence.RavenDB/CustomChecks/CheckFreeDiskSpace.cs
+++ b/src/ServiceControl.Persistence.RavenDB/CustomChecks/CheckFreeDiskSpace.cs
@@ -4,18 +4,16 @@
using System.IO;
using System.Threading;
using System.Threading.Tasks;
+ using Microsoft.Extensions.Logging;
using NServiceBus.CustomChecks;
- using NServiceBus.Logging;
+ using ServiceControl.Infrastructure;
using ServiceControl.Persistence.RavenDB;
- class CheckFreeDiskSpace(RavenPersisterSettings settings) : CustomCheck("ServiceControl database", "Storage space", TimeSpan.FromMinutes(5))
+ class CheckFreeDiskSpace(RavenPersisterSettings settings, ILogger logger) : CustomCheck("ServiceControl database", "Storage space", TimeSpan.FromMinutes(5))
{
public override Task PerformCheck(CancellationToken cancellationToken = default)
{
- if (Logger.IsDebugEnabled)
- {
- Logger.Debug($"Check ServiceControl data drive space remaining custom check starting. Threshold {percentageThreshold:P0}");
- }
+ logger.LogDebug("Check ServiceControl data drive space remaining custom check starting. Threshold {PercentageThreshold:P0}", percentageThreshold);
if (!settings.UseEmbeddedServer)
{
@@ -33,10 +31,7 @@ public override Task PerformCheck(CancellationToken cancellationTok
var percentRemaining = (decimal)dataDriveInfo.AvailableFreeSpace / dataDriveInfo.TotalSize;
- if (Logger.IsDebugEnabled)
- {
- Logger.Debug($"Free space: {availableFreeSpace:N0}B | Total: {totalSpace:N0}B | Percent remaining {percentRemaining:P1}");
- }
+ logger.LogDebug("Free space: {FreeSpaceTotalBytesFree:N0}B | Total: {FreeSpaceTotalBytesAvailable:N0}B | Remaining {PercentRemaining:P1}%", availableFreeSpace, totalSpace, percentRemaining);
return percentRemaining > percentageThreshold
? CheckResult.Pass
@@ -45,22 +40,19 @@ public override Task PerformCheck(CancellationToken cancellationTok
public static void Validate(RavenPersisterSettings settings)
{
+ var logger = LoggerUtil.CreateStaticLogger();
var threshold = settings.DataSpaceRemainingThreshold;
- string message;
-
if (threshold < 0)
{
- message = $"{RavenPersistenceConfiguration.DataSpaceRemainingThresholdKey} is invalid, minimum value is 0.";
- Logger.Fatal(message);
- throw new Exception(message);
+ logger.LogCritical("{RavenPersistenceConfigurationDataSpaceRemainingThresholdKey} is invalid, minimum value is 0", RavenPersistenceConfiguration.DataSpaceRemainingThresholdKey);
+ throw new Exception($"{RavenPersistenceConfiguration.DataSpaceRemainingThresholdKey} is invalid, minimum value is 0.");
}
if (threshold > 100)
{
- message = $"{RavenPersistenceConfiguration.DataSpaceRemainingThresholdKey} is invalid, maximum value is 100.";
- Logger.Fatal(message);
- throw new Exception(message);
+ logger.LogCritical("{RavenPersistenceConfigurationDataSpaceRemainingThresholdKey} is invalid, maximum value is 100", RavenPersistenceConfiguration.DataSpaceRemainingThresholdKey);
+ throw new Exception($"{RavenPersistenceConfiguration.DataSpaceRemainingThresholdKey} is invalid, maximum value is 100.");
}
}
@@ -68,6 +60,5 @@ public static void Validate(RavenPersisterSettings settings)
readonly decimal percentageThreshold = settings.DataSpaceRemainingThreshold / 100m;
public const int DataSpaceRemainingThresholdDefault = 20;
- static readonly ILog Logger = LogManager.GetLogger(typeof(CheckFreeDiskSpace));
}
}
\ No newline at end of file
diff --git a/src/ServiceControl.Persistence.RavenDB/CustomChecks/CheckMinimumStorageRequiredForIngestion.cs b/src/ServiceControl.Persistence.RavenDB/CustomChecks/CheckMinimumStorageRequiredForIngestion.cs
index 053a41cff7..dad26352d7 100644
--- a/src/ServiceControl.Persistence.RavenDB/CustomChecks/CheckMinimumStorageRequiredForIngestion.cs
+++ b/src/ServiceControl.Persistence.RavenDB/CustomChecks/CheckMinimumStorageRequiredForIngestion.cs
@@ -4,21 +4,19 @@
using System.IO;
using System.Threading;
using System.Threading.Tasks;
+ using Microsoft.Extensions.Logging;
using NServiceBus.CustomChecks;
- using NServiceBus.Logging;
+ using ServiceControl.Infrastructure;
using ServiceControl.Persistence;
using ServiceControl.Persistence.RavenDB;
- class CheckMinimumStorageRequiredForIngestion(MinimumRequiredStorageState stateHolder, RavenPersisterSettings settings) : CustomCheck("Message Ingestion Process", "ServiceControl Health", TimeSpan.FromSeconds(5))
+ class CheckMinimumStorageRequiredForIngestion(MinimumRequiredStorageState stateHolder, RavenPersisterSettings settings, ILogger logger) : CustomCheck("Message Ingestion Process", "ServiceControl Health", TimeSpan.FromSeconds(5))
{
public override Task PerformCheck(CancellationToken cancellationToken = default)
{
var percentageThreshold = settings.MinimumStorageLeftRequiredForIngestion / 100m;
- if (Logger.IsDebugEnabled)
- {
- Logger.Debug($"Check ServiceControl data drive space starting. Threshold {percentageThreshold:P0}");
- }
+ logger.LogDebug("Check ServiceControl data drive space starting. Threshold {PercentageThreshold:P0}", percentageThreshold);
// Should be checking UseEmbeddedServer but need to check DatabasePath instead for the ATT hack to work
if (string.IsNullOrEmpty(settings.DatabasePath))
@@ -35,10 +33,7 @@ public override Task PerformCheck(CancellationToken cancellationTok
var percentRemaining = (decimal)dataDriveInfo.AvailableFreeSpace / dataDriveInfo.TotalSize;
- if (Logger.IsDebugEnabled)
- {
- Logger.Debug($"Free space: {availableFreeSpace:N0}B | Total: {totalSpace:N0}B | Percent remaining {percentRemaining:P1}");
- }
+ logger.LogDebug("Free space: {FreeSpaceTotalBytesFree:N0}B | Total: {FreeSpaceTotalBytesAvailable:N0}B | Remaining {PercentRemaining:P1}%", availableFreeSpace, totalSpace, percentRemaining);
if (percentRemaining > percentageThreshold)
{
@@ -46,33 +41,36 @@ public override Task PerformCheck(CancellationToken cancellationTok
return SuccessResult;
}
- var message = $"Error message ingestion stopped! {percentRemaining:P0} disk space remaining on data drive '{dataDriveInfo.VolumeLabel} ({dataDriveInfo.RootDirectory})' on '{Environment.MachineName}'. This is less than {percentageThreshold}% - the minimal required space configured. The threshold can be set using the {RavenBootstrapper.MinimumStorageLeftRequiredForIngestionKey} configuration setting.";
- Logger.Warn(message);
+ logger.LogWarning("Error message ingestion stopped! {PercentRemaining:P0} disk space remaining on data drive '{DataDriveInfoVolumeLabel} ({DataDriveInfoRootDirectory})' on '{MachineName}'. This is less than {PercentageThreshold}% - the minimal required space configured. The threshold can be set using the {RavenBootstrapperMinimumStorageLeftRequiredForIngestionKey} configuration setting",
+ percentRemaining,
+ dataDriveInfo.VolumeLabel,
+ dataDriveInfo.RootDirectory,
+ Environment.MachineName,
+ percentageThreshold,
+ RavenBootstrapper.MinimumStorageLeftRequiredForIngestionKey);
stateHolder.CanIngestMore = false;
- return CheckResult.Failed(message);
+ return CheckResult.Failed($"Error message ingestion stopped! {percentRemaining:P0} disk space remaining on data drive '{dataDriveInfo.VolumeLabel} ({dataDriveInfo.RootDirectory})' on '{Environment.MachineName}'. This is less than {percentageThreshold}% - the minimal required space configured. The threshold can be set using the {RavenBootstrapper.MinimumStorageLeftRequiredForIngestionKey} configuration setting.");
}
public static void Validate(RavenPersisterSettings settings)
{
+ var logger = LoggerUtil.CreateStaticLogger();
var threshold = settings.MinimumStorageLeftRequiredForIngestion;
if (threshold < 0)
{
- var message = $"{RavenBootstrapper.MinimumStorageLeftRequiredForIngestionKey} is invalid, minimum value is 0.";
- Logger.Fatal(message);
- throw new Exception(message);
+ logger.LogCritical("{RavenBootstrapperMinimumStorageLeftRequiredForIngestionKey} is invalid, minimum value is 0", RavenBootstrapper.MinimumStorageLeftRequiredForIngestionKey);
+ throw new Exception($"{RavenBootstrapper.MinimumStorageLeftRequiredForIngestionKey} is invalid, minimum value is 0.");
}
if (threshold > 100)
{
- var message = $"{RavenBootstrapper.MinimumStorageLeftRequiredForIngestionKey} is invalid, maximum value is 100.";
- Logger.Fatal(message);
- throw new Exception(message);
+ logger.LogCritical("{RavenBootstrapperMinimumStorageLeftRequiredForIngestionKey} is invalid, maximum value is 100", RavenBootstrapper.MinimumStorageLeftRequiredForIngestionKey);
+ throw new Exception($"{RavenBootstrapper.MinimumStorageLeftRequiredForIngestionKey} is invalid, maximum value is 100.");
}
}
public const int MinimumStorageLeftRequiredForIngestionDefault = 5;
static readonly Task SuccessResult = Task.FromResult(CheckResult.Pass);
- static readonly ILog Logger = LogManager.GetLogger(typeof(CheckMinimumStorageRequiredForIngestion));
}
}
\ No newline at end of file
diff --git a/src/ServiceControl.Persistence.RavenDB/CustomChecks/CheckRavenDBIndexErrors.cs b/src/ServiceControl.Persistence.RavenDB/CustomChecks/CheckRavenDBIndexErrors.cs
index 5567aa7507..89ea567a80 100644
--- a/src/ServiceControl.Persistence.RavenDB/CustomChecks/CheckRavenDBIndexErrors.cs
+++ b/src/ServiceControl.Persistence.RavenDB/CustomChecks/CheckRavenDBIndexErrors.cs
@@ -5,12 +5,12 @@
using System.Text;
using System.Threading;
using System.Threading.Tasks;
+ using Microsoft.Extensions.Logging;
using NServiceBus.CustomChecks;
- using NServiceBus.Logging;
using Raven.Client.Documents.Operations.Indexes;
using ServiceControl.Persistence.RavenDB;
- class CheckRavenDBIndexErrors(IRavenDocumentStoreProvider documentStoreProvider) : CustomCheck("Error Database Index Errors", "ServiceControl Health", TimeSpan.FromMinutes(5))
+ class CheckRavenDBIndexErrors(IRavenDocumentStoreProvider documentStoreProvider, ILogger logger) : CustomCheck("Error Database Index Errors", "ServiceControl Health", TimeSpan.FromMinutes(5))
{
public override async Task PerformCheck(CancellationToken cancellationToken = default)
{
@@ -41,10 +41,8 @@ public override async Task PerformCheck(CancellationToken cancellat
text.AppendLine().AppendLine("See: https://docs.particular.net/search?q=servicecontrol+troubleshooting");
var message = text.ToString();
- Logger.Error(message);
+ logger.LogError(message);
return CheckResult.Failed(message);
}
-
- static readonly ILog Logger = LogManager.GetLogger();
}
}
diff --git a/src/ServiceControl.Persistence.RavenDB/CustomChecks/CheckRavenDBIndexLag.cs b/src/ServiceControl.Persistence.RavenDB/CustomChecks/CheckRavenDBIndexLag.cs
index 7084d78e34..57c191756b 100644
--- a/src/ServiceControl.Persistence.RavenDB/CustomChecks/CheckRavenDBIndexLag.cs
+++ b/src/ServiceControl.Persistence.RavenDB/CustomChecks/CheckRavenDBIndexLag.cs
@@ -5,13 +5,13 @@
using System.Text;
using System.Threading;
using System.Threading.Tasks;
+ using Microsoft.Extensions.Logging;
using NServiceBus.CustomChecks;
- using NServiceBus.Logging;
using Raven.Client.Documents.Operations;
using ServiceControl.Persistence.RavenDB;
using CustomCheck = NServiceBus.CustomChecks.CustomCheck;
- class CheckRavenDBIndexLag(IRavenDocumentStoreProvider documentStoreProvider) : CustomCheck("Error Database Index Lag", "ServiceControl Health", TimeSpan.FromMinutes(5))
+ class CheckRavenDBIndexLag(IRavenDocumentStoreProvider documentStoreProvider, ILogger logger) : CustomCheck("Error Database Index Lag", "ServiceControl Health", TimeSpan.FromMinutes(5))
{
public override async Task PerformCheck(CancellationToken cancellationToken = default)
{
@@ -31,7 +31,7 @@ public override async Task PerformCheck(CancellationToken cancellat
return CheckResult.Pass;
}
- static int CheckAndReportIndexesWithTooMuchIndexLag(IndexInformation[] indexes)
+ int CheckAndReportIndexesWithTooMuchIndexLag(IndexInformation[] indexes)
{
int indexCountWithTooMuchLag = 0;
@@ -44,12 +44,12 @@ static int CheckAndReportIndexesWithTooMuchIndexLag(IndexInformation[] indexes)
if (indexLag > IndexLagThresholdError)
{
indexCountWithTooMuchLag++;
- Log.Error($"Index [{indexStats.Name}] IndexingLag {indexLag} is above error threshold ({IndexLagThresholdError}). Launch in maintenance mode to let indexes catch up.");
+ logger.LogError("Index [{IndexName}] IndexingLag {IndexLag} is above error threshold ({IndexLagThresholdError}). Launch in maintenance mode to let indexes catch up", indexStats.Name, indexLag, IndexLagThresholdError);
}
else if (indexLag > IndexLagThresholdWarning)
{
indexCountWithTooMuchLag++;
- Log.Warn($"Index [{indexStats.Name}] IndexingLag {indexLag} is above warning threshold ({IndexLagThresholdWarning}). Launch in maintenance mode to let indexes catch up.");
+ logger.LogWarning("Index [{IndexName}] IndexingLag {IndexLag} is above warning threshold ({IndexLagThresholdWarning}). Launch in maintenance mode to let indexes catch up", indexStats.Name, indexLag, IndexLagThresholdWarning);
}
}
}
@@ -57,9 +57,9 @@ static int CheckAndReportIndexesWithTooMuchIndexLag(IndexInformation[] indexes)
return indexCountWithTooMuchLag;
}
- static void CreateDiagnosticsLogEntry(DatabaseStatistics statistics, IndexInformation[] indexes)
+ void CreateDiagnosticsLogEntry(DatabaseStatistics statistics, IndexInformation[] indexes)
{
- if (!Log.IsDebugEnabled)
+ if (!logger.IsEnabled(LogLevel.Debug))
{
return;
}
@@ -73,11 +73,10 @@ static void CreateDiagnosticsLogEntry(DatabaseStatistics statistics, IndexInform
{
report.AppendLine($"- Index [{indexStats.Name,-44}] State: {indexStats.State}, Stale: {indexStats.IsStale,-5}, Priority: {indexStats.Priority,-6}, LastIndexingTime: {indexStats.LastIndexingTime:u}");
}
- Log.Debug(report.ToString());
+ logger.LogDebug(report.ToString());
}
static readonly TimeSpan IndexLagThresholdWarning = TimeSpan.FromMinutes(1);
static readonly TimeSpan IndexLagThresholdError = TimeSpan.FromMinutes(10);
- static readonly ILog Log = LogManager.GetLogger();
}
}
\ No newline at end of file
diff --git a/src/ServiceControl.Persistence.RavenDB/ErrorMessagesDataStore.cs b/src/ServiceControl.Persistence.RavenDB/ErrorMessagesDataStore.cs
index 4c3f77bf6d..4940807646 100644
--- a/src/ServiceControl.Persistence.RavenDB/ErrorMessagesDataStore.cs
+++ b/src/ServiceControl.Persistence.RavenDB/ErrorMessagesDataStore.cs
@@ -6,7 +6,7 @@
using System.Linq;
using System.Threading.Tasks;
using Editing;
- using NServiceBus.Logging;
+ using Microsoft.Extensions.Logging;
using Raven.Client;
using Raven.Client.Documents;
using Raven.Client.Documents.Commands;
@@ -28,7 +28,8 @@ class ErrorMessagesDataStore(
IRavenSessionProvider sessionProvider,
IRavenDocumentStoreProvider documentStoreProvider,
IBodyStorage bodyStorage,
- ExpirationManager expirationManager)
+ ExpirationManager expirationManager,
+ ILogger logger)
: IErrorMessageDataStore
{
public async Task>> GetAllMessages(
@@ -338,7 +339,7 @@ public async Task ErrorLastBy(string failedMessageId)
return result;
}
- static FailedMessageView Map(FailedMessage message, IAsyncDocumentSession session)
+ FailedMessageView Map(FailedMessage message, IAsyncDocumentSession session)
{
var processingAttempt = message.ProcessingAttempts.Last();
@@ -369,7 +370,7 @@ static FailedMessageView Map(FailedMessage message, IAsyncDocumentSession sessio
}
catch (Exception ex)
{
- Logger.Warn($"Unable to parse SendingEndpoint from metadata for messageId {message.UniqueMessageId}", ex);
+ logger.LogWarning(ex, "Unable to parse SendingEndpoint from metadata for messageId {UniqueMessageId}", message.UniqueMessageId);
failedMsgView.SendingEndpoint = EndpointDetailsParser.SendingEndpoint(processingAttempt.Headers);
}
@@ -379,7 +380,7 @@ static FailedMessageView Map(FailedMessage message, IAsyncDocumentSession sessio
}
catch (Exception ex)
{
- Logger.Warn($"Unable to parse ReceivingEndpoint from metadata for messageId {message.UniqueMessageId}", ex);
+ logger.LogWarning(ex, "Unable to parse ReceivingEndpoint from metadata for messageId {UniqueMessageId}", message.UniqueMessageId);
failedMsgView.ReceivingEndpoint = EndpointDetailsParser.ReceivingEndpoint(processingAttempt.Headers);
}
@@ -676,7 +677,5 @@ public async Task StoreFailedMessagesForTestsOnly(params FailedMessage[] failedM
await session.SaveChangesAsync();
}
-
- static readonly ILog Logger = LogManager.GetLogger();
}
}
diff --git a/src/ServiceControl.Persistence.RavenDB/ExternalIntegrationRequestsDataStore.cs b/src/ServiceControl.Persistence.RavenDB/ExternalIntegrationRequestsDataStore.cs
index 27762fc546..7b339732ad 100644
--- a/src/ServiceControl.Persistence.RavenDB/ExternalIntegrationRequestsDataStore.cs
+++ b/src/ServiceControl.Persistence.RavenDB/ExternalIntegrationRequestsDataStore.cs
@@ -8,8 +8,8 @@
using System.Threading.Tasks;
using ExternalIntegrations;
using Microsoft.Extensions.Hosting;
+ using Microsoft.Extensions.Logging;
using NServiceBus;
- using NServiceBus.Logging;
using Raven.Client.Documents;
using Raven.Client.Documents.Changes;
using ServiceControl.Infrastructure;
@@ -20,12 +20,17 @@ class ExternalIntegrationRequestsDataStore
, IAsyncDisposable
{
- public ExternalIntegrationRequestsDataStore(RavenPersisterSettings settings, IRavenSessionProvider sessionProvider, IRavenDocumentStoreProvider documentStoreProvider, CriticalError criticalError)
+ public ExternalIntegrationRequestsDataStore(
+ RavenPersisterSettings settings,
+ IRavenSessionProvider sessionProvider,
+ IRavenDocumentStoreProvider documentStoreProvider,
+ CriticalError criticalError,
+ ILogger logger)
{
this.settings = settings;
this.sessionProvider = sessionProvider;
this.documentStoreProvider = documentStoreProvider;
-
+ this.logger = logger;
var timeToWait = TimeSpan.FromMinutes(5);
var delayAfterFailure = TimeSpan.FromSeconds(20);
@@ -33,6 +38,7 @@ public ExternalIntegrationRequestsDataStore(RavenPersisterSettings settings, IRa
"EventDispatcher",
timeToWait,
ex => criticalError.Raise("Repeated failures when dispatching external integration events.", ex),
+ logger,
timeToWaitWhenArmed: delayAfterFailure
);
}
@@ -97,7 +103,7 @@ async Task StartDispatcherTask(CancellationToken cancellationToken)
}
catch (Exception ex)
{
- Logger.Error("An exception occurred when dispatching external integration events", ex);
+ logger.LogError(ex, "An exception occurred when dispatching external integration events");
await circuitBreaker.Failure(ex, cancellationToken);
if (!tokenSource.IsCancellationRequested)
@@ -143,10 +149,7 @@ async Task TryDispatchEventBatch()
}
var allContexts = awaitingDispatching.Select(r => r.DispatchContext).ToArray();
- if (Logger.IsDebugEnabled)
- {
- Logger.Debug($"Dispatching {allContexts.Length} events.");
- }
+ logger.LogDebug("Dispatching {EventCount} events", allContexts.Length);
await callback(allContexts);
@@ -206,6 +209,6 @@ public async ValueTask DisposeAsync()
Func