Подтвердить что ты не робот

Изменить программный уровень 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, и я просто не вижу его. Есть что-то простое, что мне не хватает?

4b9b3361

Ответ 1

Ни одно из этих решений, представленных здесь, не работало для меня. Он не менялся в время выполнения

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

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

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

Ответ 2

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

Большие куски были:

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

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

(Помимо этого: репозиторий, иерархия, регистратор, RootLogger, LevelMap - я и не подозревал, что это возможно даже для того, чтобы сделать библиотеку протоколирования этим комплексом. Она получила около 20 уровней косвенности, что, я уверен, делает ее достаточно гибкой для чего угодно, но делает почти невозможным выполнение простых вещей, таких как "не записывать сообщения над порогом X". Gah!)

Ответ 3

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

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

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

Ответ 4

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

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

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

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

Ответ 5

Если это работает для кого-то, вот как я реализовал в своем веб-приложении конечную точку уровня переключения, предоставляемую посредством вызова 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;
}

Ответ 6

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

 LogManager.GlobalThreshold = LogLevel.Debug;

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

Ответ 7

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

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

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);