Artykuł ten stanowi proste wprowadzenie dla każdego programisty, który zainteresowany jest stworzeniem logów dla swojej aplikacji. Pokazuje jak skonfigurować środowisko z biblioteką Nlog oraz dostosować logowanie do naszych potrzeb.

Nlog stanowi dosyć bogato rozbudowane narzędzie do tworzenia logów podczas działania aplikacji stworzonej w oparciu o platformę .NET (Silverlight, WPF, ASP.NET, Windows Phone).
Zacznijmy od utworzenia projektu aplikacji. Po uruchomieniu Visual Studio. Klikamy File, a następnie wybieramy New Project. W nowo otwartym oknie kolejno klikamy Visual C#, Windows, WPF Application. Przy etykiecie Name wpisujemy nazwę naszej aplikacji. Klikamy OK.
Przejdźmy do instalacji Nlog`a. Paczkę możemy zainstalować na dwa sposoby:
- (zalecane) Za pomocą NuGet Package Manager. W tym przypadku w menu Tools wybierz Extension Manager… W nowym oknie, po lewej stronie, wybieramy zakładkę Online Gallery, a następnie w prawym górnym rogu okna wpisujemy NuGet. Wśród wyników wyszukiwania wybieramy interesujący nas dodatek i klikamy przycisk z napisem Download.
Mając już zainstalowanego NuGet`a klikamy na solucję naszego projektu i wybieramy Manage NuGet Packages… Podobnie jak w poprzednim przypadku wybieramy Online po lewej stronie okna, wyszukujemy dodatek o nazwie Nlog,
Po instalacji należy utworzyć plik konfiguracyjny. Klikamy prawym przyciskiem myszy na nasz projekt i wybieramy Add -> New Item. Zobaczymy okno, jak na obrazku:

Do wyboru mamy:
- Empty Nlog Configuration File – pusty plik konfiguracyjny, zawiera tylko szkielet,
- NLog Configuration – Console – plik przeznaczony do wypisywania logów bezpośrednio na ekranie konsolki,
- NLog Configuration – File – pozwala na zapisywanie logów bezpośrednio do pliku tekstowego log.txt, znajdującego się w folderze bazowym aplikacji,
- NLog Configuration – LogReceiverService – logi wysyłane są na serwer przy pomocy WCF lub WebServices,
- NLog Configuration – Remote Log Viewer (log4net) – logi wysyłane są do specjalnych viewerów, takich jak Chainsaw lub Log4Net Viewer.
Bardzo istotną rzeczą jest przestawienie we właściwościach konfiga ustawienia kopiowania z wartości Do not copy na Copy always. Plik ten zawsze musi znajdować się w folderze aplikacji.

Składnia pliku konfiguracyjnego
<targets><targets />
Targety określają strumień wyjściowy logów. Tutaj decydujemy się, czy będziemy logować do bazy danych, konsoli, serwera lub pliku. Uzależnione jest to od parametru xsi:type. Jego wartość decyduje jakie kolejne parametry będą potrzebne dla danego trybu logowania. Przykładowo dla bazy danych konieczne będzie określenie dokładnego connection string`a, a dla pliku jego lokacji na dysku. Dla danego logowania możemy wybrać wiele wyjść:
<targets>
<target xsi:type="Database" name="DBTarget" connectionString="connectionString" dbPassword="pass" dbUserName="user"/>
<target xsi:type="File" name="FileTarget" createDirs="true" fileName="${shortdate}.txt" />
<target xsi:type="Mail" name="MailTarget" header="New Logs" to="mark@hotmail.com"/>
</targets>
Domyślne wartości parametrów
Dla dowolnego podzbioru targetów istnieje możliwość ustawienia wartości domyślnej dla danych parametrów target`u:
<targets>
<default-target-parameters xsi:type="File" fileName="${basedir}\Logs\${level}\${shortdate}.txt"/>
<target xsi:type="File" name="FileTrace" />
<target xsi:type="File" name="FileWarn"/>
<target xsi:type="File" name="FileError"/>
</targets>
<rules>
<logger name="AppNamespace.*" level="Trace" writeTo="FileTrace"></logger>
<logger name="AppNamespace.*" level="Warn" writeTo="FileWarn"></logger>
<logger name="AppNamespace.*" level="Error" writeTo="FileError"></logger>
</rules>
Layouty
W jednym z przykładów zastosowaliśmy layout postaci ${shortdate}. Layouty stanowią atrybuty podczas definiowania targetów. Określają format informacji, które będą logowane.
Przykłady:
| ${machinename} |
Nazwa komputera |
| ${shortdate} |
Sortowalna data typu yyyy-mm-dd |
| ${level} |
Poziom logowania |
| ${message} |
Logowana wiadomość |
Pełną listę szablonów możemy znaleźć na stronie projektu Nlog pod linkiem (http://nlog-project.org/wiki/Layout_Renderers).
<rules><rules />
Zasady związane z samym logowaniem. Tutaj określamy poziom logowania, źródło oraz target, który wykorzystamy. Poziomy tworzą następującą hierarchię:

Poziomy logowania:
- Trace – najbardziej szczegółowy poziom logowania. Powinien być używany tylko i wyłącznie dla programistów. Logi o tym poziomie nigdy nie powinny być widoczne dla użytkownika systemu.
- Debug – szczegółowy poziom logowania, bardziej ogólny niż Trace. Jak sama nazwa wskazuje, stosowany podczas debugowania. Nie powinien być dostępny poza developmentem.
- Info – uogólniony poziom. Logi informacyjne, będące już w środowiskach live. Należy poważnie rozważyć, czy logi te powinny na pewno znajdować się na tym poziomie, czy debug.
- Warn – ostrzeżenia, nie wnoszące żadnych poważnych informacji. Logi dotyczące problemów, które mogą być naprawione w bardzo krótkim czasie.
- Error - błędy aplikacji, wymagające natychmiastowej poprawy lub refactoringu.
- Fatal – bardzo poważne błędy, mogące powodować, że np. aplikacja lub system w ogóle nie działają.
Parametr name definiuje źródło logowania. WriteTo określamy za pomocą którego target będziemy logować. Ustawienie parametru final na true powoduje, że dalsze reguły, związane ze źródłem, z którego aktualnie logujemy będą pomijane.
Przykłady:
<rules>
<logger name="AppNamespace.MainWindow.xaml.cs" level="Error" writeTo="MailTarget"></logger>
<logger name="AppNamespace.Database" levels="Debug,Trace" writeTo="DBTarget"></logger>
<logger name="AppNamespace.*" minlevel="Info" maxlevel="Warn" writeTo="FileTarget" final="true"></logger>
</rules>
Plik konfiguracyjny może zostać podzielony na wiele części (wiele plików o mniejszej zawartości kodu). W takim przypadku konieczne jest stworzenie jednego, głównego pliku *.config, do którego będziemy importować wszystkie podkonfingi znajdujące się w systemie:
<nlog autoReload="true" ... >
<include file="${basedir}/Logs/DevelopersLogs/${shordate}"/>
<include file="${basedir}/Logs/Warns/${shortdate}"/>
<include file="${basedir}/Logs/Errors/${shortdate}"/>
<nlog />
autoReload powoduje, że każdorazowa zmiana w którymkolwiek z załączonych plików spowoduje przeładowanie całej konfiguracji Nlog`era.
Definiowanie zmiennych
W pliku konfiguracyjnym mamy możliwość deklarowania własnych zmiennych i przypisywania do nich wartości:
<variable name="sciezkaDoZapisu" value="${basedir}/Logs/${shortdate}.txt"/>
<targets>
<target xsi:type="File" name="FileTarget" fileName="${sciezkaDoZapisu}"/>
</targets>
Logowanie
Do logowania konieczne jest odwołanie się do przestrzeni nazw NLog. Logerra inicjujemy odwołując się do statycznej metody klasy LogManager:
Logger log = LogManager.GetLogger("MainWindow");
Zazwyczaj loggery tworzy się jako statyczne zmienne, gdzie dla każdej klasy przypisany jest jeden logger, dlatego częściej praktykowany jest zapis:
private static Logger log = LogManager.GetCurrentClassLogger();
Logowanie:
// 1 możliwosc logowania
logger.Info("logowanie na poziomie Info");
// 2 mozliwosc logowania
logger.Log(LogLevel.Info, "logowanie na poziomie info");