Skip to content

Commit

Permalink
Merge pull request #2594 from Particular/legacy-queue-length-exception
Browse files Browse the repository at this point in the history
Prevent exception with legacy queue length reporting
  • Loading branch information
mikeminutillo authored Jul 15, 2021
2 parents 747bf6c + 2cab747 commit b2efd3e
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

<PropertyGroup>
<TargetFramework>net472</TargetFramework>
<LangVersion>8</LangVersion>
</PropertyGroup>

<!-- Workaround. See: https://github.com/NuGet/Home/issues/4989 -->
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
namespace ServiceControl.Monitoring.AcceptanceTests.TestSupport
{
using System;
using System.Collections.Concurrent;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Logging;
using NServiceBus.AcceptanceTesting;

static class ContextLoggerExtensions
{
public static ILoggingBuilder AddScenarioContextLogging(this ILoggingBuilder builder)
{
builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<ILoggerProvider, ContextLoggerProvider>());
return builder;
}

class ContextLoggerProvider : ILoggerProvider
{
ConcurrentDictionary<string, ILogger> loggers = new ConcurrentDictionary<string, ILogger>();
ScenarioContext context;

public ContextLoggerProvider(ScenarioContext context)
{
this.context = context;
}

public void Dispose() => loggers.Clear();

public ILogger CreateLogger(string categoryName) =>
loggers.GetOrAdd(categoryName, name => new ContextLogger(name, context));
}

class ContextLogger : ILogger
{
string categoryName;
ScenarioContext context;

public ContextLogger(string categoryName, ScenarioContext context)
{
this.categoryName = categoryName;
this.context = context;
}

public void Log<TState>(LogLevel logLevel, EventId eventId, TState state,
Exception exception, Func<TState, Exception, string> formatter) =>
context.Logs.Enqueue(new ScenarioContext.LogItem
{
LoggerName = categoryName,
Message = formatter(state, exception),
Level = ConvertLogLevel(logLevel)
});

NServiceBus.Logging.LogLevel ConvertLogLevel(LogLevel level)
=> level switch
{
LogLevel.Critical => NServiceBus.Logging.LogLevel.Fatal,
LogLevel.Trace => NServiceBus.Logging.LogLevel.Debug,
LogLevel.Debug => NServiceBus.Logging.LogLevel.Debug,
LogLevel.Information => NServiceBus.Logging.LogLevel.Info,
LogLevel.Warning => NServiceBus.Logging.LogLevel.Warn,
LogLevel.Error => NServiceBus.Logging.LogLevel.Error,
LogLevel.None => NServiceBus.Logging.LogLevel.Debug,
_ => throw new ArgumentOutOfRangeException(nameof(level), level, null)
};

public bool IsEnabled(LogLevel logLevel) =>
ConvertLogLevel(logLevel) <= context.LogLevel;

public IDisposable BeginScope<TState>(TState state) => NullScope.Instance;

class NullScope : IDisposable
{
public void Dispose() { }

public static NullScope Instance { get; } = new NullScope();
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@ async Task InitializeServiceControl(ScenarioContext context)
ctx.Stop().GetAwaiter().GetResult();
}, settings, configuration);

bootstrapper.HostBuilder.ConfigureLogging(logging => logging.AddScenarioContextLogging());

host = bootstrapper.HostBuilder.Build();
await host.StartAsync();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
namespace ServiceControl.Monitoring.AcceptanceTests.Tests
{
using System.Linq;
using System.Threading.Tasks;
using Infrastructure;
using NServiceBus;
using NServiceBus.AcceptanceTesting;
using NServiceBus.Metrics;
using NUnit.Framework;
using TestSupport.EndpointTemplates;

class When_sending_legacy_metric_report : AcceptanceTest
{
[Test]
public async Task Should_report_legacy_queue_length_reporting()
{
await Define<SomeContext>()
.WithEndpoint<EndpointSendingLegacyMetricReport>(b =>
b.When(session =>
{
var sendOptions = new SendOptions();
sendOptions.SetDestination(Settings.DEFAULT_ENDPOINT_NAME);
sendOptions.SetHeader(MetricHeaders.MetricInstanceId, "MetricInstanceId");
return session.Send(new MetricReport(), sendOptions);
}))
.Done(ctx => ctx.Logs.Any(x => x.Message == "Legacy queue length report received from MetricInstanceId instance of SendingLegacyMetricReport.EndpointSendingLegacyMetricReport"))
.Run();
}

class EndpointSendingLegacyMetricReport : EndpointConfigurationBuilder
{
public EndpointSendingLegacyMetricReport()
{
EndpointSetup<DefaultServer>();
}
}

class SomeContext : ScenarioContext
{

}
}
}
1 change: 1 addition & 0 deletions src/ServiceControl.Monitoring/Bootstrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ void CreateHost()
services.AddSingleton<MessageTypeRegistry>();
services.AddSingleton<EndpointInstanceActivityTracker>();
services.AddSingleton(sp => buildQueueLengthProvider(sp.GetRequiredService<QueueLengthStore>()));
services.AddSingleton<LegacyQueueLengthReportHandler.LegacyQueueLengthEndpoints>();
})
.UseNServiceBus(builder =>
{
Expand Down

0 comments on commit b2efd3e

Please sign in to comment.