Поточно-ориентированный прослушиватель трассировки на основе XmlWriterTraceListener

Я хочу заменить стандартный Microsoft XmlTraceListener слушателем, который переключает файлы в зависимости от ограничения размера файла или текущей даты. Я хочу сохранить формат файла XmlTraceListener по умолчанию, чтобы можно было открывать файлы с помощью инструмента ServiceTraceViewer.

Я нашел статью http://www.codeproject.com/Articles/30956/A-Rolling-XmlWriterTraceListener, но из комментариев кажется, что у этого слушателя есть некоторая нестабильность даже после применения предложенных исправлений.

Затем я нашел собственную реализацию CircularListener от Microsoft http://msdn.microsoft.com/en-us/library/aa395205.aspx

Я хотел расширить его, но заметил, что он

static CircularStream m_stream = null;

а позже доступ к этой переменной осуществляется без блокировок. При чтении http://msdn.microsoft.com/en-us/library/ms733025.aspx Я обнаружил, что даже сам XmlWriterTraceListener не является потокобезопасным. MSDN говорит:

Поскольку System.Diagnostics.XmlWriterTraceListener не является потокобезопасным, источник трассировки может блокировать ресурсы исключительно при выводе трассировок. Когда многие потоки выводят трассировку на источник трассировки, настроенный на использование этого прослушивателя, может возникнуть конфликт ресурсов, что приведет к серьезной проблеме с производительностью. Чтобы решить эту проблему, вы должны реализовать настраиваемый прослушиватель, который является потокобезопасным.

По сути, это означает, что свойство TraceListener.IsThreadSafe остается как false для XmlWriterTraceListener, поэтому система трассировки более высокого уровня блокируется каждый раз, когда вызывается TraceData / TraceEvent, я прав?

Будет ли какая-то польза от добавления блокировки вокруг этого static CircularStream m_stream и возврата true из переопределенного свойства IsThreadSafe? Или, может быть, это будет то же самое, что уже делается в XmlTraceListener?

Что я могу сделать, чтобы сделать CircularTraceListener поточно-ориентированным и эффективным?


person JustAMartin    schedule 15.03.2013    source источник
comment
Вы пробовали это в конфигурации по умолчанию с несколькими потоками и определили, что поведение блокировки вызывает проблему? Если вы хотите добавить синхронизацию, вам нужно сделать гораздо больше, чем просто заблокировать объявление этой переменной. Вам придется заблокировать каждый доступ к потоку.   -  person Jim Mischel    schedule 15.03.2013


Ответы (1)


Я думаю, что CircularTraceListener в корне ошибочен. Как вы заметили, есть static m_stream. Но, что еще хуже, когда вы создаете CircularTraceListener, он передает новый поток в базу (XmlWriterTraceListener). Это означает, что, хотя CircularTraceListener знает только о последнем созданном потоке, базовый класс потенциально использует один из многих потоков. И, конечно же, если CircularTraceListener будет удален, базовый класс удалит общий объект m_stream.

Я бы порекомендовал вам не основывать ничего на CircularTraceListener и начинать с нуля.

Обновить:

Мне гораздо больше повезло с такими вещами, как log4net и NLog для таких вещей, как циклическое ведение журнала.

person Peter Ritchie    schedule 15.03.2013