Welcome to MSDN Blogs Sign in | Join | Help

News

  • These postings are provided "AS IS" with no warranties, and confer no rights. Use of included code samples are subject to the terms specified Terms of Use
Tip #83: Did you know... You can get the name of the calling method from the stack using reflection?

Nearly every program needs a logger to log events, errors and exceptions. Sometimes it is also useful to log the name of the method that logged the event. The easiest way to do that is to make the log method take both the calling method name and event as parameters:

[C#]

void Log(string callingMethodName, string eventMessage) 

{
   Console.WriteLine("Event logged by " + callingMethodName);
   Console.WriteLine("Event: " + eventMessage);
}

In this case, every method will need to specify its name when calling Log(). In addition to this, the developer will have to watch if methods name change. However, there is a cleaner way to get the name of the calling method. It can be extracted from the stack. Since the method on top of the stack is the method that is currently being executed, the calling method will be right below it. Thus, by instantiating StackTrace (don’t forget to include System.Diagnostics) and getting the frame with index 1 will result in getting a StackFrame that corresponds to the call from the calling method. Finally, reflection can be used to get method name.

using System.Diagnostics;
	
void Log(string eventMessage) {
   Console.WriteLine("Event logged by " + (new StackTrace()).GetFrame(1).GetMethod().Name);
   Console.WriteLine("Event: " + eventMessage);
}


Katerina Rohonyan
SDET, IIS Team

Posted: Tuesday, June 23, 2009 5:25 PM by WebDevTools

Comments

Marijn said:

Indeed, StackTrace.GetFrame.GetMethod is nice for tose things.

However, beware that an optimizing compiler might optimize away stackframes (due to inlining for example). In .NET you can add a JIT attribute ([Runtime.CompilerServices.MethodImpl(Runtime.CompilerServices.MethodImplOptions.NoInlining)]) but that only instructs the JIT to not inline. The C# compiler can not be told to not inline (but it does not seem to inline currently).

# June 24, 2009 7:28 AM

Aaron said:

You beat me to this comment. I had this experience but I tried to used for something else than just logging and ended up being a nasty bug only present when compiled on release mode, so be cautious when using it as your code might be optimized by the compiler.

# June 24, 2009 10:03 AM

Greg said:

I've used this for debugging/logging but avoided it for non-debug code.  

It still doesn't beat printable to end user message numbers in error/log messages as you can text search for them right away to get the source line that printed the message.

# June 24, 2009 11:02 AM

Casey Barton said:

I just instinctively reference log4net, even for simple little on-off tools. You can log calling method amongst a hundred other attributes, just by configuring a format string.

# June 24, 2009 1:05 PM

Óscar González said:

How can you get the called method from the constructor?

# June 25, 2009 8:26 AM

Nicholas Piasecki said:

Referencing Aaron and Marijn, I got burned by this too. It's prone to error and I recommend not using it, unless you're positive it will only run in Debug builds.

# June 26, 2009 6:27 PM
Leave a Comment

(required) 

(required) 

(optional)

(required) 

  
Enter Code Here: Required

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Page view tracker