Hi Leute,
ich möchte in meine C# Anwendung Logging-Informationen reinbauen, welche ich jedoch im späteren Release nicht drinne haben möchte
Ich hatte mir überlegt mit #define log und #if log #endif Präprozessor-Anweisungen zu arbeiten, allerdings greifen diese ja nur immer pro Datei und ich müsste in jeder Datei beim Releas das #define log entfernen.
Wie regelt ihr sowas ?
Gruß
es gibt die deriktive DEBUG. diese gibt es im debug modus, im relesase aber nicht. Diese kannst du verwenden.
Gruß pdelvo
diese gibt es im debug modus, im relesase aber nicht. Nicht ganz. Per default ist sie im Release-Modus zwar ausgeschalten, aber sie lösst sich wieder einschalten bei den Projekt-Einstellungen unter "Erstellen".
Da gibt es übrigens auch die Trace-Konstante, für die sich die Logging-Informationen besser eignen sollten.
Ich würde#if TRACE
verwenden.
mfg
SeeQuark
Für solche Zwecke gibt es das System.Diagnostics.ConditionalAttribute.
Alternativ zu log4net: NLog
Wissensvermittler und Technologieberater
für .NET, Codequalität und agile Methoden
Die Produkte die ihr gepostet hat sehen ja sehr interessant aus, jedoch wunder ich mich, warum ich dort in den Tutorials die angesprochenen Präprozessor - Anweisungen nicht finde.
Der zusätzliche code der zum logging verwendet wird, hat doch eigentlich nichts im Release zu suchen, auch wenn er vielleicht keine Auswirkungen hat.
Oder machen die angesprochenen Produkte das irgendwie anders, dass der Code im Release nicht verwedet wird ?
Noch eine Frage:
wenn ich eine Funktion habe
public void Log(string message)
{
#if DEBUG
...
...
...
#endif
}
und diese dann im Quellcode verwende. Wird die Funktion dann im Release vollständig wegoptimiert (weil diese im Release ja lehr ist)
Gruß
Christoph
Wird die Funktion dann im Release vollständig wegoptimiert
Ja, wird Sie, wenn in solch einem Falle das ConditionalAttribute verwendet wird.
Der Compiler schmeißt auch selbständig bestimmte Methodenaufrufe raus. Z.B. wird aus
public void FooBar()
{
Debug.WriteLine("Bla");
MessageBox.Show("Bla");
}
im Release zu
public void FooBar()
{
MessageBox.Show("Bla");
}
Um auch im Release etwas loggen zu können, muss man dann in dem Fall mit Trace arbeiten, da Trace nicht im Release wegoptimiert wird.
Der zusätzliche code der zum logging verwendet wird, hat doch eigentlich nichts im Release zu suchen
Naja, gerade das ist doch der Kernpunkt. Kein Kunde bekommt eine Debugversion vorgelegt. Treten jetzt beim Kunden Fehler auf, ist es doch wichtig, das diese Stellen mit geloggt werden, sonst weis man doch gar nicht was passiert ist.
Ich logge z.B. fast alles mit. Und per log4net (nutze ich), kann man auch schön festlegen, was auch geloggt wird. Per default sind das bei mir Fehler und Warnungen. Meldet ein Kunde ein Fehler, wird das untersucht. Sind die Infos nicht ausreichend, wird beim Kunden der Loglevel auf Debug runtergefahren und gebeten, das der Kunde den Fehler erneut provoziert. Und meist dann weis ich wo es brennt.
[Edit]
Eine kleine Unklarheit korrigiert, mit dem bezug auf das ConditionalAttribute.
"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)
Das Verhalten des Loggers, wird in der config Datei von log4net festgelegt. Also, welcher Loglevel, in welche Datei, welche Appender, usw...
Vorteil ist daran, das man den bestehenden Sourcecode nicht anpacken muss.
Meintest du das, oder was anderes?
"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)
Hallo Zusammen,
warum einen externen Logger wie Log4Net (was ein Java Port ist) verwenden, wo das .NET Framework doch mit der Klasse TraceSource einen exzellenten Logger im Namensraum System.Diagnostics eingabut hat?
Doku zum .NET Tracing: TraceSource-Klasse (System.Diagnostics)
In meinem Falle, weil TraceSource erst ab dem 2.0 FW da ist, und das Projekt ursprünglich auf dem 1.1er entwickelt wurde.
Da ich auch lieber MS Sachen verwende als Komponenten von Drittanbietern, ist es natürlich eine Überlegung wert, bei Zeiten das Logging umzubauen.
Auch wenn es hier an dieser Stele nicht hingehört: Kann man auch eigene Appender für das .NET Tracing schreiben, so wie es unter log4net der Fall ist? Ich verwende nämlich eigene, die ich ungerne verwerfen würde.
"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)
Hallo,
muss mal den Thread wieder ausgraben. Ich wollte jetzt mal zum Testen auf das .NET Tracing umschwenken. Dabei stoße ich aber auf ein kleines Problem, wo ich noch keine Lösung gefunden habe.
Und zwar habe ich log4net zurzeit so konfiguriert, das die verschiedenen Loglevel (Debug, Info, Warn, Error, Fatal) auch in verschiedenen Dateien landen. Also immer {loglevel}.txt. Kann es sein, das das .NET Tracing das nicht unterstützt? Jedenfalls habe ich noch nichts gefunden darüber. Ich kann zwar TraceListener registrieren, die gelten dann aber für alle Meldungen. Wäre schade, wenn .NET das nicht unterstützt.
"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)
Hallo,
du kannst für jeden Level eine TraceSource erstellen und den SwitchValue entsprechend setzen. Hier ist ein gute Einführung darüber.
mfG Gü
Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.
"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"
Danke für den Link. Werde ich mir dann mal morgen genauer anschauen. Sieht aber vielversprechend aus.
"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)
Wer's extra groß (und extra mächtig) haben will kann sich mal die Microsoft Enterprise Library anschauen. Enterprise Library
Grüße
Flo
Blog: Things about Software Architecture, .NET development and SQL Server
Twitter
Google+
Je mehr ich weiß, desto mehr weiß ich was ich noch nicht weiß.
Ich denke das Framework von TheObjectGuy sollte hier nicht unerwähnt bleiben. Habe das seit ein paar Monaten im produktiven Einsatz und es bis jetzt nicht bereut die 3€ dafür ausgegeben zu haben.
@Rainbird
Ich hatte davor die hauseigenen Mitteln verwendet und auch wenn ich versuche so wenig "Fremdcode" wie möglich zu verwenden, so muss man bei TraceSource doch einiges selbst zusammenschnitzen (Stichwort RollingFileTraceListener) bis es so läuft wie man es braucht.
Wer dafür keine Zeit/Budget hat, ist mit (zB) dem von mir genannten Framework oder auch log4net sicher besser bedient.
"Eine wirklich gute Idee erkennt man daran,
dass ihre Verwirklichung von vorneherein ausgeschlossen erscheint."
(Albert Einstein)
So, ich hab mal was zusammengebastelt, was aber irgendwie nicht so läuft, wie ich mir es vorgestellt habe.
private void button1_Click(object sender, EventArgs e)
{
this.m_TS.Listeners.Remove("Default");
this.m_TS.Switch.Level = SourceLevels.All;
TextWriterTraceListener debugTrace = new TextWriterTraceListener("debug.txt");
debugTrace.Filter = new EventTypeFilter(SourceLevels.Verbose);
TextWriterTraceListener infoTrace = new TextWriterTraceListener("info.txt");
infoTrace.Filter = new EventTypeFilter(SourceLevels.Information);
this.m_TS.Listeners.Add(debugTrace);
this.m_TS.Listeners.Add(infoTrace);
this.m_TS.TraceEvent(TraceEventType.Verbose, 1, "Debug");
this.m_TS.TraceEvent(TraceEventType.Information, 2, "Information");
this.m_TS.Flush();
this.m_TS.Close();
}
So, läuft ja ganz schön, aber:
Im debugTrace landen jetzt beide Ausgaben, was ja laut Doku auch richtig ist, den SourceLevels.Verbose nimmt alles mit, was größer gleich TraceEventType.Verbose ist. Das will ich aber nicht 😃 Ich will das komplett getrennt.
Ich habe es mit verschiedenen TraceSources probiert, aber da kommt das gleiche bei raus. Kann man den Krams nicht komplett voneinander trennen?
"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)
Hi Khalid,
wenn ich mir so den Source-Level-Enum anschaue,
[Flags]
public enum SourceLevels
{
All = -1,
Off = 0,
Critical = 1,
Error = 3,
Warning = 7,
Information = 15,
Verbose = 31,
ActivityTracing = 65280,
}
dann kann man die ja bitweise kombinieren. Und die dort angegeben Stufen sind nicht nur jeweils in Bit sondern immer die Verknüpfung der jeweils niedrigsten Bits. (1, 3, 7, 15, 31 = 00001, 00011, 00111, 01111, 11111)
Wenn du also nur die zusätzlichen eines jeden Levels haben willst, kannst du vielleicht
SourceLevels.Verbose ^ SourceLevels.Information // = 10000
bzw.
SourceLevels.Information ^ SourceLevels.Warning // = 01000
nutzen um nur das jeweilige Bit zu setzen.
beste Grüße
zommi
Danke dir!
Genau das wars. So langsam wirds 😃 Muss nur noch die fehlenden TraceListener nachbauen...
"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)
Wer dafür keine Zeit/Budget hat, ist mit (zB) dem von mir genannten Framework oder auch log4net sicher besser bedient.
Ggf. kommt - neben der Funktionalität - ein weiterer Aspekt zum Tragen: Die unterstützten Plattformen. log4net ist eines der wenigen Frameworks, die überhaupt und mit vollem Umfang auf CF und Mono laufen.
Kann man log4net auch durch Sorcecode configurieren? Ich bin kein fan von conf Dateien.