title: Logging ClassName and MethodName using log4net for a .NET project
body: <p>I have been looking for a way to log class names and method names as part of my logging infrastructure.  Obviously I'd like to make it simple to use and fast at runtime.  I've done a lot of reading about logging class names and method names, but I've run across 2 themes.</p>
  
  <ol>
  <li>That log4net uses an internally throws exception to generate a stack frame and that gets expensive if you use that generally for all logging.</li>
  <li>Confusion.  There is a lot of literature out there.  I've tried a bunch of it and not gotten to something useful.  </li>
  </ol>
  
  <p>If you humor me for a second, I'd like to reset.</p>
  
  <p>I created a class like this in my project</p>
  
  <pre><code>public static class Log {
      private static Dictionary&lt;Type, ILog&gt; _loggers = new Dictionary&lt;Type, ILog&gt;();
      private static bool _logInitialized = false;
      private static object _lock = new object();
  
      public static string SerializeException(Exception e) {
          return SerializeException(e, string.Empty);
      }
  
      private static string SerializeException(Exception e, string exceptionMessage) {
          if (e == null) return string.Empty;
  
          exceptionMessage = string.Format(
              "{0}{1}{2}\n{3}",
              exceptionMessage,
              (exceptionMessage == string.Empty) ? string.Empty : "\n\n",
              e.Message,
              e.StackTrace);
  
          if (e.InnerException != null)
              exceptionMessage = SerializeException(e.InnerException, exceptionMessage);
  
          return exceptionMessage;
      }
  
      private static ILog getLogger(Type source) {
          lock (_lock) {
              if (_loggers.ContainsKey(source)) {
                  return _loggers[source];
              }
  
              ILog logger = log4net.LogManager.GetLogger(source);
              _loggers.Add(source, logger);
              return logger;
          }
      }
  
      public static void Debug(object source, object message) {
          Debug(source.GetType(), message);
      }
  
      public static void Debug(Type source, object message) {
          getLogger(source).Debug(message);
      }
  
      public static void Info(object source, object message) {
          Info(source.GetType(), message);
      }
  
      public static void Info(Type source, object message) {
          getLogger(source).Info(message);
      }
  </code></pre>
  
  <p>...</p>
  
  <pre><code>    private static void initialize() {
          XmlConfigurator.Configure(); 
      }
  
      public static void EnsureInitialized() {
          if (!_logInitialized) {
              initialize();
              _logInitialized = true;
          }
      }
  }
  </code></pre>
  
  <p>(If this code looks familiar it's because it is borrowed from the examples!)</p>
  
  <p>In any case, throughout my project I use lines like this to log:</p>
  
  <pre><code>        Log.Info(typeof(Program).Name, "System Start");
  </code></pre>
  
  <p>Well, this kind of works.  Most importantly, I get the class name but no method name.  Less, importantly, I am polluting my code with this "typeof" junk.  If I copy and paste a snippet of code between files, etc. the logging framework will be lying!</p>
  
  <p>I tried playing with the PatternLayout (%C{1}.{M}) but that didn't work (all it did was write "Log.Info" to the log--because everything is routing through the Log.X static methods!).  Besides, that's supposed to be slow. </p>
  
  <p>So, what is the best way, given my setup and my desire to be simple and fast?</p>
  
  <p>Appreciate any help in advance.</p>