Изменить уровень регистрации log4net программно

Это похоже на 650694, но ответ там не был принят, я не могу заставить эти предложения работать вообще, и я подозреваю, что я могу быть в несколько другой ситуации.

Я звоню log4net.Config.XmlConfigurator.Configure (). Но после этого момента в программе я хочу изменить порог регистрации на значение, известное только во время выполнения.

Из другого вопроса я попробовал:

((log4net.Repository.Hierarchy.Logger)mylogger.Logger).Level = log4net.Core.Level.Error;

а также:

var appender = new log4net.Appender.ColoredConsoleAppender();
appender.Layout = new log4net.Layout.PatternLayout(@"%date %-5level %message%newline");
appender.Threshold = log4net.Core.Level.Error;
appender.ActivateOptions();
log4net.Config.BasicConfigurator.Configure(appender);

но ни один из них, кажется, не имеет никакого эффекта: я все еще вижу операторы регистрации DEBUG и INFO на консоли.

Я догадываюсь, что я добавляю новый appender, который не влияет на appender, объявленный в конфигурации XML (который говорит ему печатать сообщения уровня DEBUG), но у меня пока нет никаких доказательств этого.

Я уже некоторое время копался в API log4net и просто не вижу этого. Есть что-то простое, что мне не хватает?

3.04.2009 22:18:12
Установка уровня Logger на «Error» должна предотвратить отладку или вывод информации от этого регистратора. Вы видите DEBUG и INFO для самого Logger, уровень ведения журнала которого вы меняете?
Eddie 3.04.2009 22:22:07
Это хороший момент: # 1, вероятно, только устанавливает порог для одного регистратора. Но № 2 выглядит так, как будто он должен быть глобальным.
Ken 3.04.2009 22:36:25
Да # 1 устанавливает только порог для отдельного экземпляра Logger, который вы изменяете, плюс любой Logger под ним в иерархии, который не имеет явно установленного уровня.
Eddie 3.04.2009 22:51:40
Я попытался перебрать все log4net.LogManager.GetCurrentLoggers () с # 1, и это тоже ничего не делает. И я все еще думаю, что # 2 выглядит так, как будто он должен быть глобальным.
Ken 3.04.2009 23:10:15
Не могли бы вы предоставить свою конфигурацию log4net, просто отредактируйте ее в конце своего вопроса?
Eddie 3.04.2009 23:16:38
8 ОТВЕТОВ

Наконец-то нашел рабочее решение, здесь .

Большие части были:

  • необходимо установить порог для всех регистраторов, в том числе для корневого регистратора «невозможно получить по имени»
  • нужно получить уровень из LevelMap иерархии

Большое спасибо Эдди за то, что он задал хорошие заостренные вопросы, которые привели меня к Google правильных слов. Я бы никогда не понял это один.

(Помимо: Repository, Hierarchy, Logger, RootLogger, LevelMap - я понятия не имел, что даже возможно сделать библиотеку журналов такой сложной. У нее есть около 20 уровней косвенного обращения, которые, я уверен, делают ее достаточно гибкой для всего, но делает практически невозможным выполнение простых действий, таких как «не регистрировать сообщения выше порога X». Гах!)

22
4.04.2009 00:24:29
Да, это сложнее, чем я мог себе представить! Хорошая ссылка. Мой ответ на вопрос 650694 работал для меня в нескольких приложениях, по крайней мере, с log4Net 1.2.10. Я не знаю, почему это не сработало для вас, но то, что вы нашли, основательно !
Eddie 4.04.2009 02:17:15
Похоже, что на данный момент ссылка мертва. Есть ли шанс, что кто-нибудь знает, где найти это сейчас, или он был сохранен, чтобы его можно было перенести сюда?
Larry Smith 13.06.2018 18:49:35

Есть простой способ сделать это:

LogManager.GetRepository().Threshold = Level.Info;

Более подробную информацию можно найти здесь .

8
18.02.2011 20:51:37
Это не изменило уровень ведения журнала после того, как ведение журнала уже было настроено.
Rob Levine 22.10.2012 08:54:38
Вы также должны сообщить ему, что конфигурация изменилась через RaiseConfigurationChanged.
The Muffin Man 11.08.2014 03:39:44

Ни одно из представленных здесь решений не помогло мне. Это не менялось во время выполнения

Вот что сработало для меня:

((log4net.Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Root.Level = Level.Debug;
((log4net.Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).RaiseConfigurationChanged(EventArgs.Empty);

Вы должны вызвать RaiseConfigurationChanged после внесения изменений в его конфигурацию.

91
27.03.2014 08:40:50
Ах, ответ, который я ищу. За что я последний раз проголосовал 4 года назад :)
stuartd 17.05.2018 14:46:20

Я искал тот же подход и обнаружил, что последняя версия NLog 3.2.0.0 дает ниже возможность изменить уровень ведения журнала во время выполнения.

 LogManager.GlobalThreshold = LogLevel.Debug;

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

0
27.05.2015 15:16:45
по умолчанию для LogManager.GlobalThreshold является LogLevel.Trace
seUser 27.05.2015 15:19:08

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

Затем я обнаружил, что в файле конфигурации элемент appender также указал пороговое значение. Поэтому, когда я хотел изменить уровень на «Отладка», когда для appender было установлено, например, «Предупреждать», он не принимал дополнительные сообщения, поскольку они были ниже порогового значения. Поэтому я удалил порог из конфигурации приложения и просто сохранил настройку уровня.

  <root>
    <level value="Warn" />
    <appender-ref ref="RollingFile" />
  </root>

Затем я использовал решение Кена для изменения уровня во время выполнения.

1
22.06.2015 18:19:47

Если это работает для кого-то, вот как я реализовал в своем веб-приложении конечную точку уровня переключения, предоставляемую через вызов API, чтобы я мог изменить уровень ведения журнала на лету.

public HttpResponseMessage Post([FromBody] string logLevel)
{
    var newLevel = ToggleLogging(logLevel);

    // Create your own response here.
    return newLevel;
}

И фактическая реализация

private Level ToggleLogging(string logLevel)
{

    Level level = null;

    if (logLevel != null)
    {
        level = LogManager.GetRepository().LevelMap[logLevel];
    }


    if (level == null)
    {
        level = Level.Warn;
    }

    ILoggerRepository[] repositories = LogManager.GetAllRepositories();

    //Configure all loggers to be at the same level.
    foreach (ILoggerRepository repository in repositories)
    {
        repository.Threshold = level;
        Hierarchy hier = (Hierarchy)repository;
        ILogger[] loggers = hier.GetCurrentLoggers();
        foreach (ILogger logger in loggers)
        {
            ((Logger)logger).Level = level;
        }
    }

    //Configure the root logger.
    Hierarchy h = (Hierarchy)LogManager.GetRepository();
    Logger rootLogger = h.Root;
    rootLogger.Level = level;

    return level;
}
1
15.03.2019 23:34:50

В моем случае у меня были разные уровни по умолчанию для разных аппендеров, но я хотел переопределить их, если приложение находилось в подробном режиме.

Я использовал следующее:

var log4NetHierarchy = (log4net.Repository.Hierarchy.Hierarchy)LogManager.GetRepository();
foreach (var appender in log4NetHierarchy.GetAppenders())
{
    if (appender is AppenderSkeleton appenderSkeleton)
    {
        appenderSkeleton.Threshold = Level.All;
    }
}
log4NetHierarchy.RaiseConfigurationChanged(EventArgs.Empty);
0
28.08.2019 17:24:04

Ответ JeanT не работает с последней версией log4net.

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

foreach(var r in LogManager.GetAllRepositories()) { ((log4net.Repository.Hierarchy.Hierarchy)r).Root.Level = Level.Debug; ((log4net.Repository.Hierarchy.Hierarchy)r).RaiseConfigurationChanged(EventArgs.Empty); }

0
21.03.2020 20:34:51