La configurazione di Log4Net nel file esterno non funziona


92

Stiamo usando log4net e vogliamo specificare la sua configurazione in un file di configurazione esterno (come abbiamo fatto con altre sezioni). Per fare ciò abbiamo modificato la sezione log4net in App.config in:

...
<section name="log4net" 
     type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
...
<log4net configSource="Log.config" />
...

E nel file Log.Config (stessa directory di App.config) abbiamo:

<log4net>
  <appender name="General" type="log4net.Appender.FileAppender">
    <file value="myapp.log" />
    <layout type="log4net.Layout.SimpleLayout" />
  </appender>
  <root>
    <appender-ref ref="General" />
  </root>
</log4net>

Tuttavia, quando eseguiamo l'app, non viene creato alcun file di registro (e non viene eseguita alcuna registrazione). Non ci sono messaggi di errore in uscita sulla console.

Se spostiamo nuovamente il contenuto del file Log.config in App.config (sostituendo la prima riga di codice sopra), funziona come previsto. Qualche idea sul perché non funzioni in un file esterno?


Ho riscontrato lo stesso problema: probabilmente abbiamo seguito la stessa guida (mal guidata)!
Zach Burlingame

14
Questo è ciò che non mi piace di log4net. Il framework di registrazione dovrebbe essere uno dei pezzi più solidi della tua app secondo me, ma log4net spesso sembra essere un po 'instabile.
UpTheCreek

Risposte:


112

Hai il seguente attributo nel tuo AssemblyInfo.csfile:

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

e codice come questo all'inizio di ogni classe che richiede funzionalità di registrazione:

private static readonly ILog log = 
LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

Ho un post sul blog contenente questa e altre informazioni qui .


17
Funziona, assicurati di creare il file log4net.config per impostare la proprietà "Copia nella directory di output" su "Copia sempre".
E. van der Spoel

@mitchwheat Assolutamente dio, ho combattuto con una soluzione basata su ninject per fare esattamente quello che fa tutto il giorno ... grazie amico!
Guerra

39

C'è un difetto aperto su questo problema. Log4Net non supporta l'attributo configSource degli elementi di configurazione. Per utilizzare una soluzione di file di configurazione puramente si utilizza la chiave log4net.Config in appSettings.

Passaggio 1: includere la definizione della sezione di configurazione normale:

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

Passaggio 2: utilizza la chiave magica log4net.Config in appSettings.

<appSettings>
      <add key="log4net.Config" value="log4net.simple.config" />
</appSettings>

Passaggio 3: contribuisci a una patch per correggere la gestione di configSource.


5
Una chiamata a log4net.Config.XmlConfigurator.Configure (); dovrebbe superare questo problema con la mancata lettura di configSource
Greg Domjan

Questo non ha cambiato nulla per me. Non ho ancora capito il problema, ma cercherò di dare seguito.
Don Rolling

5
È importante contrassegnare il file di configurazione di log4net come "copia se più recente". Se il file di configurazione non viene copiato nella cartella bin, non funzionerà.
Francisco Goldenstein

Questo ha funzionato per me così com'è e lo preferisco alla soluzione accettata perché alcune delle mie librerie vengono utilizzate in un'app Web in cui la registrazione è configurata in un log4net.config separato e talvolta utilizzata in un'app stand-along in cui si trova la registrazione configurato in app.exe.config. In questo modo è tutto nella configurazione invece che nelle informazioni sull'assembly - non voglio "codificarlo" in log4net.config
Danny

27

Il passaggio che è stato perso è

log4net.Config.XmlConfigurator.Configure(); 

questo farà sì che configSource venga utilizzato. Assicurati di chiamarlo una volta prima di chiamare GetLogger ();


Non è necessario farlo se si utilizza la soluzione di Mitch Wheat.
Robert Wagner

4
@Robert: Certo, anche se la soluzione di Mitch Wheat richiede la codifica del file di configurazione al di fuori di app.config - Ho letto la domanda originale era perché configSource non funziona, funziona se si segue questo passaggio aggiuntivo.
Greg Domjan

Mi piace di più questo approccio, soprattutto perché creo un gestore di log wrapper che utilizza internamente log4net (che potrebbe essere sostituito in seguito), quindi in questo gestore di log wrapper chiamo sempre log4net.Config.XmlConfigurator.Configure (). In questo modo, qualsiasi progetto con il proprio app.config potrebbe utilizzare questo gestore di log wrapper, senza la necessità di modificare assembler.cs
zheng yu

19

Assicurati che il tuo file log4net.config sia impostato con le seguenti proprietà:

Azione di costruzione: contenuto

Copia nella directory di output: Copia sempre


10

O usa,

<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
</configSections>
<appSettings>
<add key="log4net.Config" value="Log4Net.config" />
</appSettings>

o semplicemente,

log4net.Config.XmlConfigurator.ConfigureAndWatch(new System.IO.FileInfo("Log4Net.config"));

In entrambi i casi il file, Log4Net.config, dovrebbe trovarsi nella directory di output. Puoi farlo impostando le proprietà del file Log4Net.config in Esplora soluzioni. Crea azione - Contenuto e copia nella directory di output - Copia sempre


non è necessario il tag <configSections> per il primo caso
disklosr

2

Attenzione a questo problema ...

Nel mio caso tutto è stato configurato correttamente. Il problema è che ho utilizzato Web Deploy all'interno di Visual Studio 2013 per caricare il sito su WinHost.com e ha ripristinato gli ACL sul server. Questo a sua volta revocava tutte le autorizzazioni su cartelle e file: log4net non poteva scrivere il file.

Puoi leggere di più a riguardo qui:

Come impedire a Web Deploy / MSBuild di incasinare le autorizzazioni del server

Ho chiesto al team di supporto lì di reimpostare gli ACL e poi log4net ha iniziato a sputare i log. :)


1

Supponendo che tu abbia un file di configurazione esterno chiamato log4net.config che viene copiato nella tua directory di distribuzione, puoi configurarlo in questo modo:

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Reflection;

using log4net;

namespace MyAppNamespace {
    static class Program {
        //declare it as static and public so all classes in the project can access it
        //like so: Program.log.Error("got an error");
        public static readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(Program));

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main() {
             //configure it to use external file
            log4net.Config.XmlConfigurator.Configure(new Uri(Application.StartupPath + "\\log4net.config"));
            //use it
            log.Debug("#############   STARING APPLICATION    #################");


            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new FormMain());
        }
    }
}

1

Ho avuto lo stesso problema, oltre ad averlo

[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net")]

nel progetto in corso, avevo anche la seguente riga in un progetto di riferimento:

[assembly: log4net.Config.XmlConfigurator]

Quando ho rimosso questa riga nei progetti di riferimento, i registri iniziano a comparire.


1

È anche possibile attivare una modalità di debug per log4net. Inseriscilo nel file App.config:

 <appSettings>
      <add key="log4net.Internal.Debug" value="true"/>
 </appSettings>
 <system.diagnostics>
      <trace autoflush="true">
      <listeners>
           <add
             name="textWriterTraceListener"
             type="System.Diagnostics.TextWriterTraceListener"
             initializeData="link\to\your\file.log" />
      </listeners>
      </trace>
 </system.diagnostics>

e riceverai almeno messaggi di errore, dai quali puoi ricavare cosa è andato storto esattamente. Nel mio caso ho semplicemente dimenticato di impostare Copy to output directorya Copy Always.


0

@ Mitch, si scopre che esiste un file con la dichiarazione [assembly: ...], ma non aveva la proprietà ConfigFile.

Una volta aggiunto e indirizzato a Log.config, ha iniziato a funzionare. Avrei pensato che avrebbe funzionato come tutte le altre sezioni di configurazione (cioè AppSettings) e avrebbe accettato file di configurazione esterni senza modifiche.

Non abbiamo la seconda affermazione che hai citato, poiché la racchiudiamo in un provider di log statico globale.


0

Nel mio caso ho ricevuto questo messaggio di errore:

log4net: config file [C:\........\bin\Debug\log4net.config] not found.

E log4net.configil file era nel progetto Visual Studio 2017, ma quando ho controllato il file nella bin\Debugcartella non sono riuscito a trovarlo.

La mia configurazione di assemblaggio originale era così:

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

Dopo un po 'di tempo di ricerca, lo cambio come segue e funziona:

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

0
  1. aggiungere quanto segue a AssemblyInfo.cs

[assembly: log4net.Config.XmlConfigurator (ConfigFile = "Log4Net.config")]

  1. Assicurati che log4net.config sia incluso nel progetto
  2. Nelle proprietà di log4net.config

cambia Copia nella directory di output in Copia se più recente

  1. Doppio controllo del valore del livello di log = "ALL"

0

Vale anche la pena sottolineare che in un'app Web cerca nella directory principale, non nella cartella bin, quindi assicurati che sia lì che hai inserito il file di configurazione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.