Log4Net + Ilmerge

Im bayerischen könnte man Log4Net fast als ‚Log fei ned‘ (Bitte nicht loggen) interpretieren. Leider ist es manchmal auch wirklich so das Log4Net seinen Dienst verweigert. Eine gute Möglichkeit die Ursache zu analysieren ist z.B. den Sourcecode von Log4Net einzubinden und dann das ganze debuggen. Meistens sind es Konfigurationsfehler die das logging verhindern – aber manchmal …

Leider ist es häufig so, dass Projekte immer komplexer werden, je mehr sie wachsen. So auch bei uns. Wir haben im letzten Jahr einige WCF Service an den Start gebracht. Das funktioniert auch wunderbar. Für das logging verwenden wir immer Log4Net, da es sich eigentlich ganz gut bewährt hat. Nun wollen wir aber in unseren Produkten, die die WCF Services nutzen die WCF-Clients aber auch einfach aktualisieren können. Das Problem dabei ist, wenn so ein Client eine ganze Palette an abhängigen DLLs mit zieht (so z.B. log4net.dll). Daher verwenden wir Ilmerge um daraus eine Client DLL zu machen. So verhindern wir auch, dass falsche Versionen abhängiger DLLs vorhanden sind.

Zurück zum eigentlichen Problem: Ich habe für uns intern eine Anwendung geschrieben, die einen solchen WCF Client benutzt. Natürlich sollte aber meine Anwendung auch ein logging enthalten. Also wurde auch hier Log4Net eingebunden und konfiguriert. So weit so gut. Das logging klappt wunderbar. Meine Anwendung loggt und beim Aufruf des WCF Clients prüfen wir ob das logging bereits konfiguriert ist, damit es nicht ungewollt um konfiguriert wird.

1
2
3
4
if (!log4net.LogManager.GetRepository().Configured)  
{  
    // Use WCF-Client configuration
}

Wir nähern uns dem Problem mit großen Schritten. Mein Projekt ist auch in mehrere Assemblies aufgeteilt. Unter anderem die Hauptanwendung, die den WCF-Client referenziert und eine Assembly, die den Datenbankzugriff übernimmt. (Die anderen habe ich jetzt einfach mal weggelassen). Wie es beim Entwickeln so ist, passieren bei einem Select, Insert oder Update schon mal Fehler, aber auch hier ist ja der konfigurierte Logger eingebunden, somit sollte es ja kein Problem sein den Fehler im Log zu finden, oder?

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

Leider kann ich in meiner Assembly für den Datenbankzugriff so oft ich will etwas an Log4Net übergeben – nur es kommt nie was an. Da das ganze nun langsam produktiv eingesetzt werden soll, habe ich mich die Tage mit dem Problem nochmal eingehend beschäftigt und ich kann euch sagen: Die Lösung was so einfach – was das ganze umso ärgerlicher macht.

Die Hauptassembly referenziert die log4net.dll nicht, da diese ja durch den ‚zusammengefassten‘ WCF-Client zu Verfügung stand. Die Assembly für den Datenbankzugriff hat eine Referenz auf die log4net.dll. Und obwohl beide Assemblies indirekt die gleichen dll’s referenzierten (also selbe Version), war genau dass das Problem. In der Datenbankklasse konnte Log4Net den Logger nicht richtig initialisieren, weil er zwei Mal eine log4net.dll gefunden hat. Und schon wird einfach nichts mehr gelogged.
Lösung war dann auch einfach: log4net.dll nicht mehr mit dem WCF-Client über Ilmerge zusammenfügen und dafür in der Hauptassembly eine Referenz auf die log4net.dll verwenden – schon geht alles ohne Probleme.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert