3 Stimmen

Trace-Methoden zu System.Diagnostics.TraceListener hinzufügen

Ich habe eine von System.Diagnostics.TraceListener abgeleitete Log-Klasse wie folgt geschrieben

public class Log : TraceListener

Dies fungiert als Wrapper für Log4Net und ermöglicht die Verwendung von System.Diagnostics Tracing wie folgt

Trace.Listeners.Clear();
Trace.Listeners.Add(new Log("MyProgram"));
Trace.TraceInformation("Program Starting");

Es gibt einen Antrag auf Hinzufügung zusätzlicher Verfolgungsebenen neben den Standardverfolgungsebenen (Fehler, Warnung, Information).

Ich möchte, dass dies der System.Diagnostics.Trace hinzugefügt wird, damit es wie folgt verwendet werden kann

Trace.TraceVerbose("blah blah");
Trace.TraceAlert("Alert!");

Gibt es eine Möglichkeit, dies mit einer Erweiterungsklasse zu tun? Ich habe versucht

public static class TraceListenerExtensions
{
     public static void TraceVerbose(this Trace trace) {}
}

aber in der übergebenen Trace-Instanz wird nichts angezeigt :(

11voto

wageoghe Punkte 26872

Es ist zwar etwas spät, aber haben Sie schon einmal über die Verwendung von TraceSource nachgedacht? TraceSources geben Ihnen tatsächliche Objektinstanzen, die Sie verwenden können, um in System.Diagnostics zu protokollieren (was bedeutet, dass Sie sie mit einer Erweiterungsmethode erweitern könnten, wie Sie in Ihrer Frage vorschlagen). TraceSources werden normalerweise in app.config konfiguriert (ähnlich wie Sie log4net Logger konfigurieren würden). Sie können den Grad der Protokollierung steuern und welche Trace-Listener zuhören. Sie könnten also einen Anwendungscode haben, der gegen eine TraceSource programmiert ist, der etwa so aussehen könnte:

public class MyClassThatNeedsLogging
{
  private static TraceSource ts = 
          new TraceSource(MethodBase.GetCurrentMethod().DeclaringType.Name);
  //Or, to get full name (including namespace)
  private static TraceSource ts2 = 
          new TraceSource(MethodBase.GetCurrentMethod().DeclaringType.FullName);

  private count;

  public MyClassThatNeedsLogging(int count)
  {
    this.count = count;

    ts.TraceEvent(TraceEventType.Information, 0, "Inside ctor.  count = {0}", count);
  }

  public int DoSomething()
  {
    if (this.count < 0)
    {
      ts.TraceEvent(TraceEventType.Verbose, 0, "Inside DoSomething.  count < 0");
      count = Math.Abs(count);
    }

    for (int i = 0; i < count; i++)
    {
      ts.TraceEvent(TraceEventType.Verbose, 0, "looping.  i = {0}", i);
    }
  }
}

Sie können TraceSources auch unter einem beliebigen Namen erstellen (d.h. es muss nicht der Klassenname sein):

TraceSource ts1 = new TraceSource("InputProcessing");
TraceSource ts2 = new TraceSource("Calculations");
TraceSource ts3 = new TraceSource("OutputProcessing");

Wie bereits erwähnt, wird jede TraceSource in der Regel in der Datei app.config konfiguriert, zusammen mit dem Logging-Level und dem Listener, der die Ausgabe erhalten soll.

Für Ihre Erweiterungsmethode könnten Sie etwa so vorgehen:

public static class TraceSourceExtensions
{
  public static void TraceVerbose(this TraceSource ts, string message)
  {
    ts.TraceEvent(TraceEventType.Verbose, 0, message);
  }
}

Wenn Sie TraceSource weiter anpassen möchten (z. B. zusätzliche Ebenen hinzufügen), finden Sie in diesem Artikel eine gute Beschreibung, wie Sie das tun können:

http://msdn.microsoft.com/en-us/magazine/cc300790.aspx

Wenn Sie letztendlich log4net innerhalb Ihres TraceListeners verwenden (und damit benannte Logger, Logging-Levels usw. definieren), müssen Sie möglicherweise nicht viele TraceSources konfigurieren. Sie könnten sogar in der Lage sein, nur eine zu konfigurieren (deren Name bekannt wäre), oder Sie könnten eine programmatisch erstellen, sie auf "all" setzen und sie mit Ihrem spezifischen TraceListener verbinden.

Schließlich können Sie anstelle der Protokollierung über das statische Trace-Objekt auch über TraceSource-Instanzen protokollieren. Wenn eine TraceSource konfiguriert ist und ihr Name bekannt ist, kann eine gültige TraceSource (für die Protokollierung) überall wie folgt erstellt werden:

TraceSource ts = new TraceSource("logger");
ts.TraceEvent(TraceEventType.Information, 0, "Hello World!");
//Or, via your extension method
ts.TraceVerbose(TraceEventType.Verbose, 0, "Logged via extension method");

Möglicherweise gibt es bessere Möglichkeiten zu erreichen, was Sie versuchen zu erreichen, aber dies könnte Ihnen etwas zum Nachdenken über die Verwendung von TraceSource vs die statische Trace-Klasse geben.

-1voto

Fredrik Mörk Punkte 151006

Ihr Problem ist, dass Sie keine Erweiterungsmethoden hinzufügen können, die auf statische Klassen wirken. Der erste Parameter einer Erweiterungsmethode ist die Instanz, auf die sie wirken soll. Da die Trace Klasse statisch ist, gibt es keine solche Instanz. Sie sind wahrscheinlich besser dran, wenn Sie einen eigenen statischen Log-Wrapper erstellen, der die gewünschten Methoden bereitstellt, wie z.B. TraceVerbose :

public static class LogWrapper
{
    public static void TraceVerbose(string traceMessage)
    {
        Trace.WriteLine("VERBOSE: " + traceMessage);
    }
    // ...and so on...
}

Dies entkoppelt auch Ihren Protokollierungscode von dem tatsächlich verwendeten Protokollierungs-Framework, so dass Sie später von der Trace-Protokollierung zur Verwendung von log4net oder etwas anderem wechseln können, wenn Sie dies wünschen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X