Die Log4Net-Konfiguration in einer externen Datei funktioniert nicht

92

Wir verwenden log4net und möchten die Konfiguration in einer externen Konfigurationsdatei angeben (wie wir es in anderen Abschnitten getan haben). Zu diesem Zweck haben wir den Abschnitt log4net in der App.config in Folgendes geändert:

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

Und in der Log.Config-Datei (dasselbe Verzeichnis wie die App.config) haben wir:

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

Wenn wir die App ausführen, wird jedoch keine Protokolldatei erstellt (und keine Protokollierung durchgeführt). Es werden keine Fehlermeldungen an die Konsole ausgegeben.

Wenn wir den Inhalt der Datei Log.config wieder in die Datei App.config verschieben (wobei die erste Codezeile oben ersetzt wird), funktioniert dies wie erwartet. Irgendeine Idee, warum es in einer externen Datei nicht funktioniert?

Robert Wagner
quelle
Ich bin auf das gleiche Problem gestoßen - wir sind wahrscheinlich dem gleichen (fehlgeleiteten) Leitfaden gefolgt!
Zach Burlingame
14
Das mag ich an log4net nicht. Das Protokollierungsframework sollte meiner Meinung nach eines der solidesten Elemente Ihrer App sein - aber log4net scheint oft ein bisschen unübersichtlich zu sein.
UpTheCreek

Antworten:

112

Haben Sie das folgende Attribut in Ihrer AssemblyInfo.csDatei:

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

und Code wie diesen zu Beginn jeder Klasse, für die Protokollierungsfunktionen erforderlich sind:

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

Ich habe einen Blog-Beitrag mit dieser und anderen Informationen hier .

Mitch Wheat
quelle
17
Stellen Sie sicher, dass Sie beim Erstellen der Datei log4net.config die Eigenschaft "In Ausgabeverzeichnis kopieren" unter "Immer kopieren" festlegen.
E. van der Spoel
@mitchwheat Absolut gottähnlich, ich habe mit einer Ninject-basierten Lösung gekämpft, um genau das zu tun, was dies den ganzen Tag tut ... danke Mann!
Krieg
39

Es gibt einen offenen Fehler in dieser Angelegenheit. Log4Net unterstützt das Attribut configSource von Konfigurationselementen nicht. Um eine reine Konfigurationsdateilösung zu verwenden, verwenden Sie den log4net.Config-Schlüssel in appSettings.

Schritt 1: Fügen Sie die normale Definition des Konfigurationsabschnitts hinzu:

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

Schritt 2: Verwenden Sie den magischen Schlüssel log4net.Config in appSettings.

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

Schritt 3: Tragen Sie einen Patch bei, um die Behandlung von configSource zu korrigieren.

Niederschlagend
quelle
5
Ein Aufruf von log4net.Config.XmlConfigurator.Configure (); sollte dieses Problem überwinden, indem es configSource nicht liest
Greg Domjan
Das hat nichts für mich geändert. Ich habe das Problem noch nicht herausgefunden, aber ich werde versuchen, es weiterzuverfolgen.
Don Rolling
5
Es ist wichtig, die log4net-Konfigurationsdatei als "Kopie, wenn neuer" zu markieren. Wenn die Konfigurationsdatei nicht in den Ordner bin kopiert wird, funktioniert sie nicht.
Francisco Goldenstein
Dies funktionierte für mich unverändert und ich bevorzuge es gegenüber der akzeptierten Lösung, da einige meiner Bibliotheken in einer Web-App verwendet werden, in der die Protokollierung in einer separaten log4net.config konfiguriert ist, und manchmal in einer Stand-Along-App, in der die Protokollierung erfolgt konfiguriert in app.exe.config. Auf diese Weise ist alles in der Konfiguration statt in den Assembly-Informationen - ich möchte es nicht in log4net.config "fest codieren"
Danny
27

Der Schritt, der verpasst wurde, ist

log4net.Config.XmlConfigurator.Configure(); 

Dadurch wird die configSource verwendet. Stellen Sie sicher, dass Sie es einmal aufrufen, bevor Sie GetLogger () aufrufen.

Greg Domjan
quelle
Sie müssen dies nicht tun, wenn Sie die Lösung von Mitch Wheat verwenden.
Robert Wagner
4
@Robert: Sicher, obwohl die Lösung von Mitch Wheat eine harte Codierung der Konfigurationsdatei außerhalb der app.config erfordert - ich habe die ursprüngliche Frage gelesen, warum configSource nicht funktioniert, funktioniert es, wenn dieser zusätzliche Schritt befolgt wird.
Greg Domjan
Ich mag diesen Ansatz mehr, insbesondere weil ich einen Wrapper-Log-Handler erstelle, der intern log4net verwendet (der später ersetzt werden könnte), und dann in diesem Wrapper-Log-Handler immer log4net.Config.XmlConfigurator.Configure () aufrufe. Auf diese Weise kann jedes Projekt mit seiner eigenen app.config diesen Wrapper-Protokollhandler verwenden, ohne Assembler.cs ändern zu müssen
zheng yu
19

Stellen Sie sicher, dass Ihre Datei log4net.config mit den folgenden Eigenschaften festgelegt ist:

Aktion erstellen: Inhalt

In Ausgabeverzeichnis kopieren: Immer kopieren

Lewis Moten
quelle
10

Entweder verwenden,

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

oder nur,

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

In beiden Fällen sollte sich die Datei Log4Net.config im Ausgabeverzeichnis befinden. Sie können dies tun, indem Sie die Eigenschaften der Datei Log4Net.config im Solution Explorer festlegen. Aktion erstellen - Inhalt und in Ausgabeverzeichnis kopieren - Immer kopieren

Byju
quelle
Sie brauchen nicht das <configSections> -Tag für den ersten Fall
disklosr
2

Achten Sie auf dieses Problem ...

In meinem Fall war alles richtig konfiguriert. Das Problem ist, dass ich Web Deploy in Visual Studio 2013 verwendet habe, um die Site auf WinHost.com hochzuladen und die ACLs zurückzusetzen auf dem Server zurückzusetzen. Dies wiederum widerrief alle Berechtigungen für Ordner und Dateien - log4net konnte die Datei nicht schreiben.

Mehr dazu lesen Sie hier:

So verhindern Sie, dass Web Deploy / MSBuild die Serverberechtigungen durcheinander bringt

Ich habe das Support-Team dort gebeten, die ACLs zurückzusetzen, und dann hat log4net angefangen, Protokolle zu spucken. :) :)

Leniel Maccaferri
quelle
1

Angenommen, Sie hatten eine externe Konfigurationsdatei mit dem Namen log4net.config, die in Ihr Bereitstellungsverzeichnis kopiert wurde, können Sie sie folgendermaßen konfigurieren:

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());
        }
    }
}
JJ_Coder4Hire
quelle
1

Ich hatte das gleiche Problem, abgesehen davon

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

Im laufenden Projekt hatte ich auch die folgende Zeile in einem Referenzprojekt:

[assembly: log4net.Config.XmlConfigurator]

Wenn ich diese Zeile in den referenzierten Projekten entfernt habe, werden die Protokolle angezeigt.

Der Gast
quelle
1

Es ist auch möglich, einen Debug-Modus für zu aktivieren log4net. Fügen Sie dies in die Datei App.config ein:

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

und Sie erhalten zumindest Fehlermeldungen, aus denen Sie ableiten können, was genau schief gelaufen ist. In meinem Fall habe ich vergessen , einfach einstellen Copy to output directoryzu Copy Always.

Waka
quelle
0

@Mitch, Es stellt sich heraus, dass es eine Datei mit der Deklaration [Assembly: ...] gibt, die jedoch nicht über die ConfigFile-Eigenschaft verfügt.

Nachdem ich es hinzugefügt und auf Log.config verwiesen hatte, funktionierte es. Ich hätte gedacht, dass es wie alle anderen Konfigurationsabschnitte (dh AppSettings) funktionieren und externe Konfigurationsdateien ohne Änderung akzeptieren würde.

Wir haben nicht die zweite Aussage, die Sie erwähnt haben, da wir sie in einen globalen statischen Protokollanbieter einbinden.

Robert Wagner
quelle
0

In meinem Fall habe ich folgende Fehlermeldung erhalten:

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

Und log4net.configdie Datei war in Visual Studio 2017 Projekt, aber als ich die Datei einchecktebin\Debug Ordner konnte ich es nicht finden.

Mein ursprüngliches Montage-Setup war wie folgt:

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

Nach einiger Recherchezeit ändere ich es wie folgt und es funktioniert:

[assembly: log4net.Config.XmlConfigurator(ConfigFile = @"..\..\log4net.config", Watch = true)]
Maytham-ɯɐɥʇʎɐɯ
quelle
0
  1. Fügen Sie AssemblyInfo.cs Folgendes hinzu

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

  1. Stellen Sie sicher, dass log4net.config im Projekt enthalten ist
  2. In den Eigenschaften von log4net.config

Ändern Sie Kopieren in Ausgabeverzeichnis in Kopieren, falls neu

  1. Überprüfen Sie den Wert auf Protokollebene = "ALL".
e03050
quelle
0

Es ist auch erwähnenswert, dass eine Web-App im Stammverzeichnis und nicht im Ordner bin angezeigt wird. Stellen Sie daher sicher, dass Sie dort die Konfigurationsdatei ablegen.

Richard
quelle