You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Is your feature request related to a problem? Please describe.
I've been doing some work in areas where a structured logging approach akin to Serilog's log enrichment and structured data system would be very useful.
Moreover, there are some other issues with our logging system that make it tricky:
1 - We decouple the production of LogEvents from their eventual formatting, which happens inside dedicated logging actors who are subscribed to the LogEvent topic in the EventStream.
This is done, primarily, for performance reasons as string formatting is:
expensive and
transmitting logs to things like HTTP / File System / Database sinks can accidentally turn the logging system into a global lock for all actors. Yes, this actually happens regularly when users don't use the ILoggingAdapter and it is extremely destructive when it happens - the fault there lies with both the end-users and the logging libraries themselves for not being clear about sync / async guarantees while logging.
So while this decoupling produces a lot of great results, it produces a couple of nasty ones too:
ILogEventEnrichers from Serilog and similar constructs from other libraries rely on extracting the value from the enrichment process at the time the LogEvent is produced, i.e. from the live actor that is doing the logging. This is a problem because our extensible logging system can only produce those outcomes during stage 2 - when the LogEvent is formatted into its target logging system. This means enrichment vehicles can't capture temporary, runtime context when the actor is processing a message - which impedes the ability for enrichment tools to produce value.
Akka.NET's built-in LogEvent and ILoggingAdapter types don't have any means to express properties (Dictionary<string, object>) in a way that can be consistently implemented across multiple logging packages.
2 - The Context.GetLogger() Method Fundamentally Lacks Extensibility
The hacks we have to do inside Akka.Logger.Serilog today, for instance, to introduce a modicum of contextual logging is quite hacky, in my opinion:
varlog= Context.GetLogger<SerilogLoggingAdapter>();// correct
log.Info("My boss makes me use {semantic} logging","semantic");// serilog semantic logging format
Serilog's string formatter is, of course, different than the normal one we use inside Akka.NET, and making that switch is the primary reason why this code exists. However, I'm of the opinion that developers should be able to specify "use structured logging" or "don't use structured logging" generically, without having to call plugin-specific methods inside their actors.
The underlying ILoggingAdapter should support some more extensibility points, driven via an internal provider, that can help introduce third party implementations behind the scenes.
Describe the solution you'd like
I think it would be ideal if we could:
Allow logging plugins to inject their own ILoggingAdapter implementations behind the scenes, which can automatically do things such as inject the SerilogMessageFormatter without end-users having to decorate their code.
Support the capture of structured properties on ILoggingAdapter, or perhaps offer a second interface akin to the JVM's LogMarker for capturing structured data.
Open extensibility points to allow for things like Serilog's LogContext to be used inside an Akka.NET actor, and to have those values captured into an Akka.NET LogEvent. This could, in theory, be done through the ILoggingAdapter extensibility I mentioned earlier.
Describe alternatives you've considered
In JVM Akka they solved this by introducing a LogMarker type that could accept a Dictionary<string,object> of additional properties along with the format string and / or Exception data: akka/akka#28209
Introducing something like that, a second set of interfaces and classes for doing structured logging specifically, might be a nice way to give developers the ability to swap between structured logging and simple logging.
The text was updated successfully, but these errors were encountered:
I think we can mark this as resolved for now - we'd need to add support for a "default" semantic logging ILogMessageFormatter for this to be implemented by default in Akka.NET, but all of the infrastructure to do that is now enabled.
Is your feature request related to a problem? Please describe.
I've been doing some work in areas where a structured logging approach akin to Serilog's log enrichment and structured data system would be very useful.
Moreover, there are some other issues with our logging system that make it tricky:
1 - We decouple the production of
LogEvent
s from their eventual formatting, which happens inside dedicated logging actors who are subscribed to theLogEvent
topic in theEventStream
.This is done, primarily, for performance reasons as
string
formatting is:ILoggingAdapter
and it is extremely destructive when it happens - the fault there lies with both the end-users and the logging libraries themselves for not being clear about sync / async guarantees while logging.So while this decoupling produces a lot of great results, it produces a couple of nasty ones too:
ILogEventEnricher
s from Serilog and similar constructs from other libraries rely on extracting the value from the enrichment process at the time theLogEvent
is produced, i.e. from the live actor that is doing the logging. This is a problem because our extensible logging system can only produce those outcomes during stage 2 - when theLogEvent
is formatted into its target logging system. This means enrichment vehicles can't capture temporary, runtime context when the actor is processing a message - which impedes the ability for enrichment tools to produce value.LogEvent
andILoggingAdapter
types don't have any means to express properties (Dictionary<string, object>
) in a way that can be consistently implemented across multiple logging packages.2 - The
Context.GetLogger()
Method Fundamentally Lacks ExtensibilityThe hacks we have to do inside
Akka.Logger.Serilog
today, for instance, to introduce a modicum of contextual logging is quite hacky, in my opinion:https://github.com/akkadotnet/Akka.Logger.Serilog#semantic-logging-syntax
Serilog's string formatter is, of course, different than the normal one we use inside Akka.NET, and making that switch is the primary reason why this code exists. However, I'm of the opinion that developers should be able to specify "use structured logging" or "don't use structured logging" generically, without having to call plugin-specific methods inside their actors.
The underlying
ILoggingAdapter
should support some more extensibility points, driven via an internal provider, that can help introduce third party implementations behind the scenes.Describe the solution you'd like
I think it would be ideal if we could:
ILoggingAdapter
implementations behind the scenes, which can automatically do things such as inject theSerilogMessageFormatter
without end-users having to decorate their code.ILoggingAdapter
, or perhaps offer a second interface akin to the JVM'sLogMarker
for capturing structured data.LogContext
to be used inside an Akka.NET actor, and to have those values captured into an Akka.NETLogEvent
. This could, in theory, be done through theILoggingAdapter
extensibility I mentioned earlier.Describe alternatives you've considered
In JVM Akka they solved this by introducing a
LogMarker
type that could accept aDictionary<string,object>
of additional properties along with the format string and / orException
data: akka/akka#28209Introducing something like that, a second set of interfaces and classes for doing structured logging specifically, might be a nice way to give developers the ability to swap between structured logging and simple logging.
The text was updated successfully, but these errors were encountered: