diff --git a/README.md b/README.md
index 6e639a89..1c9a6fb8 100644
--- a/README.md
+++ b/README.md
@@ -636,3 +636,42 @@ To set up the `Microsoft.Extensions.Logging` log filtering, you will need to edi
```
[Back to top](#akkahosting)
+
+
+## Filtering Logs In Akka.NET
+
+In Akka.NET 1.5.21, we introduced [log filtering for log messages based on the LogSource or the content of a log message](https://getakka.net/articles/utilities/logging.html#filtering-log-messages). Depending on your coding style, you can use this feature in Akka.Hosting in several ways.
+
+1. Using The `LoggerConfigBuilder.WithLogFilter()` method.
+
+ The `LoggerConfigBuilder.WithLogFilter()` method lets you set up the `LogFilterBuilder`
+
+ ```csharp
+ builder.Services.AddAkka("MyActorSystem", configurationBuilder =>
+ {
+ configurationBuilder
+ .ConfigureLoggers(loggerConfigBuilder =>
+ {
+ loggerConfigBuilder.WithLogFilter(filterBuilder =>
+ {
+ filterBuilder.ExcludeMessageContaining("Test");
+ });
+ });
+ });
+ ```
+
+2. Setting the `loggerConfigBuilder.LogFilterBuilder` property directly.
+
+ ```csharp
+ builder.Services.AddAkka("MyActorSystem", configurationBuilder =>
+ {
+ configurationBuilder
+ .ConfigureLoggers(loggerConfigBuilder =>
+ {
+ loggerConfigBuilder.LogFilterBuilder = new LogFilterBuilder();
+ loggerConfigBuilder.LogFilterBuilder.ExcludeMessageContaining("Test");
+ });
+ });
+ ```
+
+[Back to top](#akkahosting)
diff --git a/src/Akka.Hosting.API.Tests/verify/CoreApiSpec.ApproveCore.verified.txt b/src/Akka.Hosting.API.Tests/verify/CoreApiSpec.ApproveCore.verified.txt
index 3699ed78..e5ddb84c 100644
--- a/src/Akka.Hosting.API.Tests/verify/CoreApiSpec.ApproveCore.verified.txt
+++ b/src/Akka.Hosting.API.Tests/verify/CoreApiSpec.ApproveCore.verified.txt
@@ -155,6 +155,7 @@ namespace Akka.Hosting
public Akka.Hosting.DeadLetterOptions? DeadLetterOptions { get; set; }
public Akka.Hosting.DebugOptions? DebugOptions { get; set; }
public bool LogConfigOnStart { get; set; }
+ public Akka.Event.LogFilterBuilder? LogFilterBuilder { get; set; }
public Akka.Event.LogLevel LogLevel { get; set; }
[System.Obsolete("Use the WithDefaultLogMessageFormatter method instead")]
public System.Type LogMessageFormatter { get; set; }
@@ -163,6 +164,7 @@ namespace Akka.Hosting
public Akka.Hosting.LoggerConfigBuilder ClearLoggers() { }
public Akka.Hosting.LoggerConfigBuilder WithDefaultLogMessageFormatter()
where T : Akka.Event.ILogMessageFormatter { }
+ public Akka.Hosting.LoggerConfigBuilder WithLogFilter(System.Action filterBuilder) { }
}
public static class LoggingExtensions
{
diff --git a/src/Akka.Hosting.Tests/HostingExtensionsSpec.cs b/src/Akka.Hosting.Tests/HostingExtensionsSpec.cs
index 92c6cc33..2d6f991e 100644
--- a/src/Akka.Hosting.Tests/HostingExtensionsSpec.cs
+++ b/src/Akka.Hosting.Tests/HostingExtensionsSpec.cs
@@ -6,6 +6,8 @@
// -----------------------------------------------------------------------
using System;
+using System.Linq;
+using Akka.Event;
using FluentAssertions;
using FluentAssertions.Extensions;
using Microsoft.Extensions.DependencyInjection;
@@ -32,4 +34,20 @@ public void WithActorAskTimeoutInfiniteTest()
builder.Configuration.HasValue.Should().BeTrue();
builder.Configuration.Value.GetString("akka.actor.ask-timeout").Should().Be("infinite");
}
+
+ [Fact(DisplayName = "ConfigureLogger WithLogFilter should inject LogFilterSetup")]
+ public void ConfigureLoggerWithLogFilterSetupTest()
+ {
+ var builder = new AkkaConfigurationBuilder(new ServiceCollection(), "fake")
+ .ConfigureLoggers(logger =>
+ {
+ logger.WithLogFilter(filterBuilder =>
+ {
+ filterBuilder.ExcludeMessageContaining("Test");
+ });
+ });
+ var filterSetup = builder.Setups.OfType().First();
+ filterSetup.Filters.Length.Should().Be(1);
+ filterSetup.Filters.Any(f => f is RegexLogMessageFilter).Should().BeTrue();
+ }
}
\ No newline at end of file
diff --git a/src/Akka.Hosting.Tests/Logging/LoggerConfigBuilderSpecs.cs b/src/Akka.Hosting.Tests/Logging/LoggerConfigBuilderSpecs.cs
index 38e178fa..034c16fb 100644
--- a/src/Akka.Hosting.Tests/Logging/LoggerConfigBuilderSpecs.cs
+++ b/src/Akka.Hosting.Tests/Logging/LoggerConfigBuilderSpecs.cs
@@ -5,8 +5,9 @@
// -----------------------------------------------------------------------
using System;
+using System.Linq;
using Akka.Configuration;
-using Akka.Hosting.Logging;
+using Akka.Event;
using FluentAssertions;
using Microsoft.Extensions.DependencyInjection;
using Xunit;
@@ -106,4 +107,42 @@ public void DeadLetterOptionsTest()
}.ToString();
cfg.GetInt("akka.log-dead-letters").Should().Be(10);
}
+
+ [Fact(DisplayName = "WithLogFilter should populate the LogFilterBuilder property")]
+ public void WithLogFilterPropertyTest()
+ {
+ var akkaBuilder = new AkkaConfigurationBuilder(new ServiceCollection(), "test");
+ var loggerConfigBuilder = new LoggerConfigBuilder(akkaBuilder)
+ .WithLogFilter(filterBuilder =>
+ {
+ filterBuilder.ExcludeMessageContaining("Test");
+ });
+ loggerConfigBuilder.LogFilterBuilder.Should().NotBeNull();
+ var filterSetup = loggerConfigBuilder.LogFilterBuilder!.Build();
+ filterSetup.Filters.Length.Should().Be(1);
+ filterSetup.Filters.Any(f => f is RegexLogMessageFilter).Should().BeTrue();
+ }
+
+ [Fact(DisplayName = "WithLogFilter should append existing LogFilterBuilder property")]
+ public void WithLogFilterConcatTest()
+ {
+ var akkaBuilder = new AkkaConfigurationBuilder(new ServiceCollection(), "test");
+ var loggerConfigBuilder = new LoggerConfigBuilder(akkaBuilder)
+ {
+ LogFilterBuilder = new LogFilterBuilder()
+ .ExcludeSourceContaining("Test")
+ };
+ loggerConfigBuilder
+ .WithLogFilter(filterBuilder =>
+ {
+ filterBuilder.ExcludeMessageContaining("Test");
+ });
+
+ loggerConfigBuilder.LogFilterBuilder.Should().NotBeNull();
+ var filterSetup = loggerConfigBuilder.LogFilterBuilder.Build();
+ filterSetup.Filters.Length.Should().Be(2);
+ filterSetup.Filters.Any(f => f is RegexLogMessageFilter).Should().BeTrue();
+ filterSetup.Filters.Any(f => f is RegexLogSourceFilter).Should().BeTrue();
+ }
+
}
\ No newline at end of file
diff --git a/src/Akka.Hosting/LoggerConfigBuilder.cs b/src/Akka.Hosting/LoggerConfigBuilder.cs
index 963c5375..853ed447 100644
--- a/src/Akka.Hosting/LoggerConfigBuilder.cs
+++ b/src/Akka.Hosting/LoggerConfigBuilder.cs
@@ -46,6 +46,8 @@ internal LoggerConfigBuilder(AkkaConfigurationBuilder builder)
public DeadLetterOptions? DeadLetterOptions { get; set; }
public DebugOptions? DebugOptions { get; set; }
+
+ public LogFilterBuilder? LogFilterBuilder { get; set; }
[Obsolete("Use the WithDefaultLogMessageFormatter method instead")]
public Type LogMessageFormatter
@@ -96,6 +98,13 @@ public LoggerConfigBuilder WithDefaultLogMessageFormatter() where T: ILogMess
return this;
}
+ public LoggerConfigBuilder WithLogFilter(Action filterBuilder)
+ {
+ LogFilterBuilder ??= new LogFilterBuilder();
+ filterBuilder(LogFilterBuilder);
+ return this;
+ }
+
///
/// INTERNAL API
///
@@ -108,7 +117,7 @@ internal void AddLogger(Type logger)
_loggers.Add(logger);
}
- internal Config ToConfig()
+ private Config ToConfig()
{
var sb = new StringBuilder()
.Append("akka.loglevel=").AppendLine(ParseLogLevel(LogLevel))
@@ -124,6 +133,15 @@ internal Config ToConfig()
return ConfigurationFactory.ParseString(sb.ToString());
}
+ internal AkkaConfigurationBuilder Build(AkkaConfigurationBuilder builder)
+ {
+ builder.AddHoconConfiguration(ToConfig(), HoconAddMode.Prepend);
+ if (LogFilterBuilder is not null)
+ builder.AddSetup(LogFilterBuilder.Build());
+
+ return builder;
+ }
+
private static string ParseLogLevel(LogLevel logLevel)
=> logLevel switch
{
diff --git a/src/Akka.Hosting/Logging/LoggerFactoryLogger.cs b/src/Akka.Hosting/Logging/LoggerFactoryLogger.cs
index 7eca8fcf..95d2bb11 100644
--- a/src/Akka.Hosting/Logging/LoggerFactoryLogger.cs
+++ b/src/Akka.Hosting/Logging/LoggerFactoryLogger.cs
@@ -24,7 +24,7 @@ public class LoggerFactoryLogger: ActorBase, IRequiresMessageQueue
protected readonly ILoggingAdapter InternalLogger = Akka.Event.Logging.GetLogger(Context.System.EventStream, nameof(LoggerFactoryLogger));
private readonly ILoggerFactory _loggerFactory;
- private ILogger _akkaLogger;
+ private readonly ILogger _akkaLogger;
public LoggerFactoryLogger()
{
diff --git a/src/Akka.Hosting/LoggingExtensions.cs b/src/Akka.Hosting/LoggingExtensions.cs
index e792c966..7c9cfb61 100644
--- a/src/Akka.Hosting/LoggingExtensions.cs
+++ b/src/Akka.Hosting/LoggingExtensions.cs
@@ -24,7 +24,7 @@ public static AkkaConfigurationBuilder ConfigureLoggers(this AkkaConfigurationBu
{
var setup = new LoggerConfigBuilder(builder);
configurator(setup);
- return builder.AddHoconConfiguration(setup.ToConfig(), HoconAddMode.Prepend);
+ return setup.Build(builder);
}
///