42

I'm currently developing a application logging library using the built in TraceListener. This library will be used in many projects and should offer a simple interface where I only have to care about WHAT is going to be written in into the log file, but not HOW.

By using the reflection namespace, I can figure out which application currently called a log function (retrieving execution assembly name), but I want also the name of the function and class that called the logging function.

Let's say I have:

public static void LogInfo(string vLogText) {
   Trace.WriteLine(
        MethodInfo.GetCurrentMethod().Name
        + this.GetType().ToString() + vLogText);
   }

When I call from another project (class: TestClass, method: TestMethod)

Tracer.LogInfo("log this!")

I expect to see in the log:

TestClass, TestMethod, log this!

But instead I got

TracerClass, LogInfo, log this!

How to get the parent method and class name?

user207421
  • 305,947
  • 44
  • 307
  • 483
Neurodefekt
  • 899
  • 2
  • 10
  • 18
  • 6
    [This might help you immensely](http://msdn.microsoft.com/en-us/library/hh534540.aspx) if you're using newest C# and VS 2012. – Patryk Ćwiek Feb 13 '13 at 08:34
  • @Trustme-I'maDoctor This is brilliant! Wasn't aware of such a thing. Can you please make this to a answer instead of a comment so I can vote up and mark it as closed? Thank you very much. – Neurodefekt Feb 13 '13 at 08:38
  • @Neurodefekt No problem, it's done. Glad I could help. :) – Patryk Ćwiek Feb 13 '13 at 08:41

2 Answers2

33

Try doing something like this:

var mth = new StackTrace().GetFrame(1).GetMethod();
var cls = mth.ReflectedType.Name;
// where 1 illustrates how deep into the stack to reflect.

There are more elegant solutions in C# 5.0 >, however if you are using older frameworks, the above will help.

Matthew Layton
  • 39,871
  • 52
  • 185
  • 313
Jens Kloster
  • 11,099
  • 5
  • 40
  • 54
  • 21
    Two things: 1) This can significantly affect performance 2) In optimized code, method inlining can cause an incorrect method name to be printed. – Mike Zboray Feb 13 '13 at 08:40
  • 1
    If performance isn't a concern, you can use MethodImpl to enforce no inlining: `[MethodImpl(MethodImplOptions.NoInlining)]` – Colin Zabransky Nov 02 '18 at 16:28
  • 1
    The line `var cls = mth.ReflectedType.Name;` produces the method type including the signature, not only the class name of the instance invoking the method. I suggest `var cls = mth.DeclaringType.Name;` to the the class name – Domin Feb 05 '19 at 09:05
3

You may just record the full stack trace instead of just the calling method using Environment.StackTrace. This may help you if you want to use the same logging structure to log exceptions.

Refer to this msdn page for more information.

daryal
  • 14,643
  • 4
  • 38
  • 54