1

I started using log4net.async to log using a separate thread but the performance hasn't improved as much as I had anticipated initially and I understand the reason for that being that some of the strings we are logging are very long because they describe properties of a message that is received.

So for example, we could do:

theLogger.Debug(msg.ToString());

When the "ToString()" method is called it could generate a really long string representing a message and it might take awhile to actually generate it (slow deserialization, etc.). Although it is important for me to log the message I would prefer to "stringify" the message on a separate thread rather than the currently running thread so that my currently running thread can continue processing. How would I make log4net evaluate the "ToString()" result or "stringify" the message object on a separate thread?

Denis
  • 11,796
  • 16
  • 88
  • 150
  • Is `msg` immutable (or at least never mutated after this log operation is queued?), and safe to be accessed in this way from another thread? – Servy Mar 29 '17 at 13:51
  • 2
    @CodeCaster I don't think this question is about how to eliminate debug calls in release mode, and providing `Action` also won't help. OP uses forwarding appender which writes messages to file on background thread (all messages, not just debug ones) and he wants to delay execution of `msg.ToSring()` so that it happens on background thread of that async forwarder. So it's not specific to debug calls, nor is it related to IsDebugEnabled settings, nor to conditional compilation. – Evk Mar 29 '17 at 14:25
  • @Evk you're right, I missed that, reopened. Thanks. I don't have any experience with log4net.async, but won't this just move the problem a few milliseconds ahead in time? As long as the other thread is "stringifying" the log message, other log calls will block until that thread is free again? Or has log4net.async some kind of queuing built in? – CodeCaster Mar 29 '17 at 14:29
  • @CodeCaster log4net.async has queueing built in so logs can be delayed which is fine but the msg immutability may be an issue in some cases. I wonder if the object can be copied and set aside or maybe some other trick. – Denis Mar 29 '17 at 18:29
  • @Servy - the message could be made immutable - I can see going down that path. Anyone that wants to modify the message should create a new one. It is logical and very applicable so that is a modification I would definitely support and would be on-board implementing. So let's say that this will not be an issue - if we have to make the message immutable that is doable but if it's not necessary that would be better. – Denis Mar 29 '17 at 18:35

1 Answers1

1

If you want to defer the string creation to a later point in time (potentially in a separate thread) you could create a wrapper that accepts a Func<object, string> that will be invoked only when needed. That wrapper could then also do the dispatch to a separate thread.

In addition, I would recomment to perform some benchmarks on your current string operations and the overhead of dispatching to a separate thread with Func invokcation.

Ronald Rink 'd-fens'
  • 1,289
  • 1
  • 10
  • 27
  • actually no, as we are not using log4net directly (only via `TraceSource`). but you might consider using `Task`s to achieve this (or use a concurrent queue for it) – Ronald Rink 'd-fens' Mar 30 '17 at 09:54