Formatting trace output - c#

I'm using TextWriterTraceListener to log diagnostics messages to a text file. However I wan't also to log a timestamp of every trace message added. Is it possible to define a kind of formatter for the listener that would automatically add timestamps?
Currently I'm adding timestamps manually on every Trace.WriteLine() call but this isn't very comfortable.

I suggest you use Log4Net instead, which has a lot more customizability.
Alternatively you could write your own TraceListener implementation which put the timestamps on for you. You may even be able just derive from TextWriterTraceListener and override Write and WriteLine:
public override void Write(string x)
{
// Use whatever format you want here...
base.Write(string.Format("{0:r}: {1}", DateTime.UtcNow, x));
}
public override void WriteLine(string x)
{
// Use whatever format you want here...
base.WriteLine(string.Format("{0:r}: {1}", DateTime.UtcNow, x));
}
As noted in comments, this ends up with date duplication for TraceInformation, because that calls Write twice. Using a "proper" logging framework is definitely better.

I recently encountered similar situation and it looks like now we have a tool very much fit for the task, namely Essential Diagnostics. You set up a listener in app.config like in code below and then just place Essential.Diagnostics.dll into the same folder. NO RECOMPILING IS REQUIRED. You can use this with any applications that uses System.Diagnostics for tracing, even if you do not own the source. Isn't that marvelous?
<sharedListeners>
<add name="rollingfile"
type="Essential.Diagnostics.RollingFileTraceListener, Essential.Diagnostics"
initializeData="{ApplicationName}-{DateTime:yyyy-MM-dd}.log"
convertWriteToEvent="true"
template="{DateTime:yyyy-MM-dd HH:mm:ss.fff} {Message}{Data}"
/>
</sharedListeners>

You could write your own TextWriterTraceListener subclass which overrides the WriteLine methods, decorates the line, and then passes the decorated string to the base class implementation to do the actual output.

Or just add "DateTime" as a traceOutputOption.

Not really an answer to your question but have you considered just using log4Net?
You can configure it to add times etc, along with a vast amount of other useful functionality.

Consider using The Logging Application Block

Even though this is old and an answer has been accepted, I will throw in one more option. You can use the Ukadc.Diagnostics addon from codeplex. Among other things, it enables you to define custom formatting, similar to the formatting that you can define with log4net and NLog. It is a configuration-only dependency. That is, you configure the use of Ukadc.Diagnostics through the app.config file. There are no source dependencies (you continue to log via System.Diagnostics not through a special api). Having said that, there are some limitations that you should be aware of:
The formatting options currently implemented in Ukadc.Diagnostics really only work correctly when logging with TraceSources. When logging with Trace.Write and Trace.WriteLine the TraceEventCache object is not filled in and that is where most of the formatting objects get their information.
You must use a Ukadc.Diagnostics TraceListener (or a custom listener derived from the Ukadc.Diagnostics base TraceListener) to get the custom formatting to appear in your output. If you found a new super duper rolling file TraceListener, you will have to do some work to use it in conjunction with the Ukadc.Diagnostics formatting. This might be as difficult as reimplementing the listener in terms of the Ukadc.Diagnostics base TraceListener. Or it could be easier, if you could just create a new Ukadc.Diagnostics-based TraceListener that contains the super duper rolling TraceListener, formats the messages per Ukadc.Diagnostics, and then delegates to the contained listener's Write/WriteLine methods.

Related

C# Custom Logger - Best way to capture sending object

I am attempting to build (for learning purposes) my own event logger; I am not interested in hearing about using a non-.net frameworks instead of building my own as I am doing this to better understand .net.
The idea is to have an event system that I can write out to a log file and/or pull from while inside the program. To do this I am creating an LogEvent class that will be stored inside of a Queue<LogEvent>.
I am planning on using the following fields in my LogEvent class:
private EventLogEntryType _eventType //enum: error, info, warning...
private string _eventMessage
private Exception _exception
private DateTime _eventTime
What I am not sure is the best way to capture the object that caused the event to be called. I thought about just doing a private Object _eventObject; but I am thinking that is not thread safe or secure.
Any advice on how to best store the object that called the event would be appreciated. I am also open to any other suggestions you may have.
Thanks, Tony
First off, nothing wrong with writing your own. There are some good frameworks our there, but sometimes you reach the point where some bizarre requirement gets you rolling your own, I've been there anyway...
I don't think you should be using text messages. After doing this type of logging in several projects, I have come the the conclusion that the best approach is to have a set of event types (integer IDs) with some type of extra information field.
You should have an enum of LogEvetTypes that looks something like this:
public enum LogEventTypes
{
//1xxx WS Errors
ThisOrThatWebServiceError = 1001,
//2xxx DB access error
//etc...
}
This, from my experience will make your life much easier when trying to make use of the information you logged. You can also add an ExtraInformation field in order to provide event instance specific information.
As for the object that caused the event, I would just use something like typeof(YourClass).ToString();. If this a custom class you created, you can also implement a ToString override that will name sense in your logging context.
Edit: I am adding several details I wrote about in the comments, since I think they are important. Passing objects, which are not immutable, by ref to service methods is generally not a good idea. You might reassigne the same variable in a loop (for example) and create a bug that is near-impossible to find. Also, I would recommend doing some extra work now to decouple the logging infrastructure from the implementation details of the application, since doing this later will cause a lot of pain. I am saying this from my own very painful experience.

Function? Class?

I'm writing an app (C#) and at times I will need to log to the Windows event log. So the first thing that comes to mind is to write a function in my one and only class and call it when I need it. Something like this:
private void Write_Event_Log(string log, string source, string message, EventLogEntryType type, int eventid)
{
if (!EventLog.SourceExists(source))
EventLog.CreateEventSource(source, log);
EventLog.WriteEntry(source, message, type, eventid);
}
A colleague of mine asked, "why didn't you just create a new class for your event log writer?" So my question is, why would I? And what would this class even look like? And why would I need it when my function works nicely? ok that's 3 questions but you get the point :)
why would I?
To encapsulate the logging functionality into its own class. Why? Single Responsibility Principle http://en.wikipedia.org/wiki/Single_responsibility_principle. Ny mixing it into your class you are making that class be responsible for at least two (2) things: whatever it does and logging.
And what would this class even look like?
public class LogWriter
{
public static Log(string log, string source, string message, EventLogEntryType type, int eventid)
{
if (!EventLog.SourceExists(source))
EventLog.CreateEventSource(source, log);
EventLog.WriteEntry(source, message, type, eventid);
}
}
And why would I need it when my function works nicely?
Think about when you are no longer responsible for the code. Think ahead to when the code grows. Eventually, in addition to logging it might have a host of other very helpful functions included in it. The next programmer would be much happier not having to refactor your work because the design precedent has been set.
This is a very general question about OO design. Your colleague is referring to separation of responsibilities; he doesn't think that the idea of an event log writer fits into the abstraction of the class you put it in, and it deserves its own.
If this is all you are ever going to use it for (this one method) and this program is simple enough that you are implementing it one class, there is no need to use another class to interact with your event writer. If you can conceive that your event writer might be used in a different way, or by a different class, in the future, then yes, absolutely make it is own class so that you avoid future problems where you have to change the source code that uses it.
The function you've written is a small function that doesn't keep state, so another class is not really necessary unless it's to avoid future problems.
Simple, what if you wish to use this method every where in all other parts of your code base? You again copy - paste. Instead have a helper or a Add in class, where just instantiate and keep calling.
Plus if its in a class, you can have more properties and provide more customization methods as well in logging data.
See if you can make use of built in eventlog/trace stuffs.
If it's a small application (which with one class it must be) then it probably doesn't matter.
But design wise in a larger application, you probably would want to consider having the logging functionality in a class by itself in order to keep each class as narrowly focused as possible.
For the same reason that someone put SourceExists(Source) and CreateEventSource(source, log) into their own class, so you could call them just by referencing the assembly that has that class defined, and writing
EventLog.SourceExists(source);
or
EventLog.CreateEventSource(source, log);
So if you will never ever need to write to the event log in any other application you ever write, then what you are doing is fine... but if you might ever need this again, then .....
I think you should have seperate class because if you are going to create more no.of classes in your application you can use same logging for all of them see below example
public static class Logger
{
private static string logFilePath = string.Empty;
public static void Log(string logMessage, TextWriter w)
{
w.Write( logMessage);
w.Flush();
}
public static void Log(string textLog)
{
string directoryString =
filepath+ #"\Logging";
Directory.CreateDirectory(directoryString);
logFilePath = directoryString + "\\" +
DateTime.Now.ToShortDateString().Replace("/", "") + ".txt";
StreamWriter sw = null;
if (!File.Exists(logFilePath))
{
try
{
sw = File.CreateText(logFilePath);
}
finally
{
if (sw != null) sw.Dispose();
}
}
using (StreamWriter w = File.AppendText(logFilePath))
{
Log(textLog, w);
w.Close();
}
}
I agree that you shouldn't create a new class for writing directly to the event log, but for another reason. That class already exists!
Consider using the built-in debug/tracing mechanisms in System.Diagnostics:
Debug output
Trace output
These are standard classes that dump information to a collection of TraceListener objects, of which many useful types already exist:
DefaultTraceListener - Dumps output to standard debug out, I believe via OutputDebugString().
EventLogTraceListener - Dumps output to the windows event log.
So this changes your output mechanism from a programmatic question into a configuration question. (Yes, if you're working in a straight-up managed app, you can populate your TraceListener collection via your app.config.) That means that everywhere you simply use the appropriate Trace.Write() or Debug.Write() call (Depending on if your want the output in a release build), and the configuration determines where the output goes.
Of course, you can also populate your TraceListener collection programmatically, it's fun and simple.
And this way you don't have to build up your own home-grown logging infrastructure. It's all built-in! Use it in good health! :D
If, on the other hand, you insist on rolling your own (a bad idea, I think), your colleague is right. It's a separate responsibility and belongs in a separate class. I would expect static methods for output because there's probably no concept instances of your debug log. In fact, I'd expect an interface very similar to System.Diagnostics.Debug, so yeah, just use that one instead.
Depending on your approach, you may run into a subtle gotcha' that's in the docs, but not immediately obvious without a careful reading. I found an answer for it elsewhere.

Use Attributes To Check Whether to Access a Method

I have a method that is only accessible if a certain criteria is fulfilled, if it's not, then the method won't be executed. Currently, this is how I code the thing:
public void CanAccessDatabase()
{
if(StaticClass.IsEligible())
{
return;
}
// do the logic
}
Now, this code is ugly because out of no where there is this if(StaticClass.IsEligible()) condition that is not relevant to the concern of the method.
So I am thinking about putting the IsEligible method in the attribute, so that my code will look like this. If the condition is not fulfilled, then this method will just return without executing the logic below.
[IsEligibleCheck]
public void CanAccessDatabase()
{
// do the logic
}
Eligibility is a runtime decision, of course.
Any idea on how to code up the logic for IsEligibleCheck ? Thanks
Edit: I know PostSharp can do this, but I am looking at something that works out of box, not depending on any third party library.
Any idea on how to code up the logic for IsEligibleCheck?
This is a perfect spot for AOP.
Edit: I know PostSharp can do this, but I am looking at something that works out of box, not depending on any third-party library.
Is Microsoft considered third-party? If not, you could look at Unity from their Patterns & Practices team. Look at the Interceptor mechanism in Unity.
Otherwise, you effectively have to roll your own implementation using reflection. Effectively what you have to do is wrap your objects in a proxy wherein the proxy uses reflection to check the attributes and interpret them appropriately. If IsEligibleCheck succeeds then the proxy invokes the method on the wrapped object. Really, it's easier to just reuse an already existing implementation.
My advice is just use Unity (or another AOP solution).
Unfortunately, attributes doesn't get executed at runtime. A handful of built-in attributes modify the code that gets compiled, like the MethodImpl attributes and similar, but all custom attributes are just metadata. If no code goes looking for the metadata, it will sit there and not impact the execution of your program at all.
In other words, you need that if-statement somewhere.
Unless you can use a tool like PostSharp, then you cannot get this done in out-of-the box .NET, without explicit checks for the attributes.
This looks like a perfect candidate for AOP. In a nutshell, this means that the CanAccessDatabase logic will live in an "aspect" or "interceptor", that is, separate from the business logic, thus achieving separation of concerns (the aspect is only responsible for security, business code is only responsible for business things).
In C#, two popular options for doing AOP are Castle.DynamicProxy and PostSharp. Each has its pros and cons. This question sums up their differences.
Here are other options for doing AOP in .Net, some of them can be done without 3rd-party libraries. I still recommend using either DynamicProxy, PostSharp, LinFu, Spring.AOP or Unity, other solutions are not nearly as flexible.
Custom attributes go hand in hand with Reflection.
You will need to create another class that is responsible for calling the methods in your CanAccessDatabase() class.
Using reflection, this new class will determine the attributes on each method. If the IsEligibleCheck attribute is found, it will perform the StatiClass.IsEligible() check and only call CanAccessDatabase() if the check passes.
Heres an introduction to doing this at MSDN. It revolves around using the MemberInfo.GetCustomAttributes() method.
Heres the pseudocode:
Get the Type of the CanAccessDatabase() class
Using this type, get all methods in this class (optionally filtering public, private etc).
Loop through the list of methods
Call GetCustomAttributes() on the current method.
Loop through the list of custom attributes
If the IsEligibleCheck attribute is found
If StaticClass.IsEligible is true
Call the current method (using MethodInfo.Invoke())
End If
End If
End Loop
End Loop
I know this is an old thread...
You can use the Conditional Attribute: http://msdn.microsoft.com/en-us/library/system.diagnostics.conditionalattribute.aspx
"Indicates to compilers that a method call or attribute should be ignored unless a specified conditional compilation symbol is defined."
#define IsEligibleCheck // or define elsewhere
[Conditional("IsEligibleCheck")]
public void CanAccessDatabase()
{
// do the logic
}
check AOP that will help you a lot in this, one of the powerful components in the market is PostSharp

C# conditional logging/tracing

I want to add logging or tracing to my C# application but I don't want the overhead of formatting the string or calculating values to be logged if the log verbosity level is set so low that the message will not be logged.
In C++, you can use the preprocessor to define macros that will prevent code from being executed at all like this:
#define VLOG(level,expr) if (level >= g_log.verbosity) { g_log.output << expr; }
Used like this:
VLOG(5,"Expensive function call returns " << ExpensiveFunctionCall());
How do you do that in C#?
I've read the Microsoft docs explaining the Trace and Debug facilities here, and they claim that using #undef DEBUG and #undef TRACE removes all tracing and debugging code from the produced executable, but does it really remove the whole call? Meaning, if I write
System.Diagnostics.Trace.WriteLineIf(g_log.verbosity>=5,ExpensiveFunctionCall());
it won't call my expensive function if I undefine TRACE? Or does make the call, then decide it won't trace anything?
Anyway, even if it does remove it, this is inferior to the C++ macro because I can't make that big ugly call look like my simple VLOG() call in C++ and still avoid evaluating parameters, can I? Nor can I avoid the overhead by defining the verbosity lower at runtime like I can in C++, right?
To answer one of your questions, all method calls that must evaluate in order to call Trace.WriteLine (or its siblings/cousins) do not get called if Trace.WriteLine is compiled out. So go ahead and put your expensive method calls in directly as parameters to the Trace call and it will be removed at compile-time if you don't define the TRACE symbol.
Now for your other question regarding changing your verbosity at runtime. The trick here is that Trace.WriteLine and similar methods take 'params object[] args' for their string formatting arguments. Only when the string is actually emitted (when verbosity is set sufficiently high) does the method call ToString on those objects to get a string out of them. So a trick I often play is to pass objects rather than fully-assembled strings to these methods, and leave the string creation in the ToString of the object I pass in. That way the runtime performance tax is only paid when logging is actually occurring, and it gives you the freedom to change verbosity without recompiling your app.
A solution that has worked for me is using a singleton class. It can expose your logging functions and you can control its behavior efficiently. Lets call the class 'AppLogger'. Her is an example
public class AppLogger
{
public void WriteLine(String format, params object[] args)
{
if ( LoggingEnabled )
{
Console.WriteLine( format, args );
}
}
}
Note, the Singleton stuff is left out of the above example. There are TONS of good examples out the tubes. NOw the interesting thing is how to support multi-threading. I've done it like this: (abbreviated for brevity, hahahaha)
public static void WriteLine( String format, params object[] args )
{
if ( TheInstance != null )
{
TheInstance.TheCreatingThreadDispatcher.BeginInvoke( Instance.WriteLine_Signal, format, args );
}
}
In this way, any thread can log and the messages are handled on the original creating thread. Or you could create a special thread just for handling logging output.
ConditionalAttribute is your best friend. The call will be completely removed (as though call sites were #if'd) when the #define is not set.
EDIT: someone put this in a comment (thanks!), but worth noting in the main answer body:
All the methods of Trace class are decorated with Conditional("TRACE"). Just saw this using reflector.
Which means Trace.Blah(...expensive...) does completely disappear if TRACE is not defined.
All the info about Conditional(Trace) is good - but I assume your real question is that you want to leave the Trace calls in your production code but (usually) disable them at run-time unless you experience a problem.
If you're using TraceSource's (which I believe you should, rather than calling Trace directly because it gives you more fine-grained control over tracing at a component-level at run-time), you can do something like this:
if (Component1TraceSource.ShouldTrace(TraceEventType.Verbose))
OutputExpensiveTraceInformation()
This assumes you are able to isolate the tracing parameters in another function (i.e. they mostly depend on members of the current class rather than expensive operations on the parameters to the function in which this code is in).
The advantage of this approach is because the JITer compiles on a function-by-function basis as it needs to, if the "if" evaluates to false, the function will not only not be called - it won't even be JITed. The downside is (a) you've separated knowledge of the tracing level between this call and the function OutputExpensiveTraceInformation (so if you e.g. change the TraceEventType there to be TraceEventType.Information, for instance, it won't work because you'll never even call it unless the TraceSource is enabled for Verbose level tracing in this example) and (b) it's more code to write.
This is a case where it would seem that a C-like preprocessor would help (since it could make sure, for instance,that the parameter to ShouldTrace and to the eventual TraceEvent call are the same), but I understand why C# doesn't include that.
Andrew's suggestion of isolating expensive operations in the .ToString methods of the objects you pass to TraceEvent is also a good one; in that case, you could for instance develop an object which is just used for Trace to which you pass the objects you want to build an expensive string representation of and isolate that code in the ToString method of the trace object rather than doing it in the parameter list to the TraceEvent call (which will cause it to be executed even if the TraceLevel is not enabled at run-time).
Hope this helps.
have you tried a sophisticated logging api like log4net (http://logging.apache.org/log4net/index.html)?
Two of these answers (Andrew Arnott's and Brian's) did answer part of my question. The ConditionalAttribute that is applied to the Trace and Debug class methods causes all calls to the methods to be removed if TRACE or DEBUG are #undef'd, including the expensive parameter evaluation. Thanks!
For the second part, whether you can completely remove all calls at runtime, not at compile time, I found the answer in the log4net fac. According to them, if you set a readonly property at startup time, the runtime will compile away all calls that don't pass the test! This doesn't let you change it after startup but that's fine, it's better than removing them at compile time.
For your comment
"because I can't make that big ugly call look like my simple VLOG() call in C++ " - You could add a using statement as example below.
using System.Diagnostics;
....
Trace.WriteLineIf(.....)
As I understand, it will remove lines containing Trace, if you undefine the Trace symbol.
I'm not sure, but you can find out the answer yourself.
Make it a REALLY expensive function (like Thread.Sleep(10000)) and time the call. If it takes a very long time, then it's calling your function anyway.
(You can wrap the Trace.WriteLineIf() call with #if TRACE and #endif and test it again for a base comparison.)
It will invoke the expensive call because it might have side effects that are desired.
What you can do is decorate your expensive method with a [Conditional("TRACE")] or [Conditional("DEBUG")] attribute. The method will not be compiled into the final executable if the DEBUG or TRACE constant is not defined, nor will any calls to execute the expensive method.

How to save the output of a console application

I need advice on how to have my C# console application display text to the user through the standard output while still being able access it later on. The actual feature I would like to implement is to dump the entire output buffer to a text file at the end of program execution.
The workaround I use while I don't find a cleaner approach is to subclass TextWriter overriding the writing methods so they would both write to a file and call the original stdout writer. Something like this:
public class DirtyWorkaround {
private class DirtyWriter : TextWriter {
private TextWriter stdoutWriter;
private StreamWriter fileWriter;
public DirtyWriter(string path, TextWriter stdoutWriter) {
this.stdoutWriter = stdoutWriter;
this.fileWriter = new StreamWriter(path);
}
override public void Write(string s) {
stdoutWriter.Write(s);
fileWriter.Write(s);
fileWriter.Flush();
}
// Same as above for WriteLine() and WriteLine(string),
// plus whatever methods I need to override to inherit
// from TextWriter (Encoding.Get I guess).
}
public static void Main(string[] args) {
using (DirtyWriter dw = new DirtyWriter("path", Console.Out)) {
Console.SetOut(dw);
// Teh codez
}
}
}
See that it writes to and flushes the file all the time. I'd love to do it only at the end of the execution, but I couldn't find any way to access to the output buffer.
Also, excuse inaccuracies with the above code (had to write it ad hoc, sorry ;).
The perfect solution for this is to use log4net with a console appender and a file appender. There are many other appenders available as well. It also allows you to turn the different appenders off and on at runtime.
I don't think there's anything wrong with your approach.
If you wanted reusable code, consider implementing a class called MultiWriter or somesuch that takes as input two (or N?) TextWriter streams and distributes all writs, flushes, etc. to those streams. Then you can do this file/console thing, but just as easily you can split any output stream. Useful!
Probably not what you want, but just in case... Apparently, PowerShell implements a version of the venerable tee command. Which is pretty much intended for exactly this purpose. So... smoke 'em if you got 'em.
I would say mimic the diagnostics that .NET itself uses (Trace and Debug).
Create a "output" class that can have different classes that adhere to a text output interface. You report to the output class, it automatically sends the output given to the classes you have added (ConsoleOutput, TextFileOutput, WhateverOutput).. And so on.. This also leaves you open to add other "output" types (such as xml/xslt to get a nicely formatted report?).
Check out the Trace Listeners Collection to see what I mean.
Consider refactoring your application to separate the user-interaction portions from the business logic. In my experience, such a separation is quite beneficial to the structure of your program.
For the particular problem you're trying to solve here, it becomes straightforward for the user-interaction part to change its behavior from Console.WriteLine to file I/O.
I'm working on implementing a similar feature to capture output sent to the Console and save it to a log while still passing the output in real time to the normal Console so it doesn't break the application (eg. if it's a console application!).
If you're still trying to do this in your own code by saving the console output (as opposed to using a logging system to save just the information you really care about), I think you can avoid the flush after each write, as long as you also override Flush() and make sure it flushes the original stdoutWriter you saved as well as your fileWriter. You want to do this in case the application is trying to flush a partial line to the console for immediate display (such as an input prompt, a progress indicator, etc), to override the normal line-buffering.
If that approach has problems with your console output being buffered too long, you might need to make sure that WriteLine() flushes stdoutWriter (but probably doesn't need to flush fileWriter except when your Flush() override is called). But I would think that the original Console.Out (actually going to the console) would automatically flush its buffer upon a newline, so you shouldn't have to force it.
You might also want to override Close() to (flush and) close your fileWriter (and probably stdoutWriter as well), but I'm not sure if that's really needed or if a Close() in the base TextWriter would issue a Flush() (which you would already override) and you might rely on application exit to close your file. You should probably test that it gets flushed on exit, to be sure. And be aware that an abnormal exit (crash) likely won't flush buffered output. If that's an issue, flushing fileWriter on newline may be desirable, but that's another tricky can of worms to work out.

Categories

Resources