The Artima Developer Community
Sponsored Link

.NET Buzz Forum
[Enterprise Library] NLog Trace Listener im Eigenbau

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
-

Posts: 1524
Nickname: nitronic
Registered: Jul, 2006

Norbert Eder works as a software architect.
[Enterprise Library] NLog Trace Listener im Eigenbau Posted: Jun 19, 2007 1:34 PM
Reply to this message Reply

This post originated from an RSS feed registered with .NET Buzz by -.
Original Post: [Enterprise Library] NLog Trace Listener im Eigenbau
Feed Title: Norbert Eder - Living .NET
Feed URL: http://feeds.feedburner.com/NorbertEder-Livingnet
Feed Description: Copyright (c)2005, 2006 by Norbert Eder
Latest .NET Buzz Posts
Latest .NET Buzz Posts by -
Latest Posts From Norbert Eder - Living .NET

Advertisement
Eventuell hat sich der werte Leser die Enterprise Library [1] bereits einmal genauer angesehen. Wenn nicht, dann möchte ich zuerst ein paar einführende Worte loswerden.

Die Enterprise Library besteht aus sogenannten Blocks. Jeder Block besitzt eine eindeutige Aufgabe. Beispielsweise gibt es den Logging und den Exception Handling Block. Der Vorteil besteht darin, dass es mit Hilfe der Blocks das Verhalten über die Konfiguration (App.config, Web.config, ...) gesteuert werden kann. Beispiel:

Bei Exceptions stellt sich die Frage, wie denn diese im Spezialfall zu behandeln sind. Sind sie für den User sichtbar, sollen sie geloggt werden, oder gar der schlimmste Fall: soll sie nicht behandelt werden? Die geworfenen Exceptions werden an den Exception Handling Block übergeben, welcher durch eine Konfigurationsdatei entsprechend eingerichtet wird. Im Nachhinein kann nun festgelegt werden, was mit bestimmten Exceptions passieren soll. Ebenso verhält es sich mit den anderen Blocks.

Beim Logging verhält es sich gleich. Durch die Konfiguration kann festgelegt werden, wohin geloggt werden soll. Hier stehen unterschiedlichste Möglichkeiten bereit: EventLog, Datenbank, Email, Flat File usw. In unserem Beispiel möchten wir allerdings alle geworfenen Exceptions via NLog aufzeichnen.

Sehen wir uns dazu allerdings das Grundgerüst an. Das Beispiel läuft als Konsolenanwendung und Instanziiert eine Klasse DoSomethingClass, welche eine einzige Methode ThrowAnException besitzt:
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling;

namespace ExceptionLoggingDemo
{
    public class DoSomethingClass
    {
        public void ThrowAnException()
        {
            try
            {
                int i = 0;
                i = 1 / i;
            }
            catch (Exception ex)
            {
                ExceptionPolicy.HandleException(ex, "DemoException");
                throw ex;
            }
        }
    }
}

Die Konsolen-Anwendung selbst sieht folgendermaßen aus:
using System;
using System.Collections.Generic;
using System.Text;

namespace ExceptionLoggingDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            new DoSomethingClass().ThrowAnException();
            Console.WriteLine("Exception thrown");
            Console.ReadKey();
        }
    }
}

Nun binden wir die Enterprise Library ein bzw. die Teile davon, die wir tatsächlich benötigen. Dabei handelt es sich um folgende Libraries:

- Microsoft.Practices.EnterpriseLibrary.Common
- Microsoft.Practices.EnterpriseLibrary.ExceptionHandling
- Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging
- Microsoft.Practices.EnterpriseLibrary.Logging

Bevor wir nun daran gehen, die Enterprise Library zu konfigurieren, erstellen müssen wir uns genauer ansehen, wie der Ablauf aussehen soll.

Grundsätzlich binden wir den Exception Handling Block ein. Dieser fängt unsere Ausnahmen auf. Hier müssen wir eine neue Exception Policy hinzufügen, damit unsere Exception auch aufgefangen wird (hier sind unterschiedliche Policies möglich und können somit auch unterschiedlich behandelt werden). Dieser Policy hängen wir einen Logging Block um. Hierbei ist schön zu sehen, dass die einzelnen Blocks sehr gut miteinander zusammenarbeiten. Durch diese Definition legen wir fest, dass auftretende Exceptions mitgeloggt werden sollen. Nun muss der Logging Block entsprechend konfiguriert werden. Es muss also angegeben werden, wohin die Daten geschrieben werden und wie diese formatiert werden sollen. Daraus ergeben sich zwei wichtige Bestandteile des Logging Blocks:

- Trace Listener
- Formatter

Der Trace Listener bekommt die zu schreibenden Daten übermittelt. Durch die Einbindung eines Formatters können diese Daten entsprechend formatiert werden, um besser lesbar bzw. einfacher zu verarbeiten sind. Als Formatter stehen ein TextFormatter und ein XmlFormatter zur Verfügung. Eigene Ableitungen sind an dieser Stelle natürlich möglich. Zudem wissen wir nun, an welcher Stelle wir ansetzen müssen: Wir benötigen einen CustomTraceListener.

Dazu wird ein eigenes Projekt erstellt, welches den benutzerdefinierten Listener enthalten wird. Nachfolgend der Sourcecode des Listeners:
[ConfigurationElementType(typeof(CustomTraceListenerData))]
public class NLogTraceListener : CustomTraceListener
{
    private LogLevel _logLevel = LogLevel.Info;

    public override void TraceData(
        TraceEventCache eventCache, 
        string source, 
        TraceEventType eventType, 
        int id, 
        object data)
    {
        if (data is LogEntry && this.Formatter != null)
        {
            switch (eventType)
            {
                case TraceEventType.Critical:
                    _logLevel = LogLevel.Fatal;
                    break;
                case TraceEventType.Error:
                    _logLevel = LogLevel.Error;
                    break;
                case TraceEventType.Information:
                    _logLevel = LogLevel.Info;
                    break;
                case TraceEventType.Warning:
                    _logLevel = LogLevel.Warn;
                    break;
                case TraceEventType.Verbose:
                    _logLevel = LogLevel.Debug;
                    break;
                default:
                    _logLevel = LogLevel.Info;
                    break;
            }

            this.WriteLine(this.Formatter.Format(data as LogEntry));
        }
        else
        {
            this.WriteLine(data.ToString());
        }
    }

    public override void Write(string message)
    {
        LogManager.GetCurrentClassLogger().Log(_logLevel, message);
    }

    public override void WriteLine(string message)
    {
        LogManager.GetCurrentClassLogger().Log(_logLevel, message);
    }
}

Insgesamt werden drei Methoden überschrieben (wobei ansich nur zwei Methoden tatsächlich benötigt werden):

- TraceData
- Write
- WriteLine

Wichtig sind zwei Dinge: Durch das Überschreiben der Methode TraceData kommen wir an den TraceEventType. Dieser gibt an, um welches Fehler-Level es sich handelt (Critical, Error, Warning, Info, ...). Dies benötigen wir, um es an NLog weitergeben zu können. Der Rest besteht ansich im Aufruf der Methode WriteLine unter Einbindung des zugewiesenen Formatters.

Schließlich muss noch eine App.config eingebunden werden. In dieser Konfigurations-Datei wird die Konfiguration der Enterprise-Library hinterlegt. Per rechter Maustaste auf die App.config kann die Enterprise Library Configuration gestartet werden, welche sich mittlerweile netterweise ins Visual Studio integriert. Zur Konfiguration müssen die Einträge für das Exception Handling und für das Logging hinzugefügt werden. Beim Logging verwenden wir unseren CustomTraceListener. Dazu ist eine Assembly anzugeben (unser separates Projekt). Zu beachten ist hier folgendes:



Die Enterprise Library kann sowohl signiert als auch unsigniert eingebundern werden. Wird die signierte Variante verwendet, muss auch die eigene Assembly signiert sein. Zudem muss (im Falle eines TraceListeners) die Klasse von CustomTraceListener abgeleitet sein und folgendes Attribut gesetzt haben:
[ConfigurationElementType(typeof(CustomTraceListenerData))]

Damit ist alles getan, um unseren eigenen TraceListener laden zu können.



Als Verbesserung könnte hier ein eigener Formatter erstellt werden, welcher die Daten in einer besser lesbaren Form in unseren NLogTraceListener schreibt.

Hier nun der Download des Beispiel-Projektes:
Download NLog Trace Listener Demo

[1] Download Enterprise Library 3.1 (May 2007)

Read: [Enterprise Library] NLog Trace Listener im Eigenbau

Topic: MCE - Community Treffen am 30.06.2007 Previous Topic   Next Topic Topic:

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use