Log4Net RollingFileAppender не очищает буфер ввода IO с журналом с низким объемом - программирование
Подтвердить что ты не робот

Log4Net RollingFileAppender не очищает буфер ввода IO с журналом с низким объемом

Я размышляю над той же проблемой, что и HENRI COOK. Насколько мы можем судить по короткому описанию, как ошибка на Apache Jira.

Моя проблема заключается в том, что события регистрируются только при закрытии приложения (даже через несколько недель после события). Это происходит, когда объем ведения журнала очень низок. Я вижу это на Windows Server 2008 R2. Это не позволяет нам захватывать и реагировать на производственные ошибки.

Теперь приложение не является буферным. По умолчанию он также вызывает Flush() в базовом потоке каждый раз, когда добавляется сообщение.

Мой вопрос: ПОЧЕМУ это не промывка? И есть ли какое-либо средство, кроме программной очистки всех приложений? Вы считали бы пульсирующий appender жизнеспособным обходным решением?

Конфигурация appender:

<appender name="RollingErrorFileAppender" type="log4net.Appender.RollingFileAppender">
  <param name="File" value="D:\LogFiles\zzzz\xxxxxx__ERROR" />
  <param name="AppendToFile" value="true" />
  <param name="DatePattern" value="_yyyyMMddHH&quot;.log&quot;" />
  <param name="RollingStyle" value="Date" />
  <param name="StaticLogFileName" value="false" />
  <filter type="log4net.Filter.LevelRangeFilter">
    <param name="LevelMin" value="ERROR" />
    <param name="LevelMax" value="FATAL" />
  </filter>
  <layout type="log4net.Layout.PatternLayout">
    <param name="ConversionPattern" value="%utcdate{yyyy-MM-dd HH:mm:ss.fff},[%thread],%level,%logger,%m%n"/>
  </layout>
</appender>

ОБНОВЛЕНИЕ 2013-06-19

Я не смог воспроизвести поведение с любым кодом. Независимо от того, насколько я стараюсь, данные всегда записываются на диск немедленно. Однако было сделано важное замечание: если первая запись в файл больше 1 КБ, измененное время никогда не будет обновляться с последующей записью. Он будет обновляться только после закрытия файла со временем закрытия. Если, с другой стороны, первая запись является коротким однострочным, любая последующая запись будет обновлять модифицированное время. Такое поведение согласовано между log4net и ручным операциями ввода-вывода, между 32-битным WinXP и 64-битным W2k8R2, между .NET 2.0, 3.5 и .NET 4.0. Это еще не решает проблему, но, по крайней мере, теперь я могу понять странный шаблон изменения времени.

Спасибо, Роб

4b9b3361

Ответ 1

Поскольку вас беспокоит только уровень ошибок или хуже событий журнала, и этот трафик, к счастью, редки, я бы предложил настроить ваш appender для немедленного сброса.

<param name="ImmediateFlush" value="true" />

Это избавит вас от необходимости программно очищать приложение при каждом событии журнала (которое в любом случае не работало со звуком). Теперь, если вы хотите открыть свое приложение до большего количества уровней журналов, то, конечно же, сразу же сбрасывание всех событий может иметь большую проблему с производительностью.

ИЗМЕНИТЬ

Я добавил файл конфигурации и простую основную программу, которую я использовал для тестирования. Используя следующее, я вижу, что события журнала сразу же очищаются. Что касается вашего комментария, я также могу вычеркнуть строку ImmediateFlush из xml и увидеть значение по умолчанию true для очистки. Я сохранил строку в моем примере для явного указания желаемого поведения.

Основная основная прога:

class Program
{
    static void Main(string[] args)
    {
        ILog log = LogManager.GetLogger(typeof(Program));
        XmlConfigurator.Configure(new FileInfo(@"C:\temp\logTest.config"));

        string msg;
        while ((msg = Console.ReadLine()) != "Done")
        {
            log.Error(msg);
        }

        LogManager.Shutdown();
    }
}

logTest.config, на который ссылается главная прога:

<log4net>
    <appender name="RollingErrorFileAppender" type="log4net.Appender.RollingFileAppender">
        <param name="File" value="C:\temp\log" />
        <param name="AppendToFile" value="true" />
        <param name="DatePattern" value="_yyyyMMddHH&quot;.log&quot;" />
        <param name="RollingStyle" value="Date" />
        <param name="StaticLogFileName" value="false" />
        <param name="ImmediateFlush" value="true" />
        <filter type="log4net.Filter.LevelRangeFilter">
            <param name="LevelMin" value="ERROR" />
            <param name="LevelMax" value="FATAL" />
        </filter>
        <layout type="log4net.Layout.PatternLayout">
            <param name="ConversionPattern" value="%utcdate{yyyy-MM-dd HH:mm:ss.fff},[%thread],%level,%logger,%m%n"/>
        </layout>
    </appender>
    <root>
        <level value="INFO" />
        <appender-ref ref="RollingErrorFileAppender" />
    </root>
</log4net>