log4net argument to LogManager.GetLogger

Log4net

Log4net Problem Overview


Why do most log4net examples get the logger for a class by doing this:

private static ILog logger = 
    LogManager.GetLogger(
    System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

Rather than just passing typeof(MyClass):

private static ILog logger = LogManager.GetLogger(typeof(MyClass));

Is there any other reason for doing this, beside the fact that the first option does not require you to type a specific class name?

Log4net Solutions


Solution 1 - Log4net

I think you've got the reason. I do it that way so I don't have to worry about the class name and can just copy and paste boiler plate code in a new class.

For the official answer, see: How do I get the fully-qualified name of a class in a static block? at the log4net faq

Solution 2 - Log4net

I'm an NLog user, and usually this boils down to :

var _logger = LogManager.GetCurrentClassLogger();

It seemed a bit strange that you need to go through reflection in Log4Net, so I had a look in the NLog source code, and lo and behold, this is what they do for you:

[MethodImpl(MethodImplOptions.NoInlining)]
public static Logger GetCurrentClassLogger()
{
	string loggerName;
	Type declaringType;
	int framesToSkip = 1;
	do
	{
#if SILVERLIGHT
		StackFrame frame = new StackTrace().GetFrame(framesToSkip);
#else
		StackFrame frame = new StackFrame(framesToSkip, false);
#endif
		var method = frame.GetMethod();
		declaringType = method.DeclaringType;
		if (declaringType == null)
		{
			loggerName = method.Name;
			break;
		}
		framesToSkip++;
		loggerName = declaringType.FullName;
	} while (declaringType.Module.Name.Equals("mscorlib.dll", StringComparison.OrdinalIgnoreCase));
	return globalFactory.GetLogger(loggerName);
}

I guess I would write something similar for Log4Net as an extension or static method instead of pasting the reflection as part of my boiler code :)

Solution 3 - Log4net

As you say - its convenient as you can create a logger in a method without knowing the name of the class (trivial I know) but allows you to cut and paste methods between classes without having to rename the call.

Solution 4 - Log4net

I think the reason is, that you get the type of the runtime type using the .DeclaringType() method. You can use the logger in a base class and still see the actual type of your object in the loggers output. That makes investigations much more convinient.

Solution 5 - Log4net

It also makes it easier to create Codesmith templates for code generation purposes.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAndy WhiteView Question on Stackoverflow
Solution 1 - Log4netSteven LyonsView Answer on Stackoverflow
Solution 2 - Log4netNoctisView Answer on Stackoverflow
Solution 3 - Log4netPreet SanghaView Answer on Stackoverflow
Solution 4 - Log4netPeterBView Answer on Stackoverflow
Solution 5 - Log4netPhillip H. BlantonView Answer on Stackoverflow