-
Notifications
You must be signed in to change notification settings - Fork 20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ForContext() Extension Method Generate Context Trees and Layered Adapter #33
Conversation
Just like Serilog's ForContext(), the ForContext() extension method generates a new logging adapter instance which has as context the given property values. This means that other calls to ForContext() will generate a new context in which the new value will not be pushed into other previously generated logging contexts.
The reasons the docs describe that you need to assign it to a private member variable, is because retrieving a logger instance, has more overhead then you might think. Its not alot, but still its more then just creating a new logger instance. However in your example, this issue at hand could easily be circumvented by creating a new logger instance on each message. I understand why you'd want this change. But i'd have to think about it some more, meaning, if this is the way we want the api to behave that is. |
You are right, in fact right now my message handlers look something like this: public class SomeActor : ReceiveActor
{
private readonly ILoggingAdapter _logger = Context.GetLogger<SerilogLoggingAdapter>();
public SomeActor()
{
Receive<MessageA>(msg => Handle(msg));
Receive<MessageB>(msg => Handle(msg));
}
public void Handle(MessageA msg)
{
var logger = Context.GetLogger<SerilogLoggingAdapter>().ForContext("CorrelationId", Guid.NewGuid().ToString());
logger.Info("Received MessageA");
Self.Tell(new MessageB());
}
public void Handle(MessageB msg)
{
var logger = Context.GetLogger<SerilogLoggingAdapter>().ForContext("CorrelationId", Guid.NewGuid().ToString());
logger.Info("Received MessageB");
}
} But, in my opinion, this feels more like a fix than how it should normally behave. The reasons I believe the behavior introduced by this PR is correct are the following:
|
@arturosevilla Would you mind doing a PR on the main akka.net repo to update the serilog docs. And providing a small explanation of how to use the ForContext() and how it behaves ? |
@Danthar Not at all. I will start working on that. |
@Danthar Do you know when these changes will be published into a Nuget package? |
Soon. We are prepping a 1.3.3 release. I plan release an update for this plugin shortly thereafter |
This changeset models Serilog's
ForContext()
behavior for the provided extension method. For example,With Serilog, we would expect that
logger1
would have a propertyCorrelationId
, but notInstanceId
, andlogger2
would have both.The current implementation of
ForContext()
extension method does not allow for this behavior if theILoggingAdapter
is used as recommended in Akka.net's documentation as a class field/variable: http://getakka.net/articles/utilities/logging.html#how-to-logFor example, the following code would throw an exception depending on how messages are received:
If
MessageB
would be received by the actor first, then no issue would arise, however, ifMessageA
is sent then the correlation ID property would be set, but then aMessageB
would be sent to itself, and theForContext()
extension method would fail as the internal storage (dictionary) would have already such property, even though if a programmer used to Serilog behavior would see this code as valid (theForContext()
should generate its own context).