2015-10-01 5 views
10

Мне нужно настроить log4net для нового проекта. Все работает отлично, когда я храню всю свою информацию в файле App.config. Я хочу поставить конфигурацию log4net в отдельном файле конфигурации (возьмите App1.config)Log4Net в отдельном файле конфигурации

Вот моя app.config работает отлично:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <configSections> 
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/> 
    </configSections> 
    <log4net> 
    <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender"> 
     <layout type="log4net.Layout.PatternLayout"> 
     <conversionPattern value="%date{ABSOLUTE} [%logger] %level - %message%newline%exception"/> 
     </layout> 
    </appender> 
    <appender name="FileAppender" type="log4net.Appender.FileAppender"> 
     <file value="C:\Logs\MylogText.txt"/> 
     <appendToFile value="true"/> 
     <lockingModel type="log4net.Appender.FileAppender+MinimalLock"/> 
     <layout type="log4net.Layout.PatternLayout"> 
     <conversionPattern value="%date{ABSOLUTE} [%logger] %level - %message%newline%exception"/> 
     </layout> 
    </appender> 
    <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender"> 
     <file value="C:\Logs\RollinglogText.txt"/> 
     <appendToFile value="true"/> 
     <rollingStyle value="Size"/> 
     <maximumFileSize value="10MB"/> 
     <maxSizeRollBackups value="5"/> 
     <staticLogFileName value="true"/> 
     <layout type="log4net.Layout.PatternLayout"> 
     <conversionPattern value="%date{ABSOLUTE} [%logger] %level - %message%newline%exception"/> 
     </layout> 
    </appender> 
    <root> 
     <level value="DEBUG" /> 
     <appender-ref ref="ConsoleAppender"/> 
     <appender-ref ref="FileAppender"/> 
     <appender-ref ref="RollingFileAppender"/> 
    </root> 
    </log4net> 
    <startup> 
     <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> 
    </startup> 
</configuration> 

Я удалил все, кроме <startup> элемента из моего приложения. конфигурации и поставить это в моем app1.config:

<log4net> 
    <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender"> 
     <layout type="log4net.Layout.PatternLayout"> 
     <conversionPattern value="%date{ABSOLUTE} [%logger] %level - %message%newline%exception"/> 
     </layout> 
    </appender> 
    <appender name="FileAppender" type="log4net.Appender.FileAppender"> 
     <file value="C:\Logs\MylogText.txt"/> 
     <appendToFile value="true"/> 
     <lockingModel type="log4net.Appender.FileAppender+MinimalLock"/> 
     <layout type="log4net.Layout.PatternLayout"> 
     <conversionPattern value="%date{ABSOLUTE} [%logger] %level - %message%newline%exception"/> 
     </layout> 
    </appender> 
    <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender"> 
     <file value="C:\Logs\RollinglogText.txt"/> 
     <appendToFile value="true"/> 
     <rollingStyle value="Size"/> 
     <maximumFileSize value="10MB"/> 
     <maxSizeRollBackups value="5"/> 
     <staticLogFileName value="true"/> 
     <layout type="log4net.Layout.PatternLayout"> 
     <conversionPattern value="%date{ABSOLUTE} [%logger] %level - %message%newline%exception"/> 
     </layout> 
    </appender> 

    <root> 
     <level value="DEBUG" /> 
     <appender-ref ref="ConsoleAppender"/> 
     <appender-ref ref="FileAppender"/> 
     <appender-ref ref="RollingFileAppender"/> 
    </root> 
    </log4net> 

в моем классе Program.cs, я называю конфигурацию сборки, как что:

[assembly: log4net.Config.XmlConfigurator(ConfigFile = "App1.config", Watch = true)]

Но в моих файлах нет, когда я использую App1.config.

+2

Убедитесь, что 'App1.config' файл помечен как «Копировать на вывод» -> «Копировать всегда» в свойствах. – vendettamit

ответ

8

Используйте следующие в качестве шаблона:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 

    <configSections>  
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/> 
    </configSections> 

    <log4net configSource="log4net.config"/> 

    <startup> 
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/> 
    </startup> 

</configuration> 

и упритесь log4net конфигурации в log4net конфигурации, например,

<log4net> 
    <!-- Configuration --> 
</log4net> 

Если вы хотите, чтобы следить за изменениями в файле вы можете сделать это с помощью следующего класса (назовем LoggingConfigurator.ConfigureLogging()):

public static class LoggingConfigurator 
{ 
    private const string DebugLoggingConfiguration = @"log4net.debug.config"; 

    /// <summary> 
    /// Configures the logging. 
    /// </summary> 
    /// <exception cref="System.Configuration.ConfigurationErrorsException">Thrown if the logging configuration does not exist.</exception> 
    [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "System.Console.WriteLine(System.String)")] 
    [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "System.Console.WriteLine(System.String,System.Object)")] 
    public static void ConfigureLogging() 
    { 
     try 
     { 
      string path = GetLogConfigurationPath(); 

      var fileInfo = new FileInfo(path); 

      if (fileInfo.Exists) 
      { 
       log4net.Config.XmlConfigurator.ConfigureAndWatch(fileInfo); 
       Console.WriteLine("Loaded logging configuration from: {0}", path); 
      } 
      else 
      { 
       var message = "Logging configuration does not exist: " + path; 
       Console.WriteLine(message); 
       throw new ConfigurationErrorsException(message); 
      } 
     } 
     catch (ConfigurationErrorsException ex) 
     { 
      Console.WriteLine("log4net is not configured:\n{0}", ex); 
     } 
    } 

    /// <summary> 
    /// Gets the path to the logging configuration file. 
    /// </summary> 
    /// <returns>The path to the log configuration file.</returns> 
    private static string GetLogConfigurationPath() 
    { 
     var path = GetPathFromAppConfig(); 
     var directory = Path.GetDirectoryName(path); 

     if (directory != null) 
     { 
      var debugPath = Path.Combine(directory, DebugLoggingConfiguration); 
      if (File.Exists(debugPath)) 
      { 
       return debugPath; 
      } 
     } 

     return path; 
    } 

    /// <summary> 
    /// Gets the log4net configuration path file from the app.config. 
    /// </summary> 
    /// <returns>The path to the log4net configuration file if found, otherwise <c>null</c>.</returns> 
    private static string GetPathFromAppConfig() 
    { 
     string appConfigPath; 

     var xml = LoadAppConfig(out appConfigPath); 
     var logSectionNode = GetSection(xml, "Log4NetConfigurationSectionHandler"); 

     if (logSectionNode == null || logSectionNode.Attributes == null) 
     { 
      return appConfigPath; 
     } 

     var attribute = logSectionNode.Attributes["configSource"]; 

     if (attribute == null || string.IsNullOrEmpty(attribute.Value)) 
     { 
      return appConfigPath; 
     } 

     // Otherwise return the path to the actual log4net config file. 
     return ToAbsolutePath(attribute.Value, appConfigPath); 
    } 

    /// <summary> 
    /// Gets the node for a configurations section from an application configuration. 
    /// </summary> 
    /// <param name="configuration">The <see cref="XmlDocument"/> representing the application configuration.</param> 
    /// <param name="type">The section type.</param> 
    /// <returns>The node for the section.</returns> 
    /// <exception cref="ArgumentNullException"><paramref name="configuration"/> is <c>null</c>.</exception> 
    /// <exception cref="ArgumentNullException"><paramref name="type"/> is <c>null</c>.</exception> 
    /// <exception cref="ArgumentException"><paramref name="type"/> is an empty string.</exception> 
    /// <exception cref="ConfigurationErrorsException">The section could not be found in the application configuration.</exception> 
    private static XmlNode GetSection(XmlDocument configuration, string type) 
    { 
     if (configuration == null) 
     { 
      throw new ArgumentNullException("configuration"); 
     } 

     if (type == null) 
     { 
      throw new ArgumentNullException("type"); 
     } 

     if (type.Length == 0) 
     { 
      throw new ArgumentException("'type' cannot be an empty string."); 
     } 

     // Get the name of the section from the type 
     const string configSectionFormat = @"/configuration/configSections/section[contains(@type,'{0}')]/@name"; 

     var configSectionPath = string.Format(CultureInfo.InvariantCulture, configSectionFormat, type); 
     var configSectionNode = configuration.SelectSingleNode(configSectionPath); 

     if (configSectionNode == null) 
     { 
      throw new ConfigurationErrorsException("App.config does not have a section with a type attribute containing: " + type); 
     } 

     // Get the section from the name discovered above 
     var sectionName = configSectionNode.Value; 
     var sectionNode = configuration.SelectSingleNode(@"/configuration/" + sectionName); 

     if (sectionNode == null) 
     { 
      throw new ConfigurationErrorsException("Section not found in app.config: " + sectionName); 
     } 

     return sectionNode; 
    } 

    /// <summary> 
    /// Loads the application configuration. 
    /// </summary> 
    /// <param name="appConfigPath">The path to the application configuration.</param> 
    /// <returns>The loaded application configuration as an <see cref="XmlDocument"/>.</returns> 
    /// <exception cref="ConfigurationErrorsException">The application configuration could not be loaded.</exception> 
    private static XmlDocument LoadAppConfig(out string appConfigPath) 
    { 
     try 
     { 
      var xml = new XmlDocument(); 
      appConfigPath = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile; 
      xml.Load(appConfigPath); 
      return xml; 
     } 
     catch (Exception ex) 
     { 
      throw new ConfigurationErrorsException("Could not load app.config.", ex); 
     } 
    } 

    /// <summary> 
    /// Converts a path to an absolute path. 
    /// </summary> 
    /// <param name="path">The path (can be absolute or relative).</param> 
    /// <param name="basePath">The base path (used for resolving absolute path).</param> 
    /// <returns>The absolute path</returns> 
    /// <exception cref="ArgumentException"><paramref name="basePath"/> does not contain a directory.</exception> 
    private static string ToAbsolutePath(string path, string basePath) 
    { 
     if (Path.IsPathRooted(path)) 
     { 
      return path; 
     } 

     var directory = Path.GetDirectoryName(basePath); 

     if (directory == null) 
     { 
      throw new ArgumentException("'basePath' does not contain a directory.", "basePath"); 
     } 

     return Path.GetFullPath(Path.Combine(directory, path)); 
    } 
} 
+0

Проблема с этим способом - при использовании атрибутов сборки для загрузки log4net - это то, что больше не возможно« смотреть »конфигурационный файл журнала для изменений - см. http: // logging. apache.org/log4net/release/manual/configuration.html#dot-config – stuartd

+0

@stuartd вы все равно можете смотреть его (но не используя атрибуты), но для этого требуется немного дополнительных усилий. Я обновил свой ответ, чтобы показать, как вы можете это сделать. – Ananke

0

Ваш файл log4net xml должен начинаться с тега <log4net>. Вы не должны включать configSections или элементы configuration.

+0

Я изменил свой файл конфигурации, но он не исправил его. –

+0

Попробуйте настроить файл программно, как этот 'using (FileStream fs = new FileStream (« app1.config », FileMode.Open)) {XmlConfigurator.Configure (fs); } 'при запуске вашего приложения –

Смежные вопросы