【问题标题】:How can I programmatically update log4net configuration file?如何以编程方式更新 log4net 配置文件?
【发布时间】:2012-03-07 13:42:59
【问题描述】:

我目前在应用程序的 app.config 文件中有 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(目前只有日志级别,但我不排除其他可以配置的东西),我需要更新配置文件中的内容.

将所有配置放在一个文件中非常方便,但是,如果这样更简单,我愿意将配置放在另一个文件中。

【问题讨论】:

    标签: c# .net log4net


    【解决方案1】:

    由于没有官方方法可以做到这一点,我最终编写了一个方法,使用 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);
                }
            }
        }
    

    注意:我从here 获得的 SetAttribute 代码。

    【讨论】:

    • 太棒了!这就是我要找的。​​span>
    【解决方案2】:

    这基本上就是 log4net 的 open issue - 不幸的是它还没有解决。

    【讨论】:

    • 嗯,这是一个打击。那么其他建议呢?还是要完成。
    • 最简单的方法可能是拥有一个 log4netConfigurationChange 对象,该对象具有可串行化的支持配置更改。反序列化时,它可能具有重新应用 log4net 更改的功能。
    猜你喜欢
    • 2011-08-31
    • 1970-01-01
    • 2015-02-11
    • 2010-10-20
    • 1970-01-01
    • 1970-01-01
    • 2015-04-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多