2015-10-01 21 views
10

Tôi cần phải cấu hình log4net cho một dự án mới. Tất cả các công trình hoàn toàn tốt đẹp, khi tôi giữ tất cả các thông tin của tôi trong tập tin App.config. Tôi muốn đặt cấu hình của log4net trong một tập tin cấu hình riêng biệt (mất App1.config)Log4Net trong một tập tin cấu hình riêng biệt

Dưới đây là App.config của tôi làm việc một cách hoàn hảo:

<?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> 

Tôi đã gỡ bỏ tất cả mọi thứ trừ các yếu tố <startup> từ ứng dụng của tôi. cấu hình và đặt điều này trong app1.config tôi:

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

trong lớp Program.cs của tôi, tôi gọi là cấu hình với lắp ráp như thế:

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

Nhưng không có đăng nhập vào tệp của tôi khi tôi sử dụng App1.config.

+2

Đảm bảo file 'App1.config' được đánh dấu dưới dạng “Sao chép thành đầu ra” -> “Sao chép luôn luôn” trong Thuộc tính. – vendettamit

Trả lời

8

Sử dụng theo mẫu sau:

<?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> 

Và đặt của bạn log4net config trong log4net cấu hình ví dụ

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

Nếu bạn muốn xem những thay đổi trong file bạn có thể làm như vậy với các lớp sau (gọi 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

Sự cố khi thực hiện theo cách này - khi sử dụng các thuộc tính assembly để tải log4net - là không còn có thể 'xem' tệp cấu hình nhật ký cho các thay đổi - xem http: // logging. apache.org/log4net/release/manual/configuration.html#dot-config – stuartd

+0

@stuartd bạn vẫn có thể xem nó (nhưng không sử dụng các thuộc tính), nhưng nó đòi hỏi một chút nỗ lực. Tôi đã cập nhật câu trả lời của mình để cho thấy cách bạn có thể làm điều này. – Ananke

0

Tệp log4net xml của bạn phải bắt đầu bằng thẻ <log4net>. Bạn không nên bao gồm các yếu tố configSections hoặc configuration.

+0

Tôi đã thay đổi tệp cấu hình của mình nhưng không sửa được tệp –

+0

Thử định cấu hình tệp theo chương trình như thế này bằng cách sử dụng (FileStream fs = new FileStream ("app1.config", FileMode.Open)) {XmlConfigurator.Configure (fs); } 'khi khởi động ứng dụng của bạn –

Các vấn đề liên quan