Development Tip

프로그래밍 방식으로 log4net 로깅 수준 변경

yourdevel 2020. 12. 15. 19:53
반응형

프로그래밍 방식으로 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 로깅 문이 여전히 표시됩니다.

내 직감은 XML 구성에 선언 된 appender (디버그 수준 메시지를 인쇄하도록 지시)에 영향을 미치지 않는 새 appender를 추가하고 있지만 아직 이에 대한 증거가 없습니다.

나는 한동안 log4net API를 파헤 치고 있었는데, 나는 그것을 보지 못하고있다. 내가 놓친 간단한 것이 있습니까?


여기에 존재하는 이러한 솔루션 중 어느 것도 나를 위해 일하지 않았습니다. 런타임에 변경되지 않았습니다.

나를 위해 일한 것은 다음과 같습니다.

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

구성을 변경 한 후 RaiseConfigurationChanged를 호출해야합니다.


마침내 여기 에서 작동하는 솔루션을 찾았 습니다 .

큰 부분은 다음과 같습니다.

  • "이름으로 검색 할 수 없음"루트 로거를 포함하여 모든 로거에 임계 값을 설정해야합니다.
  • Hierarchy의 LevelMap에서 레벨을 가져와야합니다.

좋은 지적 질문을 해주신 Eddie에게 큰 감사를드립니다. 나는 이것을 혼자서 결코 이해하지 못했을 것입니다.

(제외 : Repository, Hierarchy, Logger, RootLogger, LevelMap-로깅 라이브러리를 이처럼 복잡하게 만드는 것이 가능할지 몰랐습니다. 약 20 개의 간접 레이어가 있으므로 모든 것에 대해 충분히 유연하게 만들 수 있습니다. 그러나 "임계 값 X를 초과하는 메시지를 기록하지 마십시오"와 같은 간단한 작업을 수행하는 것은 거의 불가능합니다. Gah!)


이를 수행하는 간단한 방법이 있습니다.

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

자세한 내용은 여기 에서 확인할 수 있습니다 .


이 모든 답변을 시도했지만 아무도 작동하지 않았습니다. 디버거에서 모든 로거 수준, 루트 수준, 임계 값이 지시대로 설정되었음을 알 수 있습니다. 그럼에도 불구하고 나는 내가 로깅하고 있던 롤링 파일에서 로그 레벨 변경을 보지 못했습니다.

그런 다음 구성 파일에서 appender 요소도 임계 값을 지정했음을 발견했습니다. 예를 들어 어 펜더가 경고로 설정되어있는 동안 레벨을 디버그로 변경하고 싶을 때 해당 어 펜더는 임계 값 미만이므로 추가 메시지를 선택하지 않았습니다. 그래서 어 펜더 구성에서 임계 값을 제거하고 레벨 구성 만 유지했습니다.

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

그런 다음 Ken의 솔루션을 사용하여 런타임에 레벨을 변경했습니다.


이것이 누군가에게 효과가 있다면, 여기에 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;
}

동일한 접근 방식을 찾고 있었고 최신 NLog 버전 3.2.0.0이 런타임에 로깅 수준을 변경하는 옵션을 제공한다는 것을 발견했습니다.

 LogManager.GlobalThreshold = LogLevel.Debug;

I think another approach might be to use LogManager.Configuration to overwrite the config settings using variables.


In my case I had different default levels for different appenders set the config, but wanted to overide them if the application was in verbose mode.

I used the following:

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

ReferenceURL : https://stackoverflow.com/questions/715941/change-log4net-logging-level-programmatically

반응형