Skip to content

Commit dd54670

Browse files
committed
High performance logging
Signed-off-by: Tomasz Maruszak <maruszaktomasz@gmail.com>
1 parent b3ce724 commit dd54670

File tree

34 files changed

+963
-164
lines changed

34 files changed

+963
-164
lines changed

src/Host.Plugin.Properties.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<Import Project="Common.NuGet.Properties.xml" />
55

66
<PropertyGroup>
7-
<Version>3.0.0-rc903</Version>
7+
<Version>3.0.0-rc904</Version>
88
</PropertyGroup>
99

1010
</Project>

src/SlimMessageBus.Host.AspNetCore/HttpContextAccessorCurrentMessageBusProvider.cs

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,46 @@
33
/// <summary>
44
/// Resolves the <see cref="IMessageBus"/> from the current ASP.NET Core web request (if present, otherwise falls back to the application root container).
55
/// </summary>
6-
public class HttpContextAccessorCurrentMessageBusProvider(
6+
public partial class HttpContextAccessorCurrentMessageBusProvider(
77
ILogger<HttpContextAccessorCurrentMessageBusProvider> logger,
88
IHttpContextAccessor httpContextAccessor,
99
IServiceProvider serviceProvider)
1010
: CurrentMessageBusProvider(serviceProvider)
1111
{
12+
private readonly ILogger<HttpContextAccessorCurrentMessageBusProvider> _logger = logger;
13+
1214
public override IMessageBus GetCurrent()
1315
{
1416
// When the call to resolve the given type is made within an HTTP Request, use the request scope service provider
1517
var httpContext = httpContextAccessor?.HttpContext;
1618
if (httpContext != null)
1719
{
18-
logger.LogTrace("The type IMessageBus will be requested from the per-request scope");
20+
LogCurrentFrom("request");
1921
return httpContext.RequestServices.GetService<IMessageBus>();
2022
}
2123

2224
// otherwise use the app wide scope provider
23-
logger.LogTrace("The type IMessageBus will be requested from the app scope");
25+
LogCurrentFrom("root");
2426
return base.GetCurrent();
2527
}
28+
29+
#region Logging
30+
31+
[LoggerMessage(
32+
EventId = 0,
33+
Level = LogLevel.Trace,
34+
Message = "The type IMessageBus will be requested from the {ScopeName} scope")]
35+
private partial void LogCurrentFrom(string scopeName);
36+
37+
#endregion
2638
}
39+
40+
#if NETSTANDARD2_0
41+
42+
public partial class HttpContextAccessorCurrentMessageBusProvider
43+
{
44+
private partial void LogCurrentFrom(string scopeName)
45+
=> _logger.LogTrace("The type IMessageBus will be requested from the {ScopeName} scope", scopeName);
46+
}
47+
48+
#endif

src/SlimMessageBus.Host.CircuitBreaker/Implementation/CircuitBreakerAbstractConsumerInterceptor.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
/// <summary>
44
/// Circuit breaker to toggle consumer status on an external events.
55
/// </summary>
6-
internal sealed class CircuitBreakerAbstractConsumerInterceptor : IAbstractConsumerInterceptor
6+
internal sealed class CircuitBreakerAbstractConsumerInterceptor(ILogger logger) : IAbstractConsumerInterceptor
77
{
88
public int Order => 100;
99

@@ -33,12 +33,12 @@ async Task BreakerChanged(Circuit state)
3333
var bus = consumer.Settings[0].MessageBusSettings.Name ?? "default";
3434
if (shouldPause)
3535
{
36-
consumer.Logger.LogWarning("Circuit breaker tripped for '{Path}' on '{Bus}' bus. Consumer paused.", path, bus);
36+
logger.LogWarning("Circuit breaker tripped for '{Path}' on '{Bus}' bus. Consumer paused.", path, bus);
3737
await consumer.DoStop().ConfigureAwait(false);
3838
}
3939
else
4040
{
41-
consumer.Logger.LogInformation("Circuit breaker restored for '{Path}' on '{Bus}' bus. Consumer resumed.", path, bus);
41+
logger.LogInformation("Circuit breaker restored for '{Path}' on '{Bus}' bus. Consumer resumed.", path, bus);
4242
await consumer.DoStart().ConfigureAwait(false);
4343
}
4444
consumer.SetIsPaused(shouldPause);

src/SlimMessageBus.Host.Configuration/SlimMessageBus.Host.Configuration.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<Description>Core configuration interfaces of SlimMessageBus</Description>
77
<PackageTags>SlimMessageBus</PackageTags>
88
<RootNamespace>SlimMessageBus.Host</RootNamespace>
9-
<Version>3.0.0-rc903</Version>
9+
<Version>3.0.0-rc904</Version>
1010
</PropertyGroup>
1111

1212
<ItemGroup>

src/SlimMessageBus.Host.Interceptor/SlimMessageBus.Host.Interceptor.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<Import Project="../Common.NuGet.Properties.xml" />
44

55
<PropertyGroup>
6-
<Version>3.0.0-rc903</Version>
6+
<Version>3.0.0-rc904</Version>
77
<Description>Core interceptor interfaces of SlimMessageBus</Description>
88
<PackageTags>SlimMessageBus</PackageTags>
99
</PropertyGroup>

src/SlimMessageBus.Host.Memory/Consumers/AbstractMessageProcessorQueue.cs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
namespace SlimMessageBus.Host.Memory;
22

3-
public abstract class AbstractMessageProcessorQueue(IMessageProcessor<object> messageProcessor, ILogger logger) : IMessageProcessorQueue
3+
public abstract partial class AbstractMessageProcessorQueue(IMessageProcessor<object> messageProcessor, ILogger logger) : IMessageProcessorQueue
44
{
5+
private readonly ILogger _logger = logger;
6+
57
public abstract void Enqueue(object transportMessage, IReadOnlyDictionary<string, object> messageHeaders);
68

79
protected async Task ProcessMessage(object transportMessage, IReadOnlyDictionary<string, object> messageHeaders, CancellationToken cancellationToken)
@@ -23,7 +25,27 @@ protected async Task ProcessMessage(object transportMessage, IReadOnlyDictionary
2325
if (r.Exception != null)
2426
{
2527
// We rely on the IMessageProcessor to execute the ConsumerErrorHandler<T>, but if it's not registered in the DI, it fails, or there is another fatal error then the message will be lost.
26-
logger.LogError(r.Exception, "Error processing message {Message} of type {MessageType}", transportMessage, transportMessage.GetType());
28+
LogMessageError(transportMessage, transportMessage.GetType(), r.Exception);
2729
}
2830
}
31+
32+
#region Logging
33+
34+
[LoggerMessage(
35+
EventId = 0,
36+
Level = LogLevel.Error,
37+
Message = "Error processing message {TransportMessage} of type {TransportMessageType}")]
38+
private partial void LogMessageError(object transportMessage, Type transportMessageType, Exception e);
39+
40+
#endregion
2941
}
42+
43+
#if NETSTANDARD2_0
44+
45+
public abstract partial class AbstractMessageProcessorQueue
46+
{
47+
private partial void LogMessageError(object transportMessage, Type transportMessageType, Exception e)
48+
=> _logger.LogError(e, "Error processing message {TransportMessage} of type {TransportMessageType}", transportMessage, transportMessageType);
49+
}
50+
51+
#endif

src/SlimMessageBus.Host.Memory/MemoryMessageBus.cs

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
/// <summary>
66
/// In-memory message bus <see cref="IMessageBus"/> implementation to use for in process message passing.
77
/// </summary>
8-
public class MemoryMessageBus : MessageBusBase<MemoryMessageBusSettings>
8+
public partial class MemoryMessageBus : MessageBusBase<MemoryMessageBusSettings>
99
{
1010
private readonly ILogger _logger;
1111
private IDictionary<string, IMessageProcessor<object>> _messageProcessorByPath;
@@ -63,11 +63,8 @@ public override IDictionary<string, object> CreateHeaders()
6363

6464
public override bool IsMessageScopeEnabled(ConsumerSettings consumerSettings, IDictionary<string, object> consumerContextProperties)
6565
{
66-
#if NETSTANDARD2_0
6766
if (consumerSettings is null) throw new ArgumentNullException(nameof(consumerSettings));
68-
#else
69-
ArgumentNullException.ThrowIfNull(consumerSettings);
70-
#endif
67+
7168
if (consumerContextProperties != null && consumerContextProperties.ContainsKey(MemoryMessageBusProperties.CreateScope))
7269
{
7370
return true;
@@ -133,7 +130,7 @@ private async Task<TResponseMessage> ProduceInternal<TResponseMessage>(object me
133130
path ??= GetDefaultPath(producerSettings.MessageType, producerSettings);
134131
if (!_messageProcessorByPath.TryGetValue(path, out var messageProcessor))
135132
{
136-
_logger.LogDebug("No consumers interested in message type {MessageType} on path {Path}", messageType, path);
133+
LogNoConsumerInterestedInMessageType(path, messageType);
137134
return default;
138135
}
139136

@@ -165,4 +162,24 @@ private async Task<TResponseMessage> ProduceInternal<TResponseMessage>(object me
165162
}
166163
return (TResponseMessage)r.Response;
167164
}
165+
166+
#region Logging
167+
168+
[LoggerMessage(
169+
EventId = 0,
170+
Level = LogLevel.Debug,
171+
Message = "No consumers interested in message type {MessageType} on path {Path}")]
172+
private partial void LogNoConsumerInterestedInMessageType(string path, Type messageType);
173+
174+
#endregion
168175
}
176+
177+
#if NETSTANDARD2_0
178+
179+
public partial class MemoryMessageBus
180+
{
181+
private partial void LogNoConsumerInterestedInMessageType(string path, Type messageType)
182+
=> _logger.LogDebug("No consumers interested in message type {MessageType} on path {Path}", messageType, path);
183+
}
184+
185+
#endif

src/SlimMessageBus.Host.Serialization/SlimMessageBus.Host.Serialization.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<Import Project="../Common.NuGet.Properties.xml" />
44

55
<PropertyGroup>
6-
<Version>3.0.0-rc903</Version>
6+
<Version>3.0.0-rc904</Version>
77
<Description>Core serialization interfaces of SlimMessageBus</Description>
88
<PackageTags>SlimMessageBus</PackageTags>
99
</PropertyGroup>

src/SlimMessageBus.Host/Collections/KindMapping.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
public class KindMapping
44
{
5-
private readonly Dictionary<string, PathKind> _kindByTopic = new();
6-
private readonly Dictionary<Type, PathKind> _kindByMessageType = new();
5+
private readonly Dictionary<string, PathKind> _kindByTopic = [];
6+
private readonly Dictionary<Type, PathKind> _kindByMessageType = [];
77

88
public void Configure(MessageBusSettings settings)
99
{

src/SlimMessageBus.Host/Collections/ProducerByMessageTypeCache.cs

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
/// The message type hierarchy is discovered at runtime and cached for faster access.
66
/// </summary>
77
/// <typeparam name="TProducer">The producer type</typeparam>
8-
public class ProducerByMessageTypeCache<TProducer> : IReadOnlyCache<Type, TProducer>
8+
public partial class ProducerByMessageTypeCache<TProducer> : IReadOnlyCache<Type, TProducer>
99
where TProducer : class
1010
{
1111
private readonly ILogger _logger;
@@ -37,7 +37,7 @@ private TProducer CalculateProducer(Type messageType)
3737
var assignableProducer = assignableProducers.FirstOrDefault();
3838
if (assignableProducer.Key != null)
3939
{
40-
_logger.LogDebug("Matched producer for message type {ProducerMessageType} for dispatched message type {MessageType}", assignableProducer.Key, messageType);
40+
LogMatchedProducerForMessageType(messageType, assignableProducer.Key);
4141
return assignableProducer.Value;
4242
}
4343

@@ -52,7 +52,7 @@ private TProducer CalculateProducer(Type messageType)
5252
}
5353
}
5454

55-
_logger.LogDebug("Unable to match any declared producer for dispatched message type {MessageType}", messageType);
55+
LogUnmatchedProducerForMessageType(messageType);
5656

5757
// Note: Nulls are also added to dictionary, so that we don't look them up using reflection next time (cached).
5858
return null;
@@ -74,4 +74,33 @@ private static int CalculateBaseClassDistance(Type type, Type baseType)
7474

7575
return distance;
7676
}
77-
}
77+
78+
#region Logging
79+
80+
[LoggerMessage(
81+
EventId = 0,
82+
Level = LogLevel.Debug,
83+
Message = "Matched producer for message type {ProducerMessageType} for dispatched message type {MessageType}")]
84+
private partial void LogMatchedProducerForMessageType(Type messageType, Type producerMessageType);
85+
86+
[LoggerMessage(
87+
EventId = 1,
88+
Level = LogLevel.Debug,
89+
Message = "Unable to match any declared producer for dispatched message type {MessageType}")]
90+
private partial void LogUnmatchedProducerForMessageType(Type messageType);
91+
92+
#endregion
93+
}
94+
95+
#if NETSTANDARD2_0
96+
97+
public partial class ProducerByMessageTypeCache<TProducer>
98+
{
99+
private partial void LogMatchedProducerForMessageType(Type messageType, Type producerMessageType)
100+
=> _logger.LogDebug("Matched producer for message type {ProducerMessageType} for dispatched message type {MessageType}", producerMessageType, messageType);
101+
102+
private partial void LogUnmatchedProducerForMessageType(Type messageType)
103+
=> _logger.LogDebug("Unable to match any declared producer for dispatched message type {MessageType}", messageType);
104+
}
105+
106+
#endif

0 commit comments

Comments
 (0)