niedziela, 27 października 2013

NLog, czyli logowanie błędów w .NET

Jakiś czas temu, opisywałem na moim blogu bardzo popularny logger dla .NET, o nazwie log4net. Sam log4net jest bardzo ok, i w zasadzie całkiem nieźle się sprawdza w swojej roli, jednak jak to mówią "lepsze jest wrogiem dobrego", a tym lepszym, a przynajmniej wygodniejszym narzędziem jest nlog.

Główne różnice, wady/zalety?
- NLog jest wygodniejszy. Co musimy zrobić? Ddokładamy bibliotekę do projektu,  za pomocą Packer Menager Console pobieramy plik konfiguracyjny, odkomentowywujemy ustawienia i... działa. W przypadku log4net trzeba pamiętać o sekcji inicjalizacji w 'global.asax' oraz odpowiednim ustawianiu pliku konfiguracyjnego
- zaawansowana konfiguracja -> tutaj akurat nie miałem okazji ostro sprawdzać obu narzędzi, jednak czytając różne blogi, zazwyczaj ludzie chwalą sobie intuicyjność oraz bardziej elastyczną konfigurację NLoga
- aktualizacje -> ost. aktualizacja nlog wyszła 09.10.2013, i jest w miarę często aktualizowany (projekt żyje), natomiast odnośnie log4net spotkałem się z opiniami, że ost. aktualizacja była ponad 5 lat temu
- autor nLog'a jkowalski.com na jednym ze spotkań Warszawskiej grupy .NET wykazywał niewielkią, ale jednak wyższą wydajność swojego rozwiązania nad rozwiązaniem log4net (i zdecydowanie wyższą nad standardowym System.Diagnostics).

Osobiście uważam, że nlog jest zwyczajnie wygodniejszy, oraz "nowszy", przez co niewiele, ale jednak lepszy niż log4net.

Całkiem fajnie opisał ten temat Maciej 'procent' Aniserowicz na swoim blogu.
Dobry post z porównaniem jest też na stackoverflow.com - log4net vs nlog
Opis NLog na codeproject.com


p.s. przykładowa konfiguracja, którą stoduje w klasie Bootstrapper projektu Nancy:
        protected override void ApplicationStartup(TinyIoCContainer container, IPipelines pipelines)
        {
            base.ApplicationStartup(container, pipelines);
            #region event logger (nLog)
            FileTarget fileTarget = CreateNlogFileConfiguration();
            SimpleConfigurator.ConfigureForTargetLogging(fileTarget, LogLevel.Info);
            LogAllRequests(pipelines);
            LogAllResponseCodes(pipelines);
            LogUnhandledExceptions(pipelines);
            #endregion
        }
        private static FileTarget CreateNlogFileConfiguration()
        {
            //SimpleConfigurator.ConfigureForTargetLogging(new AsyncTargetWrapper(new EventLogTarget()));
            FileTarget fileTarget = new FileTarget();
            fileTarget.Name = "CeidgCheckLogger";
            fileTarget.CreateDirs = true;
            fileTarget.Layout = "${date} ${level} ${callsite:className=true:includeSourcePath=false:methodName=true} ${message}";
            //fileTarget.FileName = @"${basedir}/logs/CeidgCheckNancy.${date:format=yyyy.MM.dd}.log"; //for catalog in solition
            fileTarget.FileName = @"D:/logs/CeidgCheckNancy/CeidgCheckNancy.${date:format=yyyy.MM.dd}.log";
            fileTarget.KeepFileOpen = false;
            fileTarget.Encoding = Encoding.UTF8;
            return fileTarget;
        }
        private void LogAllRequests(IPipelines pipelines)
        {
            pipelines.BeforeRequest += ctx =>
            {
                log.Info("Handling request {0} \"{1}\"",
                ctx.Request.Method, ctx.Request.Path);
                return null;
            };
        }
        private void LogAllResponseCodes(IPipelines pipelines)
        {
            pipelines.AfterRequest += ctx =>
            log.Info("Responding {0} to {1} \"{2}\"",
            ctx.Response.StatusCode, ctx.Request.Method,
            ctx.Request.Path);
        }
        private void LogUnhandledExceptions(IPipelines pipelines)
        {
            pipelines.OnError.AddItemToStartOfPipeline
            ((ctx, err) =>
            {
            log.ErrorException(string.Format("Request {0}\"{1}\" failed", ctx.Request.Method, ctx.Request.Path), err);
            return null;
            });
        }

Brak komentarzy:

Prześlij komentarz