title: How should I architect logging within my application?
body: <p>So I've done a lot of research on this and haven't found any answers where I said, "yes, THAT". I'm hoping the ever-erudite StackOverflow crowd can help me out.</p>
  
  <p>I've run into this issue in a couple of different scenarios. Say I have a C# app, and there are important things that I want to log.</p>
  
  <pre><code>public class MyClass
  {
      ... 
  
      public void ImportantMethod()
      {
          DoInterestingThing();
  
          var result = SomethingElseImportant();
          if (result == null)
          {
              logger.Log("I wasn't expecting that. No biggie.");
              return;
          }
  
          MoreInterestingStuff(); 
  }
  </code></pre>
  
  <p>The thing I'm interested in is <em>where do I get <code>logger</code> from</em>.</p>
  
  <p>As I see it I have a few options.</p>
  
  <ol>
  <li>Have it injected into MyClass in the constructor.</li>
  <li>Retrieve it using a globally available service locator.</li>
  <li>Use method decorators and AOP to have my logging done for me.</li>
  </ol>
  
  <p>None of these seem like great options. #3 looks to be impossible since I'm logging right in the middle of my business logic and not just doing a simple trace of my method calls, input parameters and/or exceptions thrown. #2, though simple seems like it would be really difficult to unit test. Of course, I would want to unit test everything. #1, though it would work fine, clutters up all my business logic with logging objects <em>that have nothing to do</em> with the business objects themselves. </p>
  
  <p>Any alternative ideas, or thoughts on one of the options above? 
  Much thanks!</p>
  
  <p>EDIT: just to be clear, I already know how to do DI (I use Unity), and I already know a good logging framework (I use log4net). Just wondering a how to use logging in an architecture sense across an application in the smartest way.</p>
  
  <hr>
  
  <p><strong>* EDIT *</strong></p>
  
  <p>I marked Mark Seeman's answer as the solution. I went through my application and found that most of my logging calls were doing the same thing a decorator could do. Namely, log the entry to the method, any exceptions thrown, and exit return values. </p>
  
  <p>Some cases I still needed to log directly inside a method. An example would be where I want to fail fast in a method which doesn't return anything but not <a href="https://stackoverflow.com/questions/77127/when-to-throw-an-exception">throw an Exception</a>. In those cases I have a singleton which holds a reference a <code>LogProvider</code> which will in turn retrieve a named log instance. The code looks similar to this:</p>
  
  <pre><code>private ILog logger = LogProviderFactory.Instance.GetLogger(typeof(Foo));
  </code></pre>
  
  <p>LogProviderFactory has a method <code>SetProvider</code> which allows you to swap out the singleton. So in unit testing I can do:</p>
  
  <pre><code>// LogProviderFactory.Instance now is our mock
  LogProviderFactory.SetProvider(MockLogProvider);
  </code></pre>
  
  <p>The logging decorator uses the same LogProvider as the singleton (which it obtains through injection), so logging is unified throughout the system.</p>
  
  <p>So really the end solution was mostly option #3, and a hybrid #2 (where it's the service locator pattern but the service is 'injected' into the locator).</p>
  
  <p><strong>AOP</strong></p>
  
  <p>As far as "aspect oriented programming" goes, I was a bit disappointed in the limitations of the language. Hoping AOP will be treated as a first-class citizen in future releases. </p>
  
  <ul>
  <li>I tried PostSharp but couldn't get it running on my machine correctly. Additionally it was a big restriction that you had to have PostSharp installed on your system to use it (as opposed to just calling a dll which comes with the solution or something similar). </li>
  <li>I used LinFu and was able to get it partially working. It blew up in a few instances however. The new 2.0 release is barely documented, so that was a hurdle. </li>
  <li>Interface interception with Unity however seems to work well out of the box. I got lucky that most things I wanted to log were in classes implementing interfaces.</li>
  </ul>