06 January 2013 Debug, Log, logging, Trace Robert Muehsig

Im Framework gibt es zwei einfache Logging Komponenten: Trace & Debug – diese können allerdings tückisch sein, wenn man nicht genau versteht was die tun. Wofür und ob man diese einsetzen sollte schreib ich dann noch am Ende.

TL;DR: Trace und Debug verschwindet wenn die Konstanten “TRACE” und “DEBUG” während des Bauenes fehlen.

Kurzes Demoprogramm:

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");

            Trace.WriteLine("Hello Tracing-World!");

            Debug.WriteLine("Hello Debug-World!");
        }
    }

Der Output im Debug Mode ist recht eindeutig:

image

Die “Console” Ausgabe erfolgt natürlich in der Konsole, die anderen beiden Enden im Debug Output vom Visual Studio, wobei man auch andere “Listener” in der App.config anhängen kann.

Eigentlich Prima, oder? Es gibt auch einige Framework Komponenten die diese Art von Logging nutzen, daher kann es ja nicht so schlecht sein.

Keine Logs nach dem Release Build? Worauf man achten sollte bei Trace und Debug…

Trace und Debug sind sehr "einfache” Loggingmechanismen, daher war ich erst einmal verwundert, warum es nach dem Release-Build nicht “loggte”. Grund ist, dass beide Komponenten während des Builds darauf achten ob eine Konstante mitgegeben wird – genau das ist auch das tückische an diesen Komponenten:

Im Debug Modus (Standardeinstellung)

 image

Es werden hier zwei Konstanten angegeben “DEBUG” und “TRACE”. Wenn diese gesetzt sind, dann sieht der Code nach dem Kompilieren auch “richtig” aus (hier mit ILSpy den Code dekompiliert) und mit dem entsprechenden Listener wird auch ein Logfile erstellt.

 image

Entferne ich beide Konstanten, dann gibt es die beiden Zeilen auch nach dem Bauen nicht mehr:

image

image

Standard-Einstellung unter Release ist diese hier:

 

image

Warum verschwindet der Code?

Die Methoden die ich benutze wurden mit dem Conditional Attribute versehen:

    [Conditional("DEBUG")]
    public static void Write(string message)
    {
      TraceInternal.Write(message);
    }

  Natürlich kann ich dieses Attribute auch in meinem eigenen Code verwenden:

image

Konstanten via MSBuild angeben:

Natürlich kann man diese Parameter auch via MSBuild mitgeben:

msbuild traceanddebug.csproj /t:Rebuild /p:Configuration=Release /p:DefineCons
tants="DEBUG;TRACE"

Wann Trace und wann Debug?

Auf Stackoverflow gibt es eine nette Diskussion wann man was nehmen könnte. Wobei dort auch oft gesagt wird, dass Trace nach dem Release erhalten bleibt. Dies stimmt natürlich nur, wenn man die Einstellungen nicht verändert und die “TRACE” Konstante beim Bauen mit übergeben wird.

Sollte ich Trace und Debug überhaupt nehmen?

Die Logging Funktionalität ist recht “einfach” und bietet nicht die Vielfalt von Log4Net oder NLog. Wer allerdings eine einfache Bibliothek für dritte schreibt, der ist vielleicht ganz gut damit bedient, weil man keine anderen Komponenten braucht – so zwingt man niemanden zur Verwendung von Log4Net etc.

Ich persönlich bin ansonsten kein Fan davon, weil ich es etwas zu unberechenbar finde (“Ohhh… kein Log, weil das Buildscript die Logs rausgekickt hatte…”) und dafür Log4Net oder NLog in ihrer Flexibilität bevorzuge.

Source Code auf GitHub</strong> </p>


Written by Robert Muehsig

Software Developer - from Dresden, Germany, now living & working in Switzerland. Microsoft MVP & Web Geek.
Other Projects: KnowYourStack.com | ExpensiveMeeting | EinKofferVollerReisen.de

If you like the content and want to support me you could buy me a beer or a coffee via Litecoin or Bitcoin - thanks for reading!