Search code examples
serilogakka.net

Akka.Net 1.5 Serilog logger not adding extra properties when using ForContext


I am trying to add extra properties to an actor's logger, using ForContext(). The current Akka.NET documentation says that from version 1.5 of Akka.NET onwards you should be able to use GetLogger(), instead of GetLogger<SerilogLoggingAdapter>() and that the specific SerilogLoggingAdapter is only needed in Akka.net 1.4.

However this does not appear to work - the only way I can get the property set by ForContext to show is by using the explicit GetLogger<SerilogLoggingAdapter>() way.

Is there some way of using ForContext calls inside an Actor without having to explicitly referring to the SerilogLoggingAdapter

Here's a trivial example - the actor MyActor tries to emit messages both ways, and only the old way gives me access to the property:

internal class Program
{
    static void Main(string[] args)
    {
        var logger = new LoggerConfiguration()
                        .WriteTo.Console(outputTemplate: "[From Context: {FromContextProperty}] [From Message:{FromMessageProperty}] {Message:lj}{NewLine}")
                        .MinimumLevel.Information()
                        .CreateLogger();

        Serilog.Log.Logger = logger;

        var systemConfig = @"
            akka {
                loglevel=DEBUG,  
                loggers=[""Akka.Logger.Serilog.SerilogLogger, Akka.Logger.Serilog""]
                logger-formatter=""Akka.Logger.Serilog.SerilogLogMessageFormatter, Akka.Logger.Serilog""
            }";

        using (var sys = ActorSystem.Create("mySystem", systemConfig)) 
        {
            Console.WriteLine("Enter some text to send to the actor, to log it");
            var act = sys.ActorOf<MyActor>();
            while (true)
            {
                act.Tell(Console.ReadLine());
            }
        }
    }
}

public class MyActor:ReceiveActor
{
    public MyActor() 
    {
        Receive<string>(txt =>
        {
            // this way does NOT render the FromContext property in the output, contrary to documentation
            Context.GetLogger()
            .ForContext("FromContextProperty", "bbb")
            .Error("NEW WAY {FromMessageProperty}", txt);

           Context.GetLogger<SerilogLoggingAdapter>()
           .ForContext("FromContextProperty", "bbb")
           .Error("OLD WAY {FromMessageProperty}", txt);
        }
        );
    }
}

Output produced, note the missing context property in the first line: missing context property when using GetLogger()

Package versions used:

 <ItemGroup>
   <PackageReference Include="Akka" Version="1.5.19" />
   <PackageReference Include="Akka.Logger.Serilog" Version="1.5.12.1" />
   <PackageReference Include="Serilog" Version="3.1.1" />
   <PackageReference Include="Serilog.Sinks.Console" Version="5.0.1" />
 </ItemGroup>

Solution

  • the current Akka.NET documentation says that from version 1.5 of Akka.NET onwards you should be able to use GetLogger(), instead of GetLogger() and that the specific SerilogLoggingAdapter is only needed in Akka.net 1.4.

    So I think we're missing this from our Akka.Hosting documentation but basically it's now possible to set the log formatter universally. There's a manual step involved though during the configuration to do this, which you can see here: https://github.com/akkadotnet/Akka.Logger.Serilog/blob/ba72148dce96f26d1faccd2a6362ceaaef9e7eca/src/Examples/Akka.Hosting.LoggingDemo/Program.cs#L26-L37

    edit: however, for passing in context you do still need to use the GetLogger() to do this. Maybe we can do something inside Akka.Logger.Serilog to have ForContext automatically do this, but for the moment that's an issue that sits outside what the formatter can do.