2014-04-11 17 views
9

Po pierwsze, widziałem wiele odpowiedzi i wskazówek w innych tematach (najbardziej podobne: Log4Net: Multiple loggers), ale nie ma odpowiedniej odpowiedzi.Log4Net Multiple Loggers

Chcę mieć 2 programy rejestrujące z różnymi aplikacjami i ograniczać do każdego zapisu w dzienniku głównego. Jest to aplikacja Console. Cały kod poniżej:

using System; 
using System.Diagnostics; 
using System.Linq; 
using log4net; 

namespace Test_log4net 
{ 
class Program 
{ 
    static void Main(string[] args) 
    { 
     log4net.Config.XmlConfigurator.Configure(); 

     ILog logger = LogManager.GetLogger("Async"); 
     logger.Info("started async"); 
     Console.WriteLine("Logger: {0}", (logger as log4net.Core.LogImpl).Logger.Name); 
     Console.WriteLine("Appenders: {0}", string.Join(", ", (logger as log4net.Core.LogImpl).Logger.Repository.GetAppenders().ToList().Select(appendr => appendr.Name))); 


     ILog logger2 = LogManager.GetLogger("Sync"); 
     logger2.Info("started sync"); //changed: from logger -> to logger2 on 10/21/2014 
     Console.WriteLine("Logger: {0}", (logger2 as log4net.Core.LogImpl).Logger.Name); 
     Console.WriteLine("Appenders: {0}", string.Join(", ", (logger2 as log4net.Core.LogImpl).Logger.Repository.GetAppenders().ToList().Select(appendr => appendr.Name))); 

     Console.ReadKey(); 
    }  
} 
} 

I plik App.config:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
<configSections> 
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/> 
</configSections> 
<startup> 
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> 
</startup> 
<log4net> 
    <root> 
     <level value="All"/> 
    </root> 

    <appender name="FileInfoAppenderA" type="log4net.Appender.RollingFileAppender"> 
     <file value="D:\\temp\\AsyncTest.log"/> 
     <filter type="log4net.Filter.LevelRangeFilter"> 
      <levelMin value="DEBUG"/> 
      <levelMax value="FATAL"/> 
     </filter> 
     <appendToFile value="true"/> 
     <rollingStyle value="Size"/> 
     <maxSizeRollBackups value="10"/> 
     <maximumFileSize value="100MB"/> 
     <staticLogFileName value="true"/> 
     <datePattern value="yyyyMMdd"/> 
     <layout type="log4net.Layout.PatternLayout"> 
      <conversionPattern value="%d - %m%n"/> 
     </layout> 
    </appender> 

    <appender name="FileInfoAppenderS" type="log4net.Appender.RollingFileAppender"> 
     <file value="D:\\temp\\SyncTest.log"/> 
     <filter type="log4net.Filter.LevelRangeFilter"> 
      <levelMin value="DEBUG"/> 
      <levelMax value="FATAL"/> 
     </filter> 
     <appendToFile value="true"/> 
     <rollingStyle value="Size"/> 
     <maxSizeRollBackups value="10"/> 
     <maximumFileSize value="100MB"/> 
     <staticLogFileName value="true"/> 
     <datePattern value="yyyyMMdd"/> 
     <layout type="log4net.Layout.PatternLayout"> 
      <conversionPattern value="%d - %m%n"/> 
     </layout> 
    </appender> 

    <logger Name="Sync" additivity="false"> 
     <level value="INFO"/> 
     <appender-ref ref="FileInfoAppenderS"/> 
    </logger> 

    <logger Name="Async" additivity="false"> 
     <level value="INFO"/> 
     <appender-ref ref="FileInfoAppenderA"/> 
    </logger> 

</log4net> 
</configuration> 

A konsola wyświetli:

Logger: Async 
Appenders: FileInfoAppenderA 
Logger: Sync 
Appenders: FileInfoAppenderA 

pliki zostały utworzone, ale obaj są puste. Kiedy określić appenders root, takie jak:

<root> 
    <level value="All"/> 
    <appender-ref ref="FileInfoAppenderA"/> 
    <appender-ref ref="FileInfoAppenderS"/> 
</root> 

wtedy, konsola:

log4net:ERROR [RollingFileAppender] Attempted to append to closed appender named [FileInfoAppenderS] 
Logger: Async 
Appenders: FileInfoAppenderA, FileInfoAppenderS 
Logger: Sync 
Appenders: FileInfoAppenderA, FileInfoAppenderS 

I tylko w AsyncTest.log:

2014-04-11 17:26:58,142 - started async 
2014-04-11 17:26:58,151 - started sync 

Co robię źle?

UPD (21.10.2014): Z najnowszej dostępnej poprzez Nuget log4net Mam następujący wyjścia konsoli:

Logger: Async 
Appenders: FileInfoAppenderA 
Logger: Sync 
Appenders: FileInfoAppenderA 

I oba pliki (AsyncTest.log, SyncTest.log) są puste.

UPD (08/4/2015): Rozwiązanie polega na użyciu małych liter podczas ustawiania atrybutów dla wszystkiego w sekcji log4net. Tak więc powinienem zmienić następujące linie w pliku app.config:

...... 
<logger name="Sync" additivity="false"> 
...... 
<logger name="Async" additivity="false"> 
...... 

Uwaga różnica: atrybut "nazwa" jest pisany małymi literami.

+0

dla rozwiązania muszę przeczytać do końca pytania. małe litery. –

Odpowiedz

13

Masz kilka literówek na swoim przykładzie. Pierwszy z nich to nie zamknąć tag konfiguracji i dlaczego dostajesz tylko w jeden plik, to dlatego, że nazywają:

logger.Info("started async"); 

i po które zaskakująco zrobić:

logger.Info("started sync"); 

Będziesz nie zapisuję w drugim pliku, ponieważ faktycznie nie logujesz się do niego.

A w konsoli dostaję od kodu:

Logger: Async 
Appenders: FileInfoAppenderS, FileInfoAppenderA 
Logger: Sync 
Appenders: FileInfoAppenderS, FileInfoAppenderA 

Dla przyszłych informacji, zrobiłeś prawidłowo umieszczając addytywności false, ponieważ oznacza to, że drewno nie będzie dziedziczyć od głównego rejestratora.Jako o rachunku:

chcę mieć 2 rejestratory z różnymi appenders plików i ograniczyć każdy napisać do głównego rejestratora

ja tego nie rozumiem. Jeśli chcesz aby twoje rejestratory zapisywały do ​​tych plików, podczas gdy root logger posiadający append konsoli, po prostu usuń addytywność i zapisze do konsoli i własnych plików. Testowany i działa bardzo dobrze.

Przeczytałem twój komentarz. Teraz dodać kod, który używam i uzyskanie co trzeba:

class Program 
{ 
    static void Main(string[] args) 
    { 
     log4net.Config.XmlConfigurator.Configure(); 

     ILog logger = LogManager.GetLogger("Async"); 
     logger.Info("started async"); 
     Console.WriteLine("Logger: {0}", (logger as log4net.Core.LogImpl).Logger.Name); 
     Console.WriteLine("Appenders: {0}", string.Join(", ", (logger as log4net.Core.LogImpl).Logger.Repository.GetAppenders().ToList().Select(appendr => appendr.Name))); 


     ILog logger2 = LogManager.GetLogger("Sync"); 
     logger2.Info("started sync"); 
     Console.WriteLine("Logger: {0}", (logger2 as log4net.Core.LogImpl).Logger.Name); 
     Console.WriteLine("Appenders: {0}", string.Join(", ", (logger2 as log4net.Core.LogImpl).Logger.Repository.GetAppenders().ToList().Select(appendr => appendr.Name))); 

     Console.ReadKey(); 
    } 
} 

A app.config:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <configSections> 
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/> 
    </configSections> 
    <startup> 
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> 
    </startup> 
    <log4net> 
    <appender name="FileInfoAppenderA" type="log4net.Appender.RollingFileAppender"> 
     <file value="C:\\temp\\AsyncTest.log"/> 
     <filter type="log4net.Filter.LevelRangeFilter"> 
     <levelMin value="DEBUG"/> 
     <levelMax value="FATAL"/> 
     </filter> 
     <appendToFile value="true"/> 
     <rollingStyle value="Size"/> 
     <maxSizeRollBackups value="10"/> 
     <maximumFileSize value="100MB"/> 
     <staticLogFileName value="true"/> 
     <datePattern value="yyyyMMdd"/> 
     <layout type="log4net.Layout.PatternLayout"> 
     <conversionPattern value="%d - %m%n"/> 
     </layout> 
    </appender> 

     <appender name="FileInfoAppenderS" type="log4net.Appender.RollingFileAppender"> 
     <file value="C:\\temp\\SyncTest.log"/> 
     <filter type="log4net.Filter.LevelRangeFilter"> 
      <levelMin value="DEBUG"/> 
      <levelMax value="FATAL"/> 
     </filter> 
     <appendToFile value="true"/> 
     <rollingStyle value="Size"/> 
     <maxSizeRollBackups value="10"/> 
     <maximumFileSize value="100MB"/> 
     <staticLogFileName value="true"/> 
     <datePattern value="yyyyMMdd"/> 
     <layout type="log4net.Layout.PatternLayout"> 
      <conversionPattern value="%d - %m%n"/> 
     </layout> 
     </appender> 

    <root> 
     <level value="INFO"/> 
    </root> 

    <logger name="Sync" additivity="false"> 
     <level value="INFO"/> 
     <appender-ref ref="FileInfoAppenderS"/> 
    </logger> 

    <logger name="Async" additivity="false"> 
     <level value="INFO"/> 
     <appender-ref ref="FileInfoAppenderA"/> 
    </logger> 
    </log4net> 
</configuration> 

wersja log4net: 1.2.13.0 z .NET 4.0 Powiedz mi proszę jeśli masz to, czego chcesz.

+0

XMight, thx do powtórki. Literówki nie wpływają na aplikację, tylko mój post (w każdym razie - naprawiony). Odtworzyłem projekt z kodu, który wcześniej zamieściłem tutaj, a log4net 1.2.13.0 nie działa w ogóle - oba pliki są puste (pomimo przejścia do logger2.Info ("started sync");). Co więcej, tylko "FileInfoAppenderA" jest wymieniony w obu rejestratorach. I dla wyjaśnienia mojego celu: 1) potrzebujesz logger1 -> log do asyng.log TYLKO 2) potrzebujesz logger2 -> log do sync.log TYLKO. 3) Not logger1, logger2 nie powinien logować się do root logger (cokolwiek jest tam zarejestrowanego) – LaoR

+0

w końcu mam problem.) Będziesz się śmiał) Czy widzisz różnicę między moim " 'and yours' '? Tak, jest po prostu rozróżniana wielkość liter nazwa atrybutu "name! = Name". Dlatego moje rejestratory nie logowały się do odpowiednich plików i obie były puste. – LaoR

+0

Cieszę się, że znalazłeś problem;) – XMight

0

Konfiguracja ta pracował dla mnie:

<log4net> 
<root name="EventLog"> 
<level value="ALL"/> 
<appender-ref ref="EventLogAppender"/> 
</root> 

<logger name="FileLogger" additivity="false"> 
<level value="ALL" /> 
<appender-ref ref="RollingFileAppender" /> 

...appenders 
</logger> 

powodzenia!