2015-10-01 24 views
10

Devo configurare log4net per un nuovo progetto. Tutto funziona perfettamente bene, quando tengo tutte le mie informazioni nel file App.config. Voglio mettere la configurazione di log4net in un file di configurazione separato (prendere App1.config)Log4Net in un file di configurazione separato

Ecco il mio app.config perfettamente funzionante:

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

ho tolto tutto, tranne l'elemento <startup> dalla mia app. config e mettere questo nel mio 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> 

nella mia classe Program.cs, io chiamo la configurazione con l'assemblea del genere:

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

Ma non c'è alcun registro nei miei file quando utilizzo App1.config.

+2

Assicurarsi che il file 'App1.config' è segnato come "Copia in uscita" -> "Copia sempre" in Proprietà. – vendettamit

risposta

8

Utilizza il seguente come modello:

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

e posizionare il log4net log4net config nella config per esempio

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

Se si desidera guardare per le modifiche nel file è possibile farlo con la seguente classe (chiamata 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

Il problema con questa operazione - quando si utilizzano gli attributi di assembly per caricare log4net - è che non è più possibile" guardare "il file di configurazione del log per le modifiche - vedere http: // logging. apache.org/log4net/release/manual/configuration.html#dot-config – stuartd

+0

@stuartd puoi ancora guardarlo (ma non usare gli attributi), ma richiede un po 'di sforzo in più. Ho aggiornato la mia risposta per mostrare come è possibile farlo. – Ananke

0

Il file xml log4net deve iniziare con il tag <log4net>. Non dovresti includere gli elementi configSections o configuration.

+0

Ho modificato il mio file di configurazione ma non lo risolve –

+0

Provare a configurare il file in modo programmatico come questo 'using (FileStream fs = new FileStream (" app1.config ", FileMode.Open)) {XmlConfigurator.Configure (fs); } 'all'avvio della tua app –