Мы пытаемся настроить серверный процесс так, чтобы каждый раз, когда он получает запрос, он регистрировал этот запрос в НОВОЕ имя файла.
Процесс, как правило, однопоточный, но мы не можем гарантировать, что никакой другой поток где-нибудь в коде не будет иногда пытаться что-то записать в log4net.
То, что, казалось, работало, это:
В первый раз, когда мы получаем запрос, мы настраиваем FileAppender «PerRequest» следующим образом:
fileAppender = new FileAppender();
log.InfoFormat("Initializing log4net per request logging");
log4net.Layout.PatternLayout layout = new Layout.PatternLayout("%date %property{processid} %property{username} %-5level %logger - %message%newline");
fileAppender.Layout = layout;
layout.ActivateOptions();
fileAppender.AppendToFile = true;
fileAppender.Name = "PerRunLogger";
fileAppender.File = makeNewRequestLogName(); // Returns a unique filename (uses a Guid)
log.InfoFormat("Configured PerRequest logger to log to '{0}'", fileAppender.File);
fileAppender.ActivateOptions();
log4net.Config.BasicConfigurator.Configure(fileAppender);
Затем каждый раз, когда мы получаем новый запрос, мы делаем следующее:
fileAppender.File = makeNewRequestLogName();
log.InfoFormat("Configured PerRequest logger to log to '{0}'", fileAppender.File);
fileAppender.ActivateOptions();
В конце запроса мы «настраиваем» регистратор PerRequest для ведения журнала с одним именем файла, поскольку мы не смогли найти удовлетворительного способа его отключения.
Это работало довольно хорошо... Но при большой нагрузке мы начали замечать, что файл журнала «PerRequest» часто содержит огромные куски «отсутствующих» строк журнала. например что-то вроде этого:
2009-09-23 19:17:17,133 4332 hollingp DEBUG PostProcessInfrastructure.PostProcessRunner - Started post processing
* normal log lines here, omitted for brevity *
2009-09-23 19:17:36,414 4332 hollingp DEBUG PluginRegistry.PostProcessVersions.PostProcessPluginCacheVersion - About to run pub_GetPostProcessingVersion stored proc
*Normally lots of log lines here, but every now and then, NOTHING *
2009-09-23 19:17:37,742 4332 hollingp DEBUG PostProcessInfrastructure.PostProcessRunner - Finished post processing
Нет хорошего объяснения тому, что мы видим в файле журнала — нет пути кода (даже если выдается исключение), который объяснил бы «отсутствующие» строки журнала — что-то (на самом деле довольно много вещей ) должен был быть зарегистрирован в этом потоке между строкой в 19:17:36 и строкой в 19:17:37.
По общему признанию, вся эта техника немного хитрая, но мы не могли придумать другого способа сделать это.
Итак, первый вопрос: есть ли лучший способ достичь того, чего мы хотим?
Второй вопрос: кто-нибудь может объяснить, что может происходить? Подозрение в том, что необходимо выполнить некоторую безопасность/блокировку потоков, но где? Что нужно заблокировать, если это так?
Нет риска того, что другой процесс попытается войти в тот же файл, потому что, как указано в комментарии в коде, мы выделяем имя файла журнала с помощью GUID — нет никаких шансов, что другой процесс попытается войти в тот же файл. тот же файл... а другой нить? Мы не можем этого исключить.