2012-03-07 2 views
2

나는 현재 같은 응용 프로그램 'app.config 파일에서 log4net의 설정이 있습니다log4net 구성 파일을 프로그래밍 방식으로 업데이트하려면 어떻게해야합니까?

... 
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/> 
    </configSections> 
    <log4net> 
    <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender"> 
     <file value="logs\Service.log"/> 
     <appendToFile value="true"/> 
     <rollingStyle value="Date"/> 
     <datePattern value="yyyyMMdd"/> 
     <layout type="log4net.Layout.PatternLayout"> 
     <conversionPattern value="%date [%thread] %-5level %logger - %message%newline"/> 
     </layout> 
    </appender> 
    <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender"> 
     <layout type="log4net.Layout.PatternLayout"> 
     <conversionPattern value="%date [%thread] %-5level %logger - %message%newline"/> 
     </layout> 
    </appender> 
    <logger name="Data.WebService"> 
     <level value="ALL"/> 
     <appender-ref ref="ConsoleAppender"/> 
     <appender-ref ref="RollingLogFileAppender"/> 
    </logger> 
    <logger name="Data.Host.HostService"> 
     <level value="ALL"/> 
     <appender-ref ref="ConsoleAppender"/> 
     <appender-ref ref="RollingLogFileAppender"/> 
    </logger> 
    </log4net> 

은 내가 log4net.Config.XmlConfigurator.Configure();를 통해이 읽을 수있어, 그러나, 나는 몇 가지를 통해 업데이트 할 수 있도록하고 싶습니다 일종의 전화도. 나는 웹 서비스에서 설정을 수락 할 것이고, 일단 내가 set the new config (현재는 로그 수준이지만 다른 것들은 도로 ​​아래로 구성 할 수 없다는 것을 배제하지 않고있다.), 나는 설정 파일에 무엇이 있는지 업데이트 할 필요가있다.

모든 파일을 하나의 파일에 저장하는 것이 매우 편리합니다.하지만 설정이 간단하면 다른 파일에서 config 파일을 찾을 수 있습니다.

답변

5

공식적인 방법이 없기 때문에 xpath를 사용하여 요소를 찾아 변경 한 다음 그에 따라 업데이트하는 방법을 작성했습니다. 필자가해야 할 일에 충분히 잘 작동하고 무차별 한 "readinthefile tostringstreplaceplatertoextfilefromextesthensfiletothefile"접근법보다 더 우아합니다.

public enum Log4NetConfigItem 
    { 
     LOGLEVEL 
    } 

    public const string LOG4NET_CONFIGFILE = "log4net.config"; 

    public void UpdateConfiguration(Log4NetConfigItem which, object value) 
    { 
     // Load the config file. 
     XmlDocument doc = new XmlDocument(); 
     doc.Load(LOG4NET_CONFIGFILE); 
     // Create an XPath navigator for the document. 
     XPathNavigator nav = doc.CreateNavigator(); 

     try 
     { 
      XPathExpression expr; 

      // Compile the correct XPath expression for the element we want to configure. 
      switch (which) 
      { 
       default: 
       case Log4NetConfigItem.LOGLEVEL: 
        // Compile a standard XPath expression 
        expr = nav.Compile("/configuration/log4net/logger/level"); 
        break; 
      } 

      // Locate the node(s) defined by the XPath expression. 
      XPathNodeIterator iterator = nav.Select(expr); 

      // Iterate on the node set 
      while (iterator.MoveNext()) 
      { 
       XPathNavigator nav2 = iterator.Current.Clone(); 

       // Update the element as required. 
       switch (which) 
       { 
        default: 
        case Log4NetConfigItem.LOGLEVEL: 
         // Update the 'value' attribute for the log level. 
         SetAttribute(nav2, String.Empty, "value", nav.NamespaceURI, value.ToString()); 
         break; 
       } 
      } 

      // Save the modified config file. 
      doc.Save(LOG4NET_CONFIGFILE); 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine(ex.Message); 
     } 
    } 

    void SetAttribute(System.Xml.XPath.XPathNavigator navigator, String prefix, String localName, String namespaceURI, String value) 
    { 
     if (navigator.CanEdit == true) 
     { 
      // Check if given localName exist 
      if (navigator.MoveToAttribute(localName, namespaceURI)) 
      { 
       // Exist, so set current attribute with new value. 
       navigator.SetValue(value); 
       // Move navigator back to beginning of node 
       navigator.MoveToParent(); 
      } 
      else 
      { 
       // Does not exist, create the new attribute 
       navigator.CreateAttribute(prefix, localName, namespaceURI, value); 
      } 
     } 
    } 

참고 : SetAttribute 코드는 here에서 가져 왔습니다.

+0

좋아요! 이것은 제가 찾고있는 것입니다. – simmeone

0

이것은 기본적으로 log4net에 대해 open issue입니다. - 불행히도 아직 해결되지 않았습니다.

+0

글쎄, 그건 타격이야. 그럼 다른 제안들? 아직도 끝내야 해. – Jon

+0

가장 쉬운 방법은 지원되는 구성 변경 사항이있는 log4netConfigurationChange 객체를 사용하는 것입니다. 직렬화 해제 할 때 log4net 변경 사항을 다시 적용 할 수있는 기능이있을 수 있습니다. – weismat

관련 문제