According to this article, you can attach a request ID to an ambient context (the LogContext
) in Serilog like this:
using (LogContext.PushProperty("RequestId", Request.Id))
{
// Process request; all logged events will carry `RequestId`
Log.Information("Adding {Item} to cart {CartId}", item, cart.Id);
}
And that is fine, and seems to be working. I have two scenarios where I need this:
What has me confused is what happens if multiple requests hits the API at once, or we process multiple messages concurrently. Since LogContext
is a static class, can I accidentally overwrite the RequestId
property in the LogContext
with values from another thread than the one who originally set the property?
Lets say thread 1 sets the RequestId
to 1
. Before it is finished, thread 2 sets the RequestId
to 2
because we received another request. Will thread 1 now use 2
as the value for RequestId
when logging? I'm guessing it wont, but can someone explain why? According this this, pushing a property with the same name as an existing property onto the stack overwrites it:
Pushing property onto the context will override any existing properties with the same name, until the object returned from PushProperty() is disposed, as the property A in the example demonstrates.
Does Serilog have one stack per handle returned from the LogContext.PushProperty(...)
method, or something? Is there any way I can override RequestId
, perhaps short of calling LogContext.PushProperty("RequestId", Request.Id)
again?
LogContext is thread-safe via AsyncLocal/ThreadStatic. Each thread has their own LogContext despite it being accessed through a static class. Requests don't share the same LogContext.