log4net – logujemy zdarzenia w aplikacji

Dzisiaj chciałbym poruszyć ważny element tworzenia aplikacji – logowanie zdarzeń. Odpowiednio przygotowane logi są często jedynym sposobem na zdiagnozowanie problemu w aplikacji, dlatego warto o tym pamiętać i z logowania korzystać.

Logowanie można przeprowadzić na wiele sposobów – ja chciałbym opisać przykład oparty na darmowej bibliotece log4net.

Temat ten podzieliłem na trzy części:

  • dzisiaj pokażę jak korzystać z log4net
  • w następnym poście pokażę, jak czytać/analizować logi
  • na koniec opiszę podstawową konfigurację log4net

To zaczynamy:
bibliotekę pobieramy ze strony: http://logging.apache.org/log4net/download.html. Z pobranego archiwum wypakowujemy plik: log4net.dll (incubating-log4net-1.2.10.zip\log4net-1.2.10\bin\net\2.0\release\log4net.dll) i wgrywamy go np. do katalogu “lib“. Następnie dodajemy referencję do tego pliku.

log4net1

W swoich aplikacjach korzystam z takiej klasy:

public class LogHelper
{
 static LogHelper()
 {
 var confFile = ConfigurationSettings.AppSettings.Get("log4net.config");
 var fi = new FileInfo(confFile);
 XmlConfigurator.Configure(fi);
 }

 public static ILog GetLog()
 {
 return LogManager.GetLogger("WebAppLog");
 }
}

Jak widać w pliku Web.config podajemy ścieżkę do pliku konfiguracyjnego, czyli:

<appSettings>
 <add key="log4net.config" value="conf\log4net.config"/>
</appSettings>

Brakuje jeszcze zawartości pliku log4net.config:

<log4net>
 <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender,log4net">
 <file value="logs\test_log.log" />
 <lockingModel type="log4net.Appender.FileAppender+MinimalLock"/>
 <param name="StaticLogFileName" value="true"/>
 <appendToFile value="true" />
 <param name="RollingStyle" value="Date"/>
 <param name="DatePattern" value="yyyy-MM-dd"/>
 <layout type="log4net.Layout.PatternLayout">
 <conversionPattern value="%date [%thread] %-5level %type.%method - %message%newline"/>
 </layout>
 </appender>

 <logger name="WebAppLog">
 <level value="ALL" />
 <appender-ref ref="RollingLogFileAppender" />
 </logger>
</log4net>

Podana konfiguracja zapisuje logi do pliku (może to być również baza danych, e-mail, konsola lub inne źródło) – file określa, do jakiego pliku będą zapisywane logi, a layout określa format zapisu logów.

Samo logowanie jest operacją niezwykle prostą:

LogHelper.GetLog().Info("My sample comments");

lub

catch (Exception ex)
{
 LogHelper.GetLog().Error("Error occurred!", ex);
}

log4net dostarcza kilka poziomów logowania:

  • Debug
  • Info
  • Warn
  • Error
  • Fatal

Nazwy poziomów logowania są bardzo czytelne i nie wymagają większego opisu.

Powyższy kod w logu zapisać może coś takiego:

2009-12-07 22:22:33,202 [8] INFO  LogForNetWebSample._Default.Page_Load - My sample comments
2009-12-07 22:22:33,292 [8] ERROR LogForNetWebSample._Default.Page_Load - Error occurred!
System.DivideByZeroException: Attempted to divide by zero.
at LogForNetWebSample._Default.Page_Load(Object sender, EventArgs e) in Default.aspx.cs:line 14

Jak widać log zawiera wiele cennych dla nas informacji – wiemy, kiedy i co się zdarzyło oraz w jakiej metodzie. Wiemy również, co działo się w aplikacji zanim wystąpił wyjątek.

Osobiście jestem zwolennikiem logowania jak największej ilości zdarzeń w naszej aplikacji – użytkownik wchodzi na stronę, klika button A, pobrano dane użytkownika, itp – jako poziom Debug. Przy przenoszeniu aplikacji na serwer produkcyjny możemy ograniczyć poziom logowania i logować jedynie logi z poziomu Error, Fatal czy Warn – bez zmiany kodu aplikacji!
log4net jest biblioteką bardzo elastyczną i posiada wiele parametrów konfiguracyjnych.

Oczywiście podczas logowania trzeba uważać, żeby nie zalogować danych poufnych – np. haseł.

Dzisiaj to tyle – zachęcam do zabawy z log4net i czytaniem logów – tylko uwaga – TO UZALEŻNIA!! :)

4 Responses to “log4net – logujemy zdarzenia w aplikacji”

  1. ProcentNo Gravatar Says:

    Polecam tworzenie statycznego loggera w każdej klasie osobno: static ILog _log = LogManager.GetLogger(typeof(CurrentClass)). Takie podejście stworzy całą hierarchię loggerów (wg przestrzeni nazw). Hierarcha owa ma przeolbrzymią zaletę: pozwala konfigurowac każdy logger z osobna W RUNTIME. Umiejętne operowanie plikiem konfiguracyjnym pozwoli wówczas wypisac w odpowiednie miejsce odfiltrowane, żądana informacje w formacie jaki nam odpowiada, bez zatrzymywania aplikacji! Na przykład badając zachowanie jakiejś klasy można włączyc poziom debug dla niej jednej, wyłączając wszystko inne – i mamy doskonaly wgląd w to co sie dzieje w tej jednej części systemu. Super sprawa. Tylko inicjalizując log4net zamiast .Configure() trzeba wywolac metode ConfigureAndWatch().


  2. dotnetomaniak.pl Says:

    log4net – logujemy zdarzenia w aplikacji | Łukasz Gąsior – Blog…

    Dziękujemy za publikację – Trackback z dotnetomaniak.pl…


  3. mbNo Gravatar Says:

    Pokażę pisze się przez “ż” – 2 razy w tekście jest przez “rz”. Popraw, proszę, ponieważ tekst bardzo fajny i szkoda go psuć błędami ortograficznymi :-)


  4. Łukasz GąsiorNo Gravatar Says:

    @mb – dzięki – jakoś się wkradło podstępnie ;)

    @Procent – jest to jedna z ciekawych/możliwych propozycji.

    Ja wolę tworzyć kilka Logerów w zależności od “modułu” aplikacji, np.:
    LogHelper.Dahsboard(), LogHelper.Payments(), LogHelper.Scheduler(), itp. Każdy z osobnymi ustawieniami – również logowane do osobnych plików.

    Chcąc analizować zachowanie jednej klasy można bardzo łatwo filtrować zawartość loga.

    Kwestia potrzeb i przyzwyczajenia :)


Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>