6

I am working in a client server application in which multiple clients and server are working on socket based communication for financial transactions where performance is very critical. Currently I am using streamwriter of system.IO namespace to write logs in file. For a single transaction I need to call streamwriter method 50 times to log different value and for more than 50,000 transactions, time taken for this logging become very important.

How can I reduce time taken by application to do logging? Whether I need to choose some other approach or any other class instead of streamwriter? What will be the best way to do logging with lesser time.

funsukvangdu
  • 1,621
  • 4
  • 20
  • 33
  • 4
    I believe most of modern logging framework are using some kind of buffer. Did you tried using one of them (log4net is the first that come into my mind)? – Steve B Jan 22 '13 at 10:59
  • Hi Steve. I didn't tried log4net till date and don't know much about it. Whether you feel it will be good for me to use it in my current application – funsukvangdu Jan 22 '13 at 11:02
  • ...or nLog (has served me very nicely with some very high output log) – spender Jan 22 '13 at 11:03
  • 1
    @AshishKhandelwal Definitely try one of the existing loggers. They are developed by several people over many years and designed to be high-performance with many options. They take advantage of buffers, threading, etc while maintaining output order. I suggest that you not to roll your own without trying one of theirs first as there can be pitfalls. I haven't used NLog, but have been using Log4Net for _years_ without complaint. – Chris Sinclair Jan 22 '13 at 11:41
  • Here are some general things to consider when deciding your logging strategy. https://sometechfacts.blogspot.com/2018/04/performance-conscious-logging.html – Tharanga Hewavithana Apr 18 '18 at 18:21

6 Answers6

7

If performance is key, then I would consider looking at Event Tracing for Windows (AKA ETW).

With .NET 4.5 and the introduction of the EventSource class this has made ETW much easier to implement than in the past.

Vance Morrison's Weblog has some good articles on this topic.

For an overview of the architecture see Improve Debugging And Performance Tuning With ETW.

There is also the Semantic Application Block from Microsoft's patterns & practices team that makes it easier to incorporate the EventSource functionality and to manage logging behavior.

Randy Levy
  • 22,566
  • 4
  • 68
  • 94
  • +1 for ETW. Like always most answers show ignorance towards what is there and how good it is. Hard to beat infrastructure that is available in the kernetl. – TomTom Jan 23 '13 at 05:36
  • Thanks, @TomTom, I think ETW wasn't really "promoted" very well and previously it was fairly complicated for typical Line of Business applications. With the .NET 4.5 additions, I think it will gather more of a following. – Randy Levy Jan 23 '13 at 07:22
  • I seriously hope. It is hard to beat. Still some "open issues" (still ooking for a way to move ETW into windows log easily) but it really has nice features. – TomTom Jan 23 '13 at 07:49
  • 1
    @TomTom, you may be interested in looking at the new Semantic Application Block CTP (see answer). – Randy Levy Feb 15 '13 at 05:44
1

I suggest you to try Log4Net, you can configure where (file, database, xml) and when (bath, transaction, ...) and easily switch tracing level (debug, info, warning, ...)

Writing a log system from scratch is not worth it.

Stefano Altieri
  • 4,550
  • 1
  • 24
  • 41
0

Cache the values before writing them to disk.

Only commit the log when you have finished your transaction.

Something like this:

StringBuilder builder = new StringBuilder();
// do transaction step 1
builder.Append("Transaction step 1" + environment.NewLine); // or however you add a line to you log

// step 2
builder.Append("Transaction step 2" + environment.NewLine);

//...

// step 50
builder.Append("Transaction step 50" + environment.NewLine);

// now write to the file
File.WriteAllText(@"C:\log.txt", builder.ToString());

You can add in some handling if there is an error in any step to still write the log.

You could also use some opensource tool like log4net: http://logging.apache.org/log4net/.

TheKingDave
  • 926
  • 1
  • 8
  • 16
  • That would be dependent on there being a concept of a "transaction". If the buffer is continually being written to.. there needs to be a "flush threshold". – Simon Whitehead Jan 22 '13 at 11:02
  • In financial applications you are general working with some transaction i.e. processing some records. Any processing can be done sequentially with a commit after the record is processed. Or as you say you will need to flush the buffer every X seconds. – TheKingDave Jan 22 '13 at 11:06
  • 1
    What I mean is that if you introduce the concept into the logging then you're tied to it. If you leave the decision of when to flush to the logging mechanism, you aren't tied to the transaction. Hopefully that makes sense :) – Simon Whitehead Jan 22 '13 at 11:09
  • Please don't recommend doing string concatenation 50 times! – Trevor Pilley Jan 22 '13 at 11:43
  • Sorry it is better to write to a file 50 times then ? I presume you mean string build yes use string builder. – TheKingDave Jan 22 '13 at 14:57
  • I've changed this example to now use string builder. – TheKingDave Jan 22 '13 at 17:08
0

I suggest log into database (high perfomance, maybe embedded sqlite/sqlce). Bonus - you can structure and query your log entries.

SalientBrain
  • 2,431
  • 16
  • 18
0

To reduce the time taken by logging I suggest:

  • Ensure that the data being logged requires minimal conversion/formatting
  • Create or use a logging library that:
    • When called puts the logging data (along with time, thread id, and other tags to be logged) in a buffer.
    • Periodically flushes the buffered data to disk (i.e. immediately when the buffered data is big enough to fill at least one physical block in the log file, or immediately when the system becomes idle, or periodically every x seconds).
    • Locks the log file for exclusive write access, so you can view it while the software is running but other processes can't lock it under your feet.
    • Uses a separate thread to handle the flushing i.e. don't slow down your worker threads.
  • If you have many server processes, consider using IPC to send the log data to a single point, to minimise the number of active files being written and number of buffers in use (you may have to test so see if this is worth it, and you may have to add tags to show the source of each entry).
  • Do scheduled/idle time backups of the logs to prevent them getting too big.
Peter Wishart
  • 11,600
  • 1
  • 26
  • 45
0

One way to improve performance of you application and be able to write out all those log messages is to queue them up in an MSMQ queue, and have a windows service application process the queued log messages when the server is not under load. You could have the queue on a completely separate server too.

Implementation-wise you can setup a WCF web service that uses MSMQ for processing your log messages. That makes it easier than having to setup a windows service.

ajawad987
  • 4,439
  • 2
  • 28
  • 45