2015-10-01 17 views
10

Potrzebuję skonfigurować log4net dla nowego projektu. Wszystko działa idealnie dobrze, gdy przechowuję wszystkie moje informacje w pliku App.config. Chcę umieścić konfiguracji log4net w oddzielnym pliku konfiguracyjnego (wziąć App1.config)Log4Net w osobnym pliku konfiguracyjnym

Tu pracuje mój app.config doskonale:

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

usunąłem wszystko z wyjątkiem elementu <startup> z mojej aplikacji. config i umieścić to w moim 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> 

w mojej klasie Program.cs wzywam konfigurację z zespołem tak:

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

Ale nie ma logowania w moich plikach, gdy używam App1.config.

+2

Zapewnienie 'App1.config' plik jest oznaczony jako "Kopiuj do wyjścia" -> "Kopiuj zawsze" we Właściwościach. – vendettamit

Odpowiedz

8

Użyj następującego jako szablonu:

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

i umieść log4net config w log4net config np

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

Jeśli chcesz obserwować zmiany w pliku można zrobić z poniższej klasie (wezwanie 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

Problem z tym, że robisz to w ten sposób - podczas używania atrybutów zespołu do załadowania log4net - jest to, że nie można już" oglądać "pliku konfiguracyjnego dziennika dla zmian - patrz http: // logowanie. apache.org/log4net/release/manual/configuration.html#dot-config – stuartd

+0

@stuartd nadal możesz go obejrzeć (ale nie używając atrybutów), ale wymaga to trochę dodatkowego wysiłku. Zaktualizowałem swoją odpowiedź, aby pokazać, jak możesz to zrobić. – Ananke

0

Twój plik xml log4net powinien rozpoczynać się od znacznika <log4net>. Nie należy włączać elementów configSections ani configuration.

+0

Zmieniłem mój plik konfiguracyjny, ale go nie naprawia –

+0

Spróbuj skonfigurować plik programowo, tak jak to używając 'FileStream fs = new FileStream (" app1.config ", FileMode.Open)) {XmlConfigurator.Configure (fs); } 'przy uruchomieniu twojej aplikacji –

Powiązane problemy