2010-10-05 9 views
38

Jakie powinny być wydatki na rejestrację? Próbowałem ten przykładNLog performance

private class Person 
{ 
    private static Logger logger = LogManager.GetCurrentClassLogger(); 
    public string Name { get; private set; } 
    public Person(string name) 
     { 
      Name = name; 
      logger.Info("New person created with name {0}", name); 
     } 
    } 

    List<Person> people = new List<Person>(); 
    for (int i = 0; i < MAXTEST; i++) 
    { 
     people.Add(new Person(i.ToString())); 
    } 

Z MAXTEST wartości 100,500,1000, 5000

wyników w MAXTEST, NOLOGGING, Logging

100, 25ms, 186ms  
500, 33ms, 812ms  
1000, 33ms, 1554ms 
5000, 33ms, 7654ms 

prawda jeden prawdopodobnie nigdy zalogować tej nadmiernej ilości, ale czy to uderzenie wydajności można się było spodziewać?

Próbowałem również używając asyncwrapper w config

<target name="asyncFile" xsi:type="AsyncWrapper"> 
    <target name="file" xsi:type="File" fileName="${basedir}/log.txt" /> 
</target> 
+0

Co robi twój logger? –

Odpowiedz

68

Wystarczy tylko dodać atrybut async do elementu targets:

<targets async="true"> 
    <target name="asyncFile" xsi:type="AsyncWrapper"> 
     <target name="file" xsi:type="File" fileName="${basedir}/log.txt" /> 
    </target> 

zamiast

<targets> 
    <target name="asyncFile" xsi:type="AsyncWrapper"> 
     <target name="file" xsi:type="File" fileName="${basedir}/log.txt" /> 
    </target> 

Chyba nie zajrzałem tak daleko w dokumentację ;-)

Asynchronous cel wrapper pozwala kod rejestrator wykonać szybciej, przez kolejce komunikatów i przetwarzania je w osobnym wątku. Powinieneś zawinąć obiekty docelowe, które spędzają nietrywialną ilość czasu w swojej metodzie Write() z asynchronicznym obiektem docelowym, aby przyspieszyć rejestrowanie . Ponieważ rejestrowanie asynchroniczne jest dość powszechnym scenariuszem, NLog obsługuje notację skróconą dla zawijania wszystkich obiektów docelowych za pomocą AsyncWrapper. Wystarczy dodać async = "true" do elementu w pliku konfiguracyjnym . ... Twoje cele iść tutaj ...

Należy pamiętać, że używanie rejestrowanie transmisji asynchronicznej może powodować pewne wiadomości mają być odrzucane. To jest by design.

+4

Jaka była różnica? Czy możesz opublikować czas, aby porównać do pierwszego zestawu wyników? –

+24

skończyło się ~ 44ms dla 5000 z logowaniem. Pozdrawiam – Eric

+1

dziękuję za informację :) –

18

Dla każdego, kto potrzebuje stracić ten narzut i jest konfigurowany za pomocą kodu, to nie wygląda jak można ustawić wszystkie cele do asynchronicznych domyślnie - trzeba go definiować per-target:

// Set up asynchronous database logging assuming dbTarget is your existing target 
AsyncTargetWrapper asyncWrapper = new AsyncTargetWrapper(dbTarget); 
config.AddTarget("async", asyncWrapper); 

// Define rules 
LoggingRule rule1 = new LoggingRule("*", LogLevel.Trace, asyncWrapper); 
config.LoggingRules.Add(rule1); 

Uważaj, jeśli domyślnie, jeśli ustawisz w kolejce zbyt wiele elementów dziennika, po prostu upuścisz elementy - spójrz na OverflowAction = AsyncTargetWrapperOverflowAction.Block, aby powrócić do zachowania synchronicznego.

+0

Tego właśnie szukałem i dziękuję za heads up na OverflowAction. – YetAnotherDeveloper

+2

Należy również zachować ostrożność w stosunku do funkcji 'AsyncTargetWrapperOverflowAction.Block', jeśli podczas tworzenia rejestru są wykonywane kopie zapasowe, prawdopodobnie system jest już obciążony. Wymuszenie logowania do bloku dodatkowo utrudni działanie. Być może lepiej jest usunąć komunikaty dziennika, niż przestać przetwarzać żądania. –

+0

Piszę do docelowej bazy danych. W mojej sekcji '' 'target''' zaznaczyłem' '' async''' '' 'true'''. Czy nadal muszę napisać kod do mojej usługi internetowej, aby rejestrowanie async lub frameworku zajmowało się tym? – Sameer