Pergunta

I want to replace default Microsoft's XmlTraceListener with a listener which switches files based on file size limit or current date. I want to keep the default XmlTraceListener file format so I can open files with the ServiceTraceViewer tool.

I found an article http://www.codeproject.com/Articles/30956/A-Rolling-XmlWriterTraceListener but from comments it seems that this listener has some instabilities even after suggested patches applied.

Then I found Microsoft's own implementation of CircularListener http://msdn.microsoft.com/en-us/library/aa395205.aspx

I wanted to extend it, but noticed that it has

static CircularStream m_stream = null;

and later this variable is being accessed without locks. When reading http://msdn.microsoft.com/en-us/library/ms733025.aspx I discovered that even XmlWriterTraceListener itself is not thread-safe. MSDN says:

Because System.Diagnostics.XmlWriterTraceListener is not thread-safe, the trace source may lock resources exclusively when outputting traces. When many threads output traces to a trace source configured to use this listener, resource contention may occur, which results in a significant performance issue. To resolve this problem, you should implement a custom listener that is thread-safe.

So essentially this means that TraceListener.IsThreadSafe property is left as false for XmlWriterTraceListener, so then the higher level tracing system is locking each time when TraceData / TraceEvent is called, am I right?

Will there be any benefit from adding a lock around that static CircularStream m_stream and returning true form the overriden IsThreadSafe property ? Or maybe it will be the same thing that is already being done in the XmlTraceListener?

What can I do to make CircularTraceListener thread-safe and efficient?

Foi útil?

Solução

I think CircularTraceListener is basically flawed. As you've noticed there is a static m_stream. But, even worse, when you construct a CircularTraceListener it passes along the new stream to the base (XmlWriterTraceListener). This means that although CircularTraceListener only knows about the last created stream, the base class is potentially using one of many streams. And, of course, if the CircularTraceListener gets disposed, the base class will dispose the shared m_stream object.

I'd recommend you'd not base anything from CircularTraceListener and start from scratch.

update:

I've had much better luck with things like log4net and NLog for things like circular logging.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top