Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/pr_validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ jobs:

- name: "dotnet test"
shell: bash
run: dotnet test -c Release
run: dotnet test -c Release

- name: "dotnet pack"
run: dotnet pack -c Release -o ./bin/nuget
14 changes: 14 additions & 0 deletions Akka.Hosting.sln
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Akka.Remote.Hosting.Tests",
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Akka.Hosting.LoggingDemo", "src\Examples\Akka.Hosting.LoggingDemo\Akka.Hosting.LoggingDemo.csproj", "{298D7727-FDC6-49B2-9030-CC7F0E09B0B8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Akka.Hosting.OpenTelemetry.Demo", "src\Examples\Akka.Hosting.OpenTelemetry.Demo\Akka.Hosting.OpenTelemetry.Demo.csproj", "{6BCB9636-DAD2-4364-8A83-3D2888FE5AB2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Akka.Hosting.OpenTelemetry.AppHost", "src\Examples\Akka.Hosting.OpenTelemetry.AppHost\Akka.Hosting.OpenTelemetry.AppHost.csproj", "{CC22F505-B648-420E-BC8A-0FCE46082986}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -110,6 +114,14 @@ Global
{298D7727-FDC6-49B2-9030-CC7F0E09B0B8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{298D7727-FDC6-49B2-9030-CC7F0E09B0B8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{298D7727-FDC6-49B2-9030-CC7F0E09B0B8}.Release|Any CPU.Build.0 = Release|Any CPU
{6BCB9636-DAD2-4364-8A83-3D2888FE5AB2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6BCB9636-DAD2-4364-8A83-3D2888FE5AB2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6BCB9636-DAD2-4364-8A83-3D2888FE5AB2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6BCB9636-DAD2-4364-8A83-3D2888FE5AB2}.Release|Any CPU.Build.0 = Release|Any CPU
{CC22F505-B648-420E-BC8A-0FCE46082986}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CC22F505-B648-420E-BC8A-0FCE46082986}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CC22F505-B648-420E-BC8A-0FCE46082986}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CC22F505-B648-420E-BC8A-0FCE46082986}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -118,6 +130,8 @@ Global
{5F6A7BE8-6906-46CE-BA1C-72EA11EFA33B} = {EFA970FF-6BCC-4C38-84D8-324D40F2BF03}
{4F79325B-9EE7-4501-800F-7A1F8DFBCC80} = {EFA970FF-6BCC-4C38-84D8-324D40F2BF03}
{298D7727-FDC6-49B2-9030-CC7F0E09B0B8} = {EFA970FF-6BCC-4C38-84D8-324D40F2BF03}
{6BCB9636-DAD2-4364-8A83-3D2888FE5AB2} = {EFA970FF-6BCC-4C38-84D8-324D40F2BF03}
{CC22F505-B648-420E-BC8A-0FCE46082986} = {EFA970FF-6BCC-4C38-84D8-324D40F2BF03}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B99E6BB8-642A-4A68-86DF-69567CBA700A}
Expand Down
14 changes: 9 additions & 5 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@
<Copyright>Copyright © 2013-$([System.DateTime]::Now.Year) Akka.NET Team</Copyright>
<Authors>Akka.NET Team</Authors>
<VersionPrefix>1.5.59</VersionPrefix>
<PackageReleaseNotes>**Bug Fixes**
<PackageReleaseNotes>**New Features**
* [Add OpenTelemetry trace correlation support for LoggerFactoryLogger](https://github.com/akkadotnet/Akka.Hosting/issues/700) - enables proper trace correlation for logs emitted from actor code. When using Akka.NET 1.5.59+, `LogEvent.ActivityContext` captures trace context at log creation time and flows it through to OpenTelemetry `LogRecord`s via the new `AkkaTraceContextProcessor`.

**Bug Fixes**
* [Fix semantic logging not capturing named placeholders as structured properties](https://github.com/akkadotnet/Akka.Hosting/pull/702) - resolved [issue #701](https://github.com/akkadotnet/Akka.Hosting/issues/701) where named placeholders like `{Event}` in log messages were not captured as searchable structured properties. Made all `LoggerConfigBuilder` properties optional and refactored message formatting code.
* [Fix TestKit startup timeout race condition](https://github.com/akkadotnet/Akka.Hosting/pull/705) - resolved race condition in `TestKit.InitializeAsync()` where `CancellationTokenSource.Register()` threw exceptions on the timer thread, causing unhandled exceptions that crashed the test host process. Also increased default startup timeout from 10s to 30s for CI environments.

**Updates**
* [Bump Akka version from 1.5.58 to 1.5.59](https://github.com/akkadotnet/akka.net/releases/tag/1.5.59)</PackageReleaseNotes>
* [Bump Akka version from 1.5.58 to 1.5.59](https://github.com/akkadotnet/akka.net/releases/tag/1.5.59)
* Added OpenTelemetry dependency (1.9.0+) for trace correlation support</PackageReleaseNotes>
<PackageIcon>akkalogo.png</PackageIcon>
<PackageProjectUrl>
https://github.com/akkadotnet/Akka.Hosting
Expand All @@ -31,8 +35,8 @@
<CoverletVersion>6.0.3</CoverletVersion>
<XunitRunneVisualstudio>3.1.5</XunitRunneVisualstudio>
<AkkaVersion>1.5.59</AkkaVersion>
<MicrosoftExtensionsVersion>[6.0.0,)</MicrosoftExtensionsVersion>
<SystemTextJsonVersion>[6.0.10,)</SystemTextJsonVersion>
<MicrosoftExtensionsVersion>[8.0.0,)</MicrosoftExtensionsVersion>

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The OTEL packages require these

<SystemTextJsonVersion>[8.0.5,)</SystemTextJsonVersion>
</PropertyGroup>
<!-- SourceLink support for all Akka.NET projects -->
<ItemGroup>
Expand All @@ -50,4 +54,4 @@
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>
</Project>
</Project>
8 changes: 6 additions & 2 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
#### 1.5.59 January 26th 2026 ####
#### 1.5.59 January 2026 ####

**New Features**
* [Add OpenTelemetry trace correlation support for LoggerFactoryLogger](https://github.com/akkadotnet/Akka.Hosting/issues/700) - enables proper trace correlation for logs emitted from actor code. Solves the problem that `Activity.Current` doesn't flow across actor mailbox boundaries because it uses `AsyncLocal<T>`. When using Akka.NET 1.5.59+, `LogEvent.ActivityContext` captures trace context at log creation time and flows it through to OpenTelemetry `LogRecord`s via the new `AkkaTraceContextProcessor`. Register with `options.AddAkkaTraceCorrelation()` in your OpenTelemetry logging configuration.

**Bug Fixes**
* [Fix semantic logging not capturing named placeholders as structured properties](https://github.com/akkadotnet/Akka.Hosting/pull/702) - resolved [issue #701](https://github.com/akkadotnet/Akka.Hosting/issues/701) where named placeholders like `{Event}` in log messages were not captured as searchable structured properties. Made all `LoggerConfigBuilder` properties optional and refactored message formatting code.
* [Fix TestKit startup timeout race condition](https://github.com/akkadotnet/Akka.Hosting/pull/705) - resolved race condition in `TestKit.InitializeAsync()` where `CancellationTokenSource.Register()` threw exceptions on the timer thread, causing unhandled exceptions that crashed the test host process. Also increased default startup timeout from 10s to 30s for CI environments.

**Updates**
* [Bump Akka version from 1.5.58 to 1.5.59](https://github.com/akkadotnet/akka.net/releases/tag/1.5.59)
* Added `OpenTelemetry` package dependency (1.9.0+) for trace correlation support

#### 1.5.58 January 9th 2026 ####

Expand Down Expand Up @@ -79,4 +83,4 @@
* [Added dependency-injected health checks](https://github.com/akkadotnet/Akka.Hosting/pull/659) - `WithHealthCheck<T>()` generic methods for DI-resolved health checks

**Updates**
* [Bump Akka version from 1.5.50 to 1.5.51](https://github.com/akkadotnet/akka.net/releases/tag/1.5.51)
* [Bump Akka version from 1.5.50 to 1.5.51](https://github.com/akkadotnet/akka.net/releases/tag/1.5.51)
2 changes: 1 addition & 1 deletion src/Akka.Cluster.Hosting.Tests/ClusterOptionsSpec.cs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ public void ClusterOptionsConfigurationTest()
using var stream = new MemoryStream(Encoding.UTF8.GetBytes(json));
var jsonConfig = new ConfigurationBuilder().AddJsonStream(stream).Build();

var clusterOptions = jsonConfig.GetSection("Akka:ClusterOptions").Get<ClusterOptions>();
var clusterOptions = jsonConfig.GetSection("Akka:ClusterOptions").Get<ClusterOptions>()!;
clusterOptions.SplitBrainResolver = jsonConfig.GetSection("Akka:KeepMajorityOption").Get<KeepMajorityOption>();

var builder = new AkkaConfigurationBuilder(new ServiceCollection(), "")
Expand Down
2 changes: 1 addition & 1 deletion src/Akka.Cluster.Hosting.Tests/XUnitLogger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public bool IsEnabled(LogLevel logLevel)
};
}

public IDisposable BeginScope<TState>(TState state)
public IDisposable? BeginScope<TState>(TState state) where TState : notnull
{
throw new NotImplementedException();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ namespace Akka.Hosting
public static Akka.Hosting.AkkaConfigurationBuilder WithHealthCheck(this Akka.Hosting.AkkaConfigurationBuilder builder, string name, Akka.Hosting.IAkkaHealthCheck healthCheck, Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus? failureStatus = default, System.Collections.Generic.IEnumerable<string>? tags = null, System.TimeSpan? timeout = default) { }
public static Akka.Hosting.AkkaConfigurationBuilder WithHealthCheck(this Akka.Hosting.AkkaConfigurationBuilder builder, string name, System.Func<Akka.Actor.ActorSystem, Akka.Hosting.ActorRegistry, System.Threading.CancellationToken, System.Threading.Tasks.Task<Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult>> healthCheck, Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus? failureStatus = default, System.Collections.Generic.IEnumerable<string>? tags = null, System.TimeSpan? timeout = default) { }
}
public static class AkkaOpenTelemetryExtensions
{
public static OpenTelemetry.Logs.OpenTelemetryLoggerOptions AddAkkaTraceCorrelation(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions options) { }
}
public class DeadLetterOptions
{
public DeadLetterOptions() { }
Expand Down Expand Up @@ -251,6 +255,21 @@ namespace Akka.Hosting.HealthChecks
}
namespace Akka.Hosting.Logging
{
public readonly struct AkkaLogState : System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, object?>>, System.Collections.IEnumerable
{
public const string SpanIdKey = "Akka.SpanId";
public const string TraceFlagsKey = "Akka.TraceFlags";
public const string TraceIdKey = "Akka.TraceId";
public AkkaLogState(System.Diagnostics.ActivityContext activityContext, string formattedMessage) { }
public AkkaLogState(System.Diagnostics.ActivityContext activityContext, System.Collections.Generic.IReadOnlyDictionary<string, object> semanticProperties, string actorPath, System.DateTimeOffset timestamp, int threadId, string logSource, string template, string formattedMessage) { }
public System.Collections.Generic.IEnumerator<System.Collections.Generic.KeyValuePair<string, object?>> GetEnumerator() { }
public override string ToString() { }
}
public sealed class AkkaTraceContextProcessor : OpenTelemetry.BaseProcessor<OpenTelemetry.Logs.LogRecord>
{
public AkkaTraceContextProcessor() { }
public override void OnEnd(OpenTelemetry.Logs.LogRecord data) { }
}
public class LoggerFactoryLogger : Akka.Actor.ActorBase, Akka.Dispatch.IRequiresMessageQueue<Akka.Event.ILoggerMessageQueueSemantics>
{
protected readonly Akka.Event.ILoggingAdapter InternalLogger;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ namespace Akka.Hosting.TestKit.Internals
public class XUnitLogger : Microsoft.Extensions.Logging.ILogger
{
public XUnitLogger(string category, Xunit.Abstractions.ITestOutputHelper helper, Microsoft.Extensions.Logging.LogLevel logLevel) { }
public System.IDisposable BeginScope<TState>(TState state) { }
public System.IDisposable? BeginScope<TState>(TState state)
where TState : notnull { }
public bool IsEnabled(Microsoft.Extensions.Logging.LogLevel logLevel) { }
public void Log<TState>(Microsoft.Extensions.Logging.LogLevel logLevel, Microsoft.Extensions.Logging.EventId eventId, TState state, System.Exception? exception, System.Func<TState, System.Exception?, string> formatter) { }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="7.0.0" />
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="8.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(TestSdkVersion)" />
<PackageReference Include="xunit" Version="$(XunitVersion)" />
<PackageReference Include="FluentAssertions" Version="6.12.2" />
Expand Down
2 changes: 1 addition & 1 deletion src/Akka.Hosting.TestKit/Akka.Hosting.TestKit.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<ItemGroup>
<PackageReference Include="Akka.TestKit.Xunit2" Version="$(AkkaVersion)" />
<PackageReference Include="Akka.Persistence.TestKit" Version="$(AkkaVersion)" />
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="7.0.0" />
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="8.0.0" />
<PackageReference Include="xunit" Version="$(XunitVersion)" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="$(MicrosoftExtensionsVersion)" />
<PackageReference Include="System.Text.Json" Version="$(SystemTextJsonVersion)" />
Expand Down
2 changes: 1 addition & 1 deletion src/Akka.Hosting.TestKit/Internals/XUnitLogger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public bool IsEnabled(LogLevel logLevel)
};
}

public IDisposable BeginScope<TState>(TState state)
public IDisposable? BeginScope<TState>(TState state) where TState : notnull
{
return NullScope.Instance;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Akka.Hosting.Tests/Akka.Hosting.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<PackageReference Include="Microsoft.Extensions.Hosting" Version="$(MicrosoftExtensionsVersion)" />
<PackageReference Include="System.Text.Json" Version="$(SystemTextJsonVersion)" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="8.0.0" />
<PackageReference Include="Akka.TestKit.Xunit2" Version="$(AkkaVersion)" />
<PackageReference Include="FluentAssertions" Version="6.12.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(TestSdkVersion)" />
Expand Down
Loading