2012-03-07 112 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();讀這一點,但是,我希望能夠通過一些更新它這種呼叫也是如此。我將接受來自Web服務的配置,一旦我擁有了set the new config(目前只有日誌級別,但我不排除其他事情可以在路上配置),我需要更新配置文件中的內容。

把所有的配置都放在一個文件中是非常方便的,但是,如果這使得配置變得更簡單,我可以在另一個文件中查找配置。

回答

5

因爲沒有官方的方法可以這樣做,所以我寫了一個方法,它使用xpath來定位要更改的元素,然後相應地進行更新。對於我需要做的事情來說,它已經足夠好用了,並且比「強大的文件讀取文件以及重新設置文件保存文件」方法更加優雅。

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 2016-05-04 13:00:14

0

對於log4net,這基本上是open issue - 不幸的是它還沒有解決。

+0

嗯,這是一個打擊。其他建議呢?仍然必須完成。 – Jon 2012-03-07 15:03:05

+0

最簡單的方法是創建一個log4netConfigurationChange對象,並支持可支持的可配置更改。反序列化時,它可能有一個函數來重新應用log4net更改。 – weismat 2012-03-07 15:25:51

相關問題