How does a System.TraceListener message add a message with a process name?

I am looking at using System.Diagnostics.Trace for logging - this is a very simple application. As a rule, he does everything I need for this. The downside is that if I call

Trace.TraceInformation("Some info"); 

Result: "SomeApp.Exe Information: 0: Some info". At first it entertained me, but it was no more. I would just print "Some info" for the console. So I decided to write cusom TraceListener, instead of using the built-in ConsoleTraceListener, it will solve the problem. I see a specific format in which I want all the text after the second colon. Here is my attempt to see if this will work.

 class LogTraceListener : TraceListener { public override void Write(string message) { int firstColon = message.IndexOf(":"); int secondColon = message.IndexOf(":", firstColon + 1); Console.Write(message); } public override void WriteLine(string message) { int firstColon = message.IndexOf(":"); int secondColon = message.IndexOf(":", firstColon + 1); Console.WriteLine(message); } } 

If I print the value of firstColon, it is always -1. If I set a breakpoint, the message will always be “Some Information.” Where does all the other information come from?

So, I looked at the call stack at the point immediately before calling Console.WriteLine. The method that called my WriteLine: System.dll method! System.Diagnostics.TraceListener.TraceEvent (System.Diagnostics.TraceEventCache eventCache, string source, System.Diagnostics.TraceEventType eventType, int id, string message) + 0x33 bytes

When I use Reflector to view this post, everything looks pretty straight forward. I do not see any code that changes the value of a string after I sent it to Console.WriteLine. The only method that can possibly change the underlying string value is to call UnsafeNativeMethods.EventWriteString, which has a pointer to the message.

Does anyone understand what is happening here, and can I change the output to be just my message, with extra fluff. It seems like evil magic that I can pass the string “Some Information” to Console.WriteLine (or any other method, for that matter), and the line whose output is different.

EDIT: I found the magic. Obviously, this was not magic. The Write method receives a call from a WriteHeader call before a WriteLine call, where I thought the magic was happening.

+7
c # tracelistener
source share
3 answers

You can get this by overriding the TraceEvent () method in your listener. Like this:

  public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string message) { Console.WriteLine("{0}: {1}", id, message); } 
+4
source share

You also need to override this TraceEvent overload if you use formatting:

 public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string format, params Object[] data) { base.WriteLine(String.Format(format, data)); } 

For example:

 Trace.TraceInformation("Thread {0} Waiting", Thread.CurrentThread.ManagedThreadId); 

Override will only output "Thread 9 Waiting \ n" when data [0] == 9

+1
source share

Why not use Trace.WriteLine("SomeInfo") instead of Trace.TraceInformation("SomeInfo") ?

0
source share

All Articles