Skip to content

Commit

Permalink
Add log filtering integration (#460)
Browse files Browse the repository at this point in the history
* Add log filtering integration

* Update API approval list

* Remove one registration method

* Update API approval list
  • Loading branch information
Arkatufus authored Jun 4, 2024
1 parent d4b23c6 commit 6719082
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 4 deletions.
39 changes: 39 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -636,3 +636,42 @@ To set up the `Microsoft.Extensions.Logging` log filtering, you will need to edi
```

[Back to top](#akkahosting)

<a id="filtering-logs"></a>
## 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)
Original file line number Diff line number Diff line change
Expand Up @@ -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<T> method instead")]
public System.Type LogMessageFormatter { get; set; }
Expand All @@ -163,6 +164,7 @@ namespace Akka.Hosting
public Akka.Hosting.LoggerConfigBuilder ClearLoggers() { }
public Akka.Hosting.LoggerConfigBuilder WithDefaultLogMessageFormatter<T>()
where T : Akka.Event.ILogMessageFormatter { }
public Akka.Hosting.LoggerConfigBuilder WithLogFilter(System.Action<Akka.Event.LogFilterBuilder> filterBuilder) { }
}
public static class LoggingExtensions
{
Expand Down
18 changes: 18 additions & 0 deletions src/Akka.Hosting.Tests/HostingExtensionsSpec.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
// -----------------------------------------------------------------------

using System;
using System.Linq;
using Akka.Event;
using FluentAssertions;
using FluentAssertions.Extensions;
using Microsoft.Extensions.DependencyInjection;
Expand All @@ -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<LogFilterSetup>().First();
filterSetup.Filters.Length.Should().Be(1);
filterSetup.Filters.Any(f => f is RegexLogMessageFilter).Should().BeTrue();
}
}
41 changes: 40 additions & 1 deletion src/Akka.Hosting.Tests/Logging/LoggerConfigBuilderSpecs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
}

}
20 changes: 19 additions & 1 deletion src/Akka.Hosting/LoggerConfigBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<T> method instead")]
public Type LogMessageFormatter
Expand Down Expand Up @@ -96,6 +98,13 @@ public LoggerConfigBuilder WithDefaultLogMessageFormatter<T>() where T: ILogMess
return this;
}

public LoggerConfigBuilder WithLogFilter(Action<LogFilterBuilder> filterBuilder)
{
LogFilterBuilder ??= new LogFilterBuilder();
filterBuilder(LogFilterBuilder);
return this;
}

/// <summary>
/// INTERNAL API
///
Expand All @@ -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))
Expand All @@ -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
{
Expand Down
2 changes: 1 addition & 1 deletion src/Akka.Hosting/Logging/LoggerFactoryLogger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public class LoggerFactoryLogger: ActorBase, IRequiresMessageQueue<ILoggerMessag
/// </summary>
protected readonly ILoggingAdapter InternalLogger = Akka.Event.Logging.GetLogger(Context.System.EventStream, nameof(LoggerFactoryLogger));
private readonly ILoggerFactory _loggerFactory;
private ILogger<ActorSystem> _akkaLogger;
private readonly ILogger<ActorSystem> _akkaLogger;

public LoggerFactoryLogger()
{
Expand Down
2 changes: 1 addition & 1 deletion src/Akka.Hosting/LoggingExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

/// <summary>
Expand Down

0 comments on commit 6719082

Please sign in to comment.