poniedziałek, 17 listopada 2008

Inspektor Gadget, czyli śledzenie aplikacji cz. III

NLog - projekt o polskich korzeniach!

Tak, tak - nie tylko prezydent USA ma polskie korzenie! Ma je także NLog, gdyż został napisany przez polskiego programistę: Jarka Kowalewskiego. Ale nie dlatego chcę przedstawić tą bibliotekę jako wartą wypróbowania. Jest to biblioteka, która z pewnością dostarczy nam wszystkich niezbędnych mechanizmów potrzebnych do logowania zdarzeń w naszych aplikacjach. Niestety aktualnie autor nie uczestniczy tak aktywnie w projekcie jak kiedyś.

Zanim przystąpimy do implementacji gorąco zachęcam do zapoznania się z poprzednim artykułem poświęconym log4net, a także wstępniakiem do całej serii Wystarczy, że jako czytelnik poznasz zasadę rejestracji zdarzeń w log4net, gdyż w NLog jest ona analogiczna.

Zaczynamy przygodę z NLog

Pierwsze co musimy zrobić, to ściągnąć binarki z oficjalnej strony projektu. Ja do celów tego artykułu wykorzystam wersję nlog-1.0-setup.exe. Dzięki tej paczce oprócz samych plików dll otrzymamy także dokumentację i zbiór przykładów. Po instalacji dodajemy referencję do NLog.dll znajdującym się w folderze net-2.0. Następnie do projektu dodajemy plik konfiguracyjny NLog.config - plik ten zostanie automatycznie wczytany i NLog z niego pobierze sobie konfigurację. Ustawmy mu właściwość "Copy to Output Directory" na: "Copy always". Wyjście naszych logów - o priorytetach: Debug wzwyż - będziemy kierować na konsolę, dlatego do pliku konfiguracyjnego powinniśmy dodać wpis: "targets".

<?xml version="1.0" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <targets>
    <target name="console" xsi:type="Console"
            layout="${longdate}|${level}|${message}"/>
  </targets>
</nlog>

Cel mamy zdefiniowany, teraz pora na definicję zasad: tak jak ustaliliśmy wcześniej interesuje nas jedynie logowanie zdarzeń o priorytecie Debug i wyższych. Dodajmy więc definicję rules poniżej definicji targets:


<rules>
    <logger name="*" minlevel="Debug" writeTo="console" />
</rules>

Sama zasada wstawiania zdarzeń do logów jest praktycznie identyczna jak w log4net. Pierwsze co musimy zrobić to otrzymać instancję klasy Logger. Robimy to wywołując statyczną metodę klasy LoggerManager:


using System;
using NLog;
namespace NLogSample
{
    class Program
    {
        private static Logger logger = LogManager.GetCurrentClassLogger();
        static void Main(string[] args)
        {
            logger.Debug("Nasz pierwszy komunikat NLog!");
        }
    }
}

Po testowym uruchomieniu efekt powinien być podobny do poniższego:


nlog1


Ok, ale logowanie na konsolę to na pewno nie jest to, co docelowo chcielibyśmy osiągnąć. Spróbujmy zatem tym razem logować zdarzenia do pliku tekstowego: chyba jednej z czytelniejszej formy logowania zdarzeń (choć problem z filtrowaniem ich to inna sprawa). Aby nie niszczyć pracy jaką włożyliśmy w poprzedni przykład :-) nasza aplikacja do pliku tekstowego będzie logowała zdarzenia o priorytetach Error i wyższych, reszta niech idzie na konsolę, tak jak było to dotychczas. Dodajmy więc nową regułę do pliku konfiguracyjnego NLog.config:


<logger name="*" minlevel="Error" writeTo="file" />

Czas na dodanie wpisu konfiguracyjnego samego celu:


<target name="file" xsi:type="File"
            layout="${longdate} ${logger} ${message}"
            fileName="${basedir}/logfile.txt"
            keepFileOpen="false"
            encoding="iso-8859-2" />

Myślę, że poszczególne atrybuty są na tyle czytelne, że nie trzeba ich szerzej opisywać, ciekawskich odsyłam do dokumentacji :-) Po modyfikacjach plik NLog.config powinien wyglądać następująco:


<?xml version="1.0" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <targets>
    <target name="console" xsi:type="Console"
            layout="${longdate}|${level}|${message}"/>
    <target name="file" xsi:type="File"
            layout="${longdate} ${logger} ${message}"
            fileName="${basedir}/logfile.txt"
            keepFileOpen="false"
            encoding="iso-8859-2" />
  </targets>
  <rules>
        <logger name="*" minlevel="Debug" writeTo="console" />
        <logger name="*" minlevel="Error" writeTo="file" />
  </rules>
</nlog>

Czas na odrobinę kodu, przypominam dodajemy logowanie zdarzeń typu Error do pliku tekstowego:


using System;
using NLog;
namespace NLogSample
{
    class Program
    {
        private static Logger logger = LogManager.GetCurrentClassLogger();
        static void Main(string[] args)
        {
            logger.Debug("Nasz pierwszy komunikat NLog!");
            int a = 1;
            int b = 0;
            try
            {
                int c = a / b;
            }
            catch (Exception ex)
            {
                logger.Error(ex);
            }
        }
    }
}

Wystarczy nam teraz uruchomić aplikację i przekonać się, że w folderze ze skompilowanym programem został utworzony plik logu, w którym będą lądowały wyjątki przechwycone w blokach try-catch.
Oczywiście to dopiero ułamek potęgi biblioteki NLog. Oprócz jej niewątpliwej szybkości (sprawdzonej w kilku benchmarkach), należy odnotować mnogość celów dla zdarzeń, czyli:

• Class Description
• ASPNetTraceTarget 
• ChainsawTarget 
• ConsoleTarget 
• DatabaseParameterInfo
• DatabaseParameterInfoCollection
• DatabaseTarget
• DebuggerTarget
• DebugTarget
• FileTarget
• FormControlTarget 
• MailTarget
• MemoryTarget
• MessageBoxTarget
• MethodCallParameter
• MethodCallParameterCollection
• MethodCallTarget
• NetworkTarget
• NLogViewerTarget 
• NullTarget 
• RichTextBoxTarget
• TraceTarget 
• WebServiceTarget

Jako zadanie domowe mogę zachęcić Was do zalogowania zdarzeń do kilku innych wyjść.


0 komentarze: