<?xml version="1.0"?><?xml-stylesheet type="text/xsl" href="/rss.xsl"?><rss version="2.0"><channel><title>slf Discussions Rss Feed</title><link>http://slf.codeplex.com/Thread/List.aspx</link><description>slf Discussions Rss Description</description><item><title>New Post: thread safety</title><link>http://slf.codeplex.com/discussions/443151</link><description>&lt;div style="line-height: normal;"&gt;Is SLF thread-safe? If not, how does one use it safely from multiple threads potentially simultaneously?&lt;br /&gt;
&lt;/div&gt;</description><author>PerrySharePoint</author><pubDate>Thu, 09 May 2013 18:10:31 GMT</pubDate><guid isPermaLink="false">New Post: thread safety 20130509061031P</guid></item><item><title>New Post: How about .NET Framework support</title><link>http://slf.codeplex.com/discussions/440913</link><description>&lt;div style="line-height: normal;"&gt;Um, hello?&lt;br /&gt;
&lt;br /&gt;
For a .NET facade, it's pretty strange that you seem to support a bunch of third party logging frameworks, but not the .NET Framework itself, i.e. System.Diagnostics, TraceSource, etc.&lt;br /&gt;
&lt;/div&gt;</description><author>sgryphon</author><pubDate>Fri, 19 Apr 2013 14:03:00 GMT</pubDate><guid isPermaLink="false">New Post: How about .NET Framework support 20130419020300P</guid></item><item><title>New Post: Releasing File Lock</title><link>http://slf.codeplex.com/discussions/433324</link><description>&lt;div style="line-height: normal;"&gt;Hello everyone,&lt;br /&gt;
&lt;br /&gt;
I have a program which uses SLF for logging. This program runs 24/7 and I would like to upload the log files to a remote server every night for later review.&lt;br /&gt;
&lt;br /&gt;
My question is, how do I release the file lock for the log without closing the program?&lt;br /&gt;
&lt;br /&gt;
I was hoping to suspend logging, upload the logs, either delete the log file or erase the contents, and then resume logging.&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;ILogger logger = LoggerService.GetLogger(typeof(TaskScheduler).FullName);

// Other initialization here

foreach (var task in managedTasks.OrderBy(t =&amp;gt; t.Priority))
{
    if (task.NextRunTime &amp;lt;= DateTime.Now)
    {
        dataManager.CurrentStatus = AppStatus.Running;
        if (task.Name == &amp;quot;Log Sender&amp;quot;)
        {
             logger = null;
        }

        // Run the task

        if (task.Name == &amp;quot;Log Sender&amp;quot;)
            logger = LoggerService.GetLogger(typeof(TaskScheduler).FullName);

        dataManager.CurrentStatus = AppStatus.Idle;
    }
}&lt;/code&gt;&lt;/pre&gt;

Currently, when I do this, I'm still getting an IOException because the file is still locked by the Task Scheduler.&lt;br /&gt;
&lt;br /&gt;
Any ideas are appreciated.&lt;br /&gt;
&lt;br /&gt;
Ben&lt;br /&gt;
&lt;/div&gt;</description><author>benhelite</author><pubDate>Fri, 15 Feb 2013 22:18:37 GMT</pubDate><guid isPermaLink="false">New Post: Releasing File Lock 20130215101837P</guid></item><item><title>New Post: Factory for BitLaboratory (Object Guy's) Logging Framework?</title><link>http://slf.codeplex.com/discussions/211851</link><description>&lt;div style="line-height: normal;"&gt;&lt;p&gt;This is an old message, but I have the exact same issue...&lt;/p&gt;
&lt;p&gt;BitFactory can be configured declaratively, and SLF can be configured declaratively, but it does not seem they can be configured declaratively together without a factory for creating BitFactoryLogger objects...&lt;/p&gt;
&lt;p&gt;Unless I am missing something as well.&lt;/p&gt;&lt;/div&gt;</description><author>benmcclure</author><pubDate>Sun, 27 Mar 2011 07:26:02 GMT</pubDate><guid isPermaLink="false">New Post: Factory for BitLaboratory (Object Guy's) Logging Framework? 20110327072602A</guid></item><item><title>New Post: callsite is lost through NLogFacade</title><link>http://slf.codeplex.com/discussions/210075</link><description>&lt;div style="line-height: normal;"&gt;&lt;p&gt;Have this been fixed for NLog? Instead of importing the NLogFacade dll, I copied the 2 files into my project. Would this prevent callsite from working?&lt;/p&gt;
&lt;p&gt;I set up logger in my global.ascx file as follows:&lt;/p&gt;
&lt;p&gt;
&lt;div style="color: black; background-color: white;"&gt;
&lt;pre&gt;
  &lt;span style="color: green;"&gt;//Setup logger&lt;/span&gt;
  LoggerService.FactoryResolver = &lt;span style="color: blue;"&gt;new&lt;/span&gt; SimpleFactoryResolver(&lt;span style="color: blue;"&gt;new&lt;/span&gt; NLogLoggerFactory());
&lt;/pre&gt;
&lt;pre&gt;&lt;br /&gt;&lt;/pre&gt;
&lt;pre&gt;Later down in my app, I log like this:&lt;/pre&gt;
&lt;pre&gt;&lt;div style="color: black; background-color: white;"&gt;&lt;pre&gt;ILogger logger = LoggerService.GetLogger();
logger.Error(&lt;span style="color: #a31515;"&gt;"Exception: {0}"&lt;/span&gt;, ex.Source);
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;&lt;/pre&gt;
&lt;pre&gt;My NLog.onfig:&lt;/pre&gt;
&lt;pre&gt;&lt;div style="color: black; background-color: white;"&gt;&lt;pre&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;nlog&lt;/span&gt; &lt;span style="color: red;"&gt;xmlns&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt;&lt;span style="color: blue;"&gt;http://www.nlog-project.org/schemas/NLog.xsd&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt;
      &lt;span style="color: red;"&gt;xmlns:xsi&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt;&lt;span style="color: blue;"&gt;http://www.w3.org/2001/XMLSchema-instance&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;

  &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;targets&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;
    &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;target&lt;/span&gt; &lt;span style="color: red;"&gt;name&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt;&lt;span style="color: blue;"&gt;file&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt; &lt;span style="color: red;"&gt;xsi:type&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt;&lt;span style="color: blue;"&gt;AsyncWrapper&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt; &lt;span style="color: red;"&gt;queueLimit&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt;&lt;span style="color: blue;"&gt;5000&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt; &lt;span style="color: red;"&gt;overflowAction&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt;&lt;span style="color: blue;"&gt;Discard&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;
      &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;target&lt;/span&gt; &lt;span style="color: red;"&gt;name&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt;&lt;span style="color: blue;"&gt;FileError&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt;
            &lt;span style="color: red;"&gt;xsi:type&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt;&lt;span style="color: blue;"&gt;File&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt;
            &lt;span style="color: red;"&gt;fileName&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt;&lt;span style="color: blue;"&gt;${basedir}/App_Data/Logs/errors.txt&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt;
            &lt;span style="color: red;"&gt;archiveFileName&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt;&lt;span style="color: blue;"&gt;${basedir}/App_Data/Archives/log.{#####}.txt&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt;
            &lt;span style="color: red;"&gt;archiveAboveSize&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt;&lt;span style="color: blue;"&gt;10240&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt;
            &lt;span style="color: red;"&gt;archiveNumbering&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt;&lt;span style="color: blue;"&gt;Sequence&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt;
            &lt;span style="color: red;"&gt;concurrentWrites&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt;&lt;span style="color: blue;"&gt;true&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt;
            &lt;span style="color: red;"&gt;keepFileOpen&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt;&lt;span style="color: blue;"&gt;false&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt;
            &lt;span style="color: red;"&gt;encoding&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt;&lt;span style="color: blue;"&gt;iso-8859-2&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt;
            &lt;span style="color: red;"&gt;layout&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt;&lt;span style="color: blue;"&gt;${longdate}|${callsite:className=true:fileName=false:includeSourcePath=false:methodName=true}|${message}&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt;&lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;target&lt;/span&gt; &lt;span style="color: red;"&gt;name&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt;&lt;span style="color: blue;"&gt;FileInfo&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt; &lt;span style="color: red;"&gt;xsi:type&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt;&lt;span style="color: blue;"&gt;File&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt; &lt;span style="color: red;"&gt;fileName&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt;&lt;span style="color: blue;"&gt;${basedir}/App_Data/Logs/info.txt&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt;&lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;target&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;
  &lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;targets&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;
  &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;rules&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;
    &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;logger&lt;/span&gt; &lt;span style="color: red;"&gt;name&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt;&lt;span style="color: blue;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt; &lt;span style="color: red;"&gt;level&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt;&lt;span style="color: blue;"&gt;Error&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt; &lt;span style="color: red;"&gt;writeTo&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt;&lt;span style="color: blue;"&gt;FileError&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt;&lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;logger&lt;/span&gt; &lt;span style="color: red;"&gt;name&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt;&lt;span style="color: blue;"&gt;*&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt; &lt;span style="color: red;"&gt;level&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt;&lt;span style="color: blue;"&gt;Info&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt; &lt;span style="color: red;"&gt;writeTo&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt;&lt;span style="color: blue;"&gt;FileInfo&lt;/span&gt;&lt;span style="color: black;"&gt;"&lt;/span&gt;&lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;rules&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;nlog&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/p&gt;&lt;/div&gt;</description><author>Mixmasterxp</author><pubDate>Wed, 16 Feb 2011 04:11:53 GMT</pubDate><guid isPermaLink="false">New Post: callsite is lost through NLogFacade 20110216041153A</guid></item><item><title>New Post: Using NLog.config</title><link>http://slf.codeplex.com/discussions/245889</link><description>&lt;div style="line-height: normal;"&gt;&lt;p&gt;Stupid question lol. Delete pls.&lt;/p&gt;&lt;/div&gt;</description><author>Mixmasterxp</author><pubDate>Mon, 14 Feb 2011 00:56:19 GMT</pubDate><guid isPermaLink="false">New Post: Using NLog.config 20110214125619A</guid></item><item><title>New Post: Reload configuration for configuration file on fly</title><link>http://slf.codeplex.com/Thread/View.aspx?ThreadId=233935</link><description>&lt;div style="line-height: normal;"&gt;
&lt;p&gt;You might also consider using &lt;a href="http://netcommon.sourceforge.net/"&gt;Common.Logging&lt;/a&gt;.&amp;nbsp; It supports (via the config file) telling log4net to configure and watch.&amp;nbsp; It also supports putting the log4net configuration in the app.config file
 OR in a separate config file.&lt;/p&gt;
&lt;/div&gt;</description><author>wageoghe</author><pubDate>Wed, 10 Nov 2010 22:23:44 GMT</pubDate><guid isPermaLink="false">New Post: Reload configuration for configuration file on fly 20101110102344P</guid></item><item><title>New Post: Reload configuration for configuration file on fly</title><link>http://slf.codeplex.com/Thread/View.aspx?ThreadId=233935</link><description>&lt;div style="line-height: normal;"&gt;
&lt;p&gt;I am looking at using SLF and log4net as the logging framework on one of my projects. I am setting up the SLF and log4net configuration in my app,config file and everything loads and logs as excepted. However one of my requirements is to be able to change
 the log4net properties from my application and have the logger to use the new settings without reloading the application. In the past I have used the log4net xmlconfiguration configandwatch() method.&lt;/p&gt;
&lt;p&gt;Is there a way to handle this through the SLF framework.&lt;/p&gt;
&lt;/div&gt;</description><author>alfrye</author><pubDate>Mon, 08 Nov 2010 21:31:36 GMT</pubDate><guid isPermaLink="false">New Post: Reload configuration for configuration file on fly 20101108093136P</guid></item><item><title>New Post: SLF with Windows Phone?</title><link>http://slf.codeplex.com/Thread/View.aspx?ThreadId=229571</link><description>&lt;div style="line-height: normal;"&gt;&lt;p&gt;Is SLF (or a future version) usable with Windows Phone 7?&lt;/p&gt;
&lt;p&gt;Thanks.&lt;/p&gt;
&lt;p&gt;&amp;nbsp; Vikram&lt;/p&gt;&lt;/div&gt;</description><author>BeauGeek</author><pubDate>Mon, 04 Oct 2010 18:23:38 GMT</pubDate><guid isPermaLink="false">New Post: SLF with Windows Phone? 20101004062338P</guid></item><item><title>New Post: callsite is lost through NLogFacade</title><link>http://slf.codeplex.com/Thread/View.aspx?ThreadId=210075</link><description>&lt;div style="line-height: normal;"&gt;&lt;p&gt;Building on my last comment, here is some code from &lt;a href="http://netcommon.sourceforge.net/"&gt;Common.Logging&lt;/a&gt; that I think is showing the correct technique for preserving the code location.&amp;nbsp; Note that declaringType is stored in the wrapping logger (in this case Common.Logging's Log4netLogger) and it is the type of their Log4netLogger (as compared to the use of the logger's base class that is used to make NLog's code location work correctly).&lt;/p&gt;
&lt;div style="color:black;background-color:white"&gt;
&lt;pre&gt;        &lt;span style="color:gray"&gt;///&lt;/span&gt; &lt;span style="color:gray"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span style="color:gray"&gt;///&lt;/span&gt;&lt;span style="color:green"&gt; Sends the message to the underlying log4net system.&lt;/span&gt;
        &lt;span style="color:gray"&gt;///&lt;/span&gt; &lt;span style="color:gray"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span style="color:gray"&gt;///&lt;/span&gt; &lt;span style="color:gray"&gt;&amp;lt;param name=&amp;quot;logLevel&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green"&gt;the level of this log event.&amp;lt;/param&amp;gt;&lt;/span&gt;
        &lt;span style="color:gray"&gt;///&lt;/span&gt; &lt;span style="color:gray"&gt;&amp;lt;param name=&amp;quot;message&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green"&gt;the message to log&amp;lt;/param&amp;gt;&lt;/span&gt;
        &lt;span style="color:gray"&gt;///&lt;/span&gt; &lt;span style="color:gray"&gt;&amp;lt;param name=&amp;quot;exception&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green"&gt;the exception to log (may be null)&amp;lt;/param&amp;gt;&lt;/span&gt;
        &lt;span style="color:blue"&gt;protected&lt;/span&gt; &lt;span style="color:blue"&gt;override&lt;/span&gt; &lt;span style="color:blue"&gt;void&lt;/span&gt; WriteInternal(LogLevel logLevel, &lt;span style="color:blue"&gt;object&lt;/span&gt; message, Exception exception)
        {
            Level level = GetLevel(logLevel);
            _logger.Log(declaringType, level, message, exception);
        }

&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;</description><author>wageoghe</author><pubDate>Fri, 10 Sep 2010 18:19:05 GMT</pubDate><guid isPermaLink="false">New Post: callsite is lost through NLogFacade 20100910061905P</guid></item><item><title>New Post: Adding unique IDs to log messages</title><link>http://slf.codeplex.com/Thread/View.aspx?ThreadId=77592</link><description>&lt;div style="line-height: normal;"&gt;&lt;p&gt;You can go to the log4net source repository here to find a log4net extension that shows how to extend log4net to include an event id parameter.&amp;nbsp; Essentially they define an interface that is the same as (or similar to)&amp;nbsp;ILog, with an additional eventId parameter.&amp;nbsp; The implementation wraps a regular log4net logger.&amp;nbsp; Each logging call creates a log4net LoggingEvent structure/class and adds an &amp;quot;EventID&amp;quot; property to the LoggingEvent's Properties dictionary.&amp;nbsp; It then uses the regular log4net logger's Log method (which takes a LoggingEvent sturcture/class).&amp;nbsp; To get the EventID to show up in the&amp;nbsp; output, I guess you would just have to add the appropriate properties reference in the format string.&lt;/p&gt;
&lt;p&gt;If SLF wanted to support the ability to log &amp;quot;event id&amp;quot; natively, one approach might be to declare an interface that is parallel to SLF.ILogger.&amp;nbsp; It might be SLF.IEventIdLogger.&amp;nbsp; It would have the same parameters as ILogger, with the addition of an event id, maybe as the first parameter like log4net did.&amp;nbsp; Now, if someone wants to log event ids, they would request IEventIdLoggers (maybe you would need a parallel LogManager like log4net implemented in their extension) and log away.&amp;nbsp; A similar technique could probably be used for NLog (put the EventId in the appropriate NLog context dictionary).&lt;/p&gt;&lt;/div&gt;</description><author>wageoghe</author><pubDate>Fri, 10 Sep 2010 18:11:13 GMT</pubDate><guid isPermaLink="false">New Post: Adding unique IDs to log messages 20100910061113P</guid></item><item><title>New Post: Expose logging context</title><link>http://slf.codeplex.com/Thread/View.aspx?ThreadId=226524</link><description>&lt;div style="line-height: normal;"&gt;&lt;p&gt;Should slf &amp;quot;generically&amp;quot; expose the logging context (NDC, MDC, etc) of log4net and NLog?&amp;nbsp;&lt;/p&gt;
&lt;p&gt;For an example of a logging abstraction that does this, see the &lt;a title=log4net href="http://github.com/castleproject/Castle.Core/tree/master/src/Castle.Services.Logging.log4netIntegration/"&gt;log4net&lt;/a&gt;&amp;nbsp;and &lt;a title=NLog href="http://github.com/castleproject/Castle.Core/tree/master/src/Castle.Services.Logging.NLogIntegration/"&gt;NLog&lt;/a&gt; abstractions at the Castle project.&amp;nbsp; log4net and NLog loggers can be resolved as basic loggers (I think with an ILogger interface) or as &amp;quot;extended&amp;quot; loggers (IExtendedLogger).&amp;nbsp; From what I can tell, the extended logger interface exposes all of the &amp;quot;context&amp;quot; information (stacks and dictionaries) that can be exposed on log4net and NLog.&amp;nbsp; There is also a TraceSource based logger, but it is only exposed as ILogger.&amp;nbsp; I'm not sure what would happen if you tried to access the extended information on a TraceSource based logger, maybe an exception, maybe it just doesn't support an interface.&lt;/p&gt;
&lt;p&gt;Anyway, without exposing the logging context generically, one would have to resort to referencing the specific logging platform's LogManager to set the context, thus defeating the purpose of using the abstraction.&lt;/p&gt;
&lt;p&gt;Of course, there is the inherent conflict between limiting the facade to capabilities available in all logging platforms vs implementing/exposing capabilities that are available in some, but not all, logging platforms.&amp;nbsp;&lt;/p&gt;&lt;/div&gt;</description><author>wageoghe</author><pubDate>Wed, 08 Sep 2010 21:05:39 GMT</pubDate><guid isPermaLink="false">New Post: Expose logging context 20100908090539P</guid></item><item><title>New Post: using external config file with slf</title><link>http://slf.codeplex.com/Thread/View.aspx?ThreadId=225170</link><description>&lt;div style="line-height: normal;"&gt;&lt;p&gt;Due to the length and complexity of some log config files, it would be usefull if we could store it in an external file and have some way to point SLF to load it from there instead of the app config file.&lt;/p&gt;&lt;/div&gt;</description><author>vmlf</author><pubDate>Sat, 28 Aug 2010 16:19:37 GMT</pubDate><guid isPermaLink="false">New Post: using external config file with slf 20100828041937P</guid></item><item><title>New Post: Adding unique IDs to log messages</title><link>http://slf.codeplex.com/Thread/View.aspx?ThreadId=77592</link><description>&lt;div style="line-height: normal;"&gt;&lt;p&gt;It depends on what you mean by this comment &amp;quot;IT support team have requested that each logged message (above DEBUG) has some form of unique ID&amp;quot;.&amp;nbsp; Do you mean that every message that is logged by tagged with, essentially, an sequentially increasing id?&amp;nbsp; So, the logged messages would have a field that would go like 1, 2, 3, etc as statements are logged?&amp;nbsp; Judging by the rest of your comment (about defining an enum of log IDs), it sounds like you are asking about something like &amp;quot;event id&amp;quot; which helps describe the actual message being logged.&amp;nbsp; So, you could define &amp;quot;log ids&amp;quot; or &amp;quot;event ids&amp;quot; like this (enum or const, or whatever you prefer):&lt;/p&gt;
&lt;div style="color:black;background-color:white"&gt;
&lt;pre&gt;&lt;div style="color:black;background-color:white"&gt;&lt;pre&gt;&lt;span style="color:blue"&gt;public&lt;/span&gt; &lt;span style="color:blue"&gt;class&lt;/span&gt; AppEventId
{
  &lt;span style="color:blue"&gt;public&lt;/span&gt; &lt;span style="color:blue"&gt;int&lt;/span&gt; Startup = 0,
  &lt;span style="color:blue"&gt;public&lt;/span&gt; &lt;span style="color:blue"&gt;int&lt;/span&gt; Initialize = 1,
  &lt;span style="color:blue"&gt;public&lt;/span&gt; &lt;span style="color:blue"&gt;int&lt;/span&gt; Shutdown = 2,  
  &lt;span style="color:blue"&gt;public&lt;/span&gt; &lt;span style="color:blue"&gt;int&lt;/span&gt; Enter = 3,  
  &lt;span style="color:blue"&gt;public&lt;/span&gt; &lt;span style="color:blue"&gt;int&lt;/span&gt; Exit = 4,
  &lt;span style="color:blue"&gt;public&lt;/span&gt; &lt;span style="color:blue"&gt;int&lt;/span&gt; DatabaseLoginFailed = 5,
  &lt;span style="color:blue"&gt;public&lt;/span&gt; &lt;span style="color:blue"&gt;int&lt;/span&gt; FooServiceNotAvailable = 6,
  &lt;span style="color:blue"&gt;public&lt;/span&gt; &lt;span style="color:blue"&gt;int&lt;/span&gt; BarServiceNotAvailable = 7,
  &lt;span style="color:blue"&gt;public&lt;/span&gt; &lt;span style="color:blue"&gt;int&lt;/span&gt; LoginFailedOnce = 8,
  &lt;span style="color:blue"&gt;public&lt;/span&gt; &lt;span style="color:blue"&gt;int&lt;/span&gt; LoginFailedTwice = 9,
  &lt;span style="color:blue"&gt;public&lt;/span&gt; &lt;span style="color:blue"&gt;int&lt;/span&gt; LoginFailedThriceUserLockedOut = 10
};

&lt;/pre&gt;
&lt;/div&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;With these ids, and with an api that accepts ids (like System.Diagnostics TraceSource.TraceEvent), you can write code that gives logging messages some additional context.&lt;/p&gt;
&lt;div style="color:black;background-color:white"&gt;
&lt;pre&gt;&lt;div style="color:black;background-color:white"&gt;&lt;pre&gt;&lt;span style="color:blue"&gt;int&lt;/span&gt; maxAttempts = 3;

TraceSource ts = &lt;span style="color:blue"&gt;new&lt;/span&gt; TraceSource(&lt;span style="color:#a31515"&gt;&amp;quot;MyTraceSource&amp;quot;&lt;/span&gt;);
ts.TraceEvent(TraceEventType.Information, AppEventIds.Enter, &lt;span style="color:#a31515"&gt;&amp;quot;Enterning XYZ&amp;quot;&lt;/span&gt;);

&lt;span style="color:blue"&gt;bool&lt;/span&gt; userLoggedIn = &lt;span style="color:blue"&gt;false&lt;/span&gt;;
&lt;span style="color:blue"&gt;int&lt;/span&gt; attempts = 0;

&lt;span style="color:blue"&gt;while&lt;/span&gt; (!userLoggedIn &amp;amp;&amp;amp; attempts &amp;lt; maxAttempts)
{
  userLoggedIn = GetUserLoginInfo();
  &lt;span style="color:blue"&gt;if&lt;/span&gt; (!userLoggedIn)
  {
    &lt;span style="color:blue"&gt;int&lt;/span&gt; id = 0;
    &lt;span style="color:blue"&gt;switch&lt;/span&gt; (maxAttempts)
    {
      &lt;span style="color:blue"&gt;case&lt;/span&gt; 0:
        id = AppEventId.LoginFailedOnce;
      &lt;span style="color:blue"&gt;break&lt;/span&gt;;
      &lt;span style="color:blue"&gt;case&lt;/span&gt; 1:
        id = AppEventId.LoginFailedTwice;
      &lt;span style="color:blue"&gt;break&lt;/span&gt;;
      &lt;span style="color:blue"&gt;case&lt;/span&gt; 2:
        id = AppEventId.LoginFailedThriceUserLockedOut;
      &lt;span style="color:blue"&gt;break&lt;/span&gt;;
    }
    ts.TraceEvent(TraceEventType.Warning, id, &lt;span style="color:#a31515"&gt;&amp;quot;Login attempt failed&amp;quot;&lt;/span&gt;);
    &lt;span style="color:blue"&gt;throw&lt;/span&gt; &lt;span style="color:blue"&gt;new&lt;/span&gt; Exception(&lt;span style="color:#a31515"&gt;&amp;quot;Login failed&amp;quot;&lt;/span&gt;);
  }
  attempts++;
}
ts.TraceEvent(TraceEventType.Information, AppEventId.Exit, &lt;span style="color:#a31515"&gt;&amp;quot;Login successful&amp;quot;&lt;/span&gt;);

&lt;/pre&gt;
&lt;/div&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Here is a question from StackOverflow that seems to be asking about event ids in the same context and meaning that you are asking:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://stackoverflow.com/questions/1637464/what-are-best-practices-for-event-id-management"&gt;http://stackoverflow.com/questions/1637464/what-are-best-practices-for-event-id-management&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Some time ago I saw another post on StackOverflow where someone made a comment about defining event ids in a manner similar to the &amp;quot;theory of reply codes&amp;quot; used in SMTP.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://stackoverflow.com/questions/576185/logging-best-practices"&gt;http://stackoverflow.com/questions/576185/logging-best-practices&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;See the &amp;quot;Other recommendations&amp;quot; under the first answer (the answer by &amp;quot;Sly&amp;quot;, just in case the answers are ever reordered) for a brief discussion of how one might structure event ids.&lt;/p&gt;
&lt;p&gt;I think that there are a couple of issues regarding the event id:&lt;/p&gt;
&lt;p&gt;1.&amp;nbsp; If an organization/product wants to use event ids, then they have to define the ids and manage them somehow.&amp;nbsp; This seems to be part of the problem you are describing.&amp;nbsp; Some ids get defined. They are used in logging messages.&amp;nbsp; Someone writes more code and wants to log a message and should make a new id, but is to lazy to do so.&amp;nbsp; Instead, they use an existing id that might be misleading to someone reading the log.&lt;/p&gt;
&lt;p&gt;2.&amp;nbsp; If an organization/product wants to use event ids, it is more awkward to log them using popular logging frameworks like log4net and NLog.&amp;nbsp; The &amp;quot;normal&amp;quot; logging functions (Logger.Info, ILog.Info, etc) don't accept an id parameter.&amp;nbsp; Also, the more generic &amp;quot;Log&amp;quot; functions also don't seem to accept an &amp;quot;event id&amp;quot; parameter (in the same sense as the EventID accepted by TraceSource.TraceEvent).&amp;nbsp; It looks like the only way to get an EventID logged is to use either the MDC, NDC, GlobalContext, or ThreadContext objects (whichever one is appropriate) on the logger/manager.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;See this StackOverflow question/answer for one example of how to get an &amp;quot;event id&amp;quot; to show up in a log4net log:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://stackoverflow.com/questions/2290102/log4net-eventlogappender-log-event-id"&gt;http://stackoverflow.com/questions/2290102/log4net-eventlogappender-log-event-id&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;(In this question they seem to be asking about the EventLogAppender, but&amp;nbsp;I see no reason why someone might not want to log event ids in other logging targets like files, etc).&lt;/p&gt;
&lt;p&gt;(Note that I have not actually used either of these logging platforms, except for recently trying out NLog).&amp;nbsp; Anyway, the EventID could be stored in the appropriate dictionary and then could be referenced in the formatting string so that the output contains the ID.&lt;/p&gt;
&lt;p&gt;So, what to do?&amp;nbsp; I'm not sure what SLF can do to help with problem 1.&amp;nbsp; It seems that the ids have to be defined and managed somewhow.&amp;nbsp; Once that is solved, it should be straightforward enough for a developer that wants to log a message to determine what the appropriate id is.&amp;nbsp; If there is not an appropriate, he/she should probably define a new one (depending on local standards/procedures).&amp;nbsp; I suppose that SLF could have some sort of event id validation facility where an application/library can &amp;quot;register&amp;quot; &amp;quot;valid&amp;quot; event ids with SLF and then any time an event id is passed to SLF via an &amp;quot;event id&amp;quot; parameter in a logging call, SLF could verify that the id is a valid one.&amp;nbsp; This would give a development shop the ability to&amp;nbsp;catch the use of nonexistent event ids, but would not help in the case of &amp;quot;wrong&amp;quot; event id being used in the wrong place.&amp;nbsp; I would say leave the event id definition and management up to the development organization.&amp;nbsp; Maybe SLF should only provide a way to explicitly pass the event id parameter and get it logged?&lt;/p&gt;
&lt;p&gt;It seems like SLF could help with problem 2.&amp;nbsp; Maybe by providing some overloads that allow the specification of an event id in the logging calls (ILogger.Info(), ILogger.Warn(), etc).&amp;nbsp; With that in place, there is now a uniform way for people to use SLF and to be able to log event ids.&amp;nbsp; For TraceSources (if natively supported by SLF), the implementation would be simple enough.&amp;nbsp; Simply pass the event id to TraceSource.TraceEvent via the event id parameter.&amp;nbsp; Done.&amp;nbsp; For log4net and NLog, the problem is trickier.&amp;nbsp; Since there is (from what I can tell) not an explicit &amp;quot;event id&amp;quot; parameter available in the logging functions for those platforms, then the event id would have to be passed by convention, perhaps by adding a key/value pair to the appropriate dictionary (maybe called &amp;quot;EventID&amp;quot;??) containing the parameter name (&amp;quot;EventID&amp;quot;) and value (the event id itself).&amp;nbsp; If the person using log4net or NLog as their underlying platform wants to use the event id parameter, he/she would have to configure the formatting string(s) to&amp;nbsp;reference the &amp;quot;EventID&amp;quot; parameter.&lt;/p&gt;
&lt;p&gt;Another issue with adding the ability to log event ids is that now you need a lot more overloads of the logging functions.&amp;nbsp; I suppose you could choose to restrict the use of the &amp;quot;event id&amp;quot; parameter to a limited set of functions or you could make the event id parameter optional or have a default value.&amp;nbsp; I do notice that SLF.ILogger does have a &amp;quot;Log&amp;quot; function that takes a LogItem structure that has an event id member.&amp;nbsp; This means that people using SLF today could program to the Log function and populate the LogItem structure explicitly.&amp;nbsp; Maybe it is not so bad if you don't have a large number of logging statements that want to log the event id?&amp;nbsp; That is ok, I guess, but it suddenly makes the application's logging code more verbose:&lt;/p&gt;
&lt;div style="color:black;background-color:white"&gt;
&lt;pre&gt;&lt;span style="color:green"&gt;// Using ILogger.Log and LogItem makes this look more like old LAB logging examples.&lt;/span&gt;
ILogger logger = SLF.GetLogger(&lt;span style="color:#a31515"&gt;&amp;quot;HelloWorldLogger&amp;quot;&lt;/span&gt;);

LogItem item = &lt;span style="color:blue"&gt;new&lt;/span&gt; LogItem();
item.Message = &lt;span style="color:#a31515"&gt;&amp;quot;Hello World!&amp;quot;&lt;/span&gt;;
item.LogLevel = LogLevel.Warn;
item.EventId = 1001; &lt;span style="color:green"&gt;//Let's just hardcode the event id for now&lt;/span&gt;
item.LoggerName = logger.Name;

logger.Log(item);

&lt;span style="color:green"&gt;//Compare with being able to pass event id explicitly:&lt;/span&gt;
ILogger logger = SLF.GetLogger(&lt;span style="color:#a31515"&gt;&amp;quot;HelloWorldLogger&amp;quot;&lt;/span&gt;);

logger.Warn(&lt;span style="color:#a31515"&gt;&amp;quot;Hello World!&amp;quot;&lt;/span&gt;, 1001);
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;If I had to vote, I would say that adding a common way to log event ids across the logging platforms supported by SLF (or custom factories/loggers implemented by users of SLF) would be useful.&lt;/p&gt;
&lt;p&gt;Sorry for the long (and late) post, hope it is helpful.&lt;/p&gt;&lt;/div&gt;</description><author>wageoghe</author><pubDate>Mon, 23 Aug 2010 16:30:39 GMT</pubDate><guid isPermaLink="false">New Post: Adding unique IDs to log messages 20100823043039P</guid></item><item><title>New Post: Extending the ILogger and LoggerBase</title><link>http://slf.codeplex.com/Thread/View.aspx?ThreadId=204931</link><description>&lt;div style="line-height: normal;"&gt;&lt;p&gt;I agree with providing the IsXXXEnabled functions for the ILogger interface.&amp;nbsp; It is certainly useful when some extra processing is required to generate some values to be logged, but that processing is required ONLY when logging.&amp;nbsp; The entire code block that performs the processing can be short-circuited by an upfront IsXXXEnabled.&lt;/p&gt;
&lt;div style="color:black;background-color:white"&gt;
&lt;pre&gt;&lt;span style="color:blue"&gt;&lt;div style="color:black;background-color:white"&gt;&lt;pre&gt;&lt;span style="color:blue"&gt;void&lt;/span&gt; Matrix BuildTransform()
{
  Matrix m = DoSomeWorkToCalculateMatrix();

  logger.Info(&lt;span style="color:#a31515"&gt;&amp;quot;Matrix = {0}&amp;quot;&lt;/span&gt;, m);

  &lt;span style="color:blue"&gt;if&lt;/span&gt; (logger.IsInfoEnabled)
  {
    IEnumerable&amp;lt;Point&amp;gt; pts = GetTestPoints();

    logger.Info(&lt;span style="color:#a31515"&gt;&amp;quot;Points before transform&amp;quot;&lt;/span&gt;);
    &lt;span style="color:blue"&gt;foreach&lt;/span&gt; (Point p &lt;span style="color:blue"&gt;in&lt;/span&gt; pts)
    {
      logger.Info(p);
    }
    logger.Info(&lt;span style="color:#a31515"&gt;&amp;quot;Points after transform&amp;quot;&lt;/span&gt;);
    &lt;span style="color:blue"&gt;foreach&lt;/span&gt; (Point p &lt;span style="color:blue"&gt;in&lt;/span&gt; pts.Transform(m))
    {
      logger.Info(p);
    }
  }
  &lt;span style="color:blue"&gt;return&lt;/span&gt; m;
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;In this case, the purpose of the function is to compute a transformation matrix.&amp;nbsp; So, after computing it, I log the matrix.&amp;nbsp; I don't about you, but I would have a hard time telling if the matrix was really right or not.&amp;nbsp; But, I would have a pretty idea if it is right be comparing some before and after views of some known test points.&amp;nbsp; In the scheme of things, getting the test points and transforming them might be enough work that I just don't want to consider doing it unless I am logging, so I bracket the entire block with IsXXXEnabled.&lt;/p&gt;
&lt;p&gt;I also agree that providing the delegate signatures via extension methods &lt;em&gt;might &lt;/em&gt;be a good way to go.&amp;nbsp; The one question I would have about that is whether or not the call site information will still work correctly.&amp;nbsp; That is, will log4net and NLog be able to determine the calling method?&amp;nbsp; I know that there is an issue with this right now for log4net and that there was an issue with NLog, but a fix has been checked in.&amp;nbsp; If you essentially wrap the ILogger logging call in an extension method, does that break the call site preservation fix that has been made for NLog?&amp;nbsp; I haven't checked myself, but I have a feeling that the Type parameter that is being passed to NLog.Logger.LogEvent will cause NLog to go up the stack until the frame after the frame containing that Type.&amp;nbsp; That would be the stack frame of the extension method, not the &amp;quot;real&amp;quot; calling method.&lt;/p&gt;&lt;/div&gt;</description><author>wageoghe</author><pubDate>Fri, 20 Aug 2010 21:13:50 GMT</pubDate><guid isPermaLink="false">New Post: Extending the ILogger and LoggerBase 20100820091350P</guid></item><item><title>New Post: callsite is lost through NLogFacade</title><link>http://slf.codeplex.com/Thread/View.aspx?ThreadId=210075</link><description>&lt;div style="line-height: normal;"&gt;&lt;p&gt;You might already know this, but the log4net logger supports an ILogger interface (note that this is NOT the same as the log4net ILog interface).&amp;nbsp; According to the documentation, ILogger.Log is the most generic way to log a message.&amp;nbsp; It has two overloads, one of which takes a LoggerEvent class.&amp;nbsp; LoggerEvent appears to be similar to NLog's LogEvent (which you apparently used to preserve the call site info for your NLog wrapper).&amp;nbsp; Maybe you could use a similar approach to preserve log4net's call site info as you used to preserve NLog's.&amp;nbsp; One field in LoggerEvent is LocationInfo.&amp;nbsp; It looks like LocationInfo can get the location info automatically (which won't help if it is called from within SLF) OR it also has a constructor that accepts the class name, method name, filename, and line number which might be easier to obtain (class name and method name, anyway).&lt;/p&gt;
&lt;p&gt;Another idea, maybe not a good one, is to use the approach that is used within the Logging Application Block.&lt;/p&gt;
&lt;p&gt;Here is what LAB does in its logger (or did in the version that is available on koders.com):&lt;/p&gt;
&lt;div style="color:black;background-color:white"&gt;
&lt;pre&gt;&lt;span style="color:blue"&gt;private&lt;/span&gt; &lt;span style="color:blue"&gt;string&lt;/span&gt; GetCallingMethod()
        {
            &lt;span style="color:blue"&gt;string&lt;/span&gt; methodName = &lt;span style="color:blue"&gt;string&lt;/span&gt;.Empty;
            StackTrace trace = &lt;span style="color:blue"&gt;new&lt;/span&gt; StackTrace(&lt;span style="color:blue"&gt;true&lt;/span&gt;);
            &lt;span style="color:blue"&gt;foreach&lt;/span&gt; (StackFrame frame &lt;span style="color:blue"&gt;in&lt;/span&gt; trace.GetFrames())
            {
                &lt;span style="color:green"&gt;// find the first method that isn't from this class&lt;/span&gt;
                &lt;span style="color:blue"&gt;if&lt;/span&gt; (!frame.GetMethod().ReflectedType.Equals(&lt;span style="color:blue"&gt;typeof&lt;/span&gt;(EntLibLogger)) &amp;amp;&amp;amp;
                    !frame.GetMethod().ReflectedType.Equals(&lt;span style="color:blue"&gt;typeof&lt;/span&gt;(ExceptionManager)))
                {
                    methodName = &lt;span style="color:blue"&gt;string&lt;/span&gt;.Format(&lt;span style="color:#a31515"&gt;&amp;quot;{0} {1}:{2}&amp;quot;&lt;/span&gt;,
                        frame.GetMethod().DeclaringType.ToString(),
                        frame.GetMethod().ToString(),
                        frame.GetFileLineNumber());
                    &lt;span style="color:blue"&gt;break&lt;/span&gt;;
                }
            }
            &lt;span style="color:blue"&gt;return&lt;/span&gt; methodName;
        }

&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Anyway, this class walks the stack up until the type of the MethodBase is not&amp;nbsp;one of several&amp;nbsp;Enterprise Library types.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Here is some experimental code that I wrote trying to mimic what is going on in LAB.&amp;nbsp; I think that I got the &amp;quot;IsAssignableFrom&amp;quot; bit from StackOverflow, as I don't recall that LAB did this exactly the same way:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style="color:black;background-color:white"&gt;
&lt;pre&gt;    &lt;span style="color:blue"&gt;internal&lt;/span&gt; &lt;span style="color:blue"&gt;string&lt;/span&gt; GetCallingMethodName()
    {
      &lt;span style="color:blue"&gt;string&lt;/span&gt; result = &lt;span style="color:#a31515"&gt;&amp;quot;unknown&amp;quot;&lt;/span&gt;;
      StackTrace trace = &lt;span style="color:blue"&gt;new&lt;/span&gt; StackTrace(&lt;span style="color:blue"&gt;false&lt;/span&gt;);
      &lt;span style="color:blue"&gt;for&lt;/span&gt; (&lt;span style="color:blue"&gt;int&lt;/span&gt; i = 0; i &amp;lt; trace.FrameCount; i++)
      {
        StackFrame frame = trace.GetFrame(i);
        MethodBase method = frame.GetMethod();
        Type dt = method.DeclaringType;
        &lt;span style="color:blue"&gt;if&lt;/span&gt; (!&lt;span style="color:blue"&gt;typeof&lt;/span&gt;(ILogger).IsAssignableFrom(dt) &amp;amp;&amp;amp; method.DeclaringType.Namespace != &lt;span style="color:#a31515"&gt;&amp;quot;DiagnosticsLibrary&amp;quot;&lt;/span&gt;)
        {
          result = &lt;span style="color:blue"&gt;string&lt;/span&gt;.Concat(method.DeclaringType.FullName, &lt;span style="color:#a31515"&gt;&amp;quot;.&amp;quot;&lt;/span&gt;, method.Name);
          &lt;span style="color:blue"&gt;break&lt;/span&gt;;
        }
      }
      &lt;span style="color:blue"&gt;return&lt;/span&gt; result;
    }&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The idea is to walk the stack up until you hit a MethodBase that does not support ILogger and the MethodBase's namespace is not the &amp;quot;logging&amp;quot; namespace.&amp;nbsp; In my case, this code was in a class that implements ILogger.&amp;nbsp; If I had put the code in some other part of the logging infrastructure, then the IsAssignableFrom check is probably not good.&lt;/p&gt;
&lt;p&gt;Obviously this is expensive to do on every logging call.&amp;nbsp; Part of the problem is that, by default, log4net and NLog don't have to do this unless that is an element in the formatting string that specifies that the call site should be logged.&amp;nbsp; So, at the time the message is logged (from application code directly to log4net or NLog), no extra cost is paid.&amp;nbsp; The cost does not come until the message is actually formatted by log4net or NLog and written out.&amp;nbsp; If the wrapper gets the call site info (as was done in the NLog wrapper/facade) then the cost of getting the information is paid during every logging call, whether or not the underlying logger's formatting string is going to use it.&amp;nbsp; I guess that there is not much that can be done since it is probably difficult/impossible to tell when/if an underlying logger is going to need to call site info.&lt;/p&gt;
&lt;p&gt;Having said all of that, see the answer by flanders in this post from StackOverflow for another way to get the calling method/class from an arbitrary depth in the calling stack:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://stackoverflow.com/questions/171970/how-can-i-find-the-method-that-called-the-current-method"&gt;http://stackoverflow.com/questions/171970/how-can-i-find-the-method-that-called-the-current-method&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;One way to save the cost of determining the call site info could be to have a configuration parameter in the &amp;quot;logging factory&amp;quot; config section (where you can specify the&amp;nbsp;log4net or NLog facades) that says whether or not to get the call site info.&amp;nbsp; So, if someone is using log4net and chooses not to configure call site info in any formatting strings, then he/she could turn the option off in the log4net facade config section.&amp;nbsp; If the &amp;quot;GetCallSiteInfo&amp;quot; parameter is &amp;quot;true&amp;quot;, then get the info, populate the LoggingEvent/LogEvent class/structure, and use the underlying logging platform's generic &amp;quot;Log&amp;quot; method.&amp;nbsp; If &amp;quot;false&amp;quot;, could still use the LoggingEvent/LogEvent and the generic &amp;quot;Log&amp;quot; method, but populate method and class with something like &amp;quot;[SLF CALL SITE LOGGING NOT CONFIGURED]&amp;quot; (or similar).&amp;nbsp; Putting something like that for the method/class info would make it a bit more obvious if there was a conflict between asking for the call site info in log4net/NLog and NOT asking for it in SLF.&amp;nbsp; Alternatively, SLF could log an informational message in its internal log about whether or not the call site parameter was set.&amp;nbsp; In the actually logging call (SLF's call to log4net/NLog to log), if call site info is not specified, you might just want to use the &amp;quot;normal&amp;quot; way of calling log4net/NLog (logger.Info(blah blah) rather than logger.Log(new LogEvent(blah blah blah).&lt;/p&gt;
&lt;p&gt;After typing all of that about getting the calling method info by walking the stack, I just looked at log4net some more and it looks like, maybe, the ILogger.Log function (remember, ILogger not ILog) supports a similar concept to NLog's Logger.Log( ... ), which you used to preserve call site info for NLog.&amp;nbsp; Log4net's ILogger.Log call takes a Type parameter that, according to the docs, means this: &lt;em&gt;&amp;quot;The declaring type of the method that is the stack boundary into the logging system for this call&amp;quot;&lt;/em&gt;.&amp;nbsp; Maybe it functions the same was as the Type passed to NLog's Logger.Log call?&amp;nbsp; Maybe you have already looked at this and determined that it doesn't work the same way.&amp;nbsp; Anyway, just thought I would pass it along.&lt;/p&gt;
&lt;p&gt;Anyway. maybe you will find some of this useful, maybe not.&amp;nbsp; I don't know yet if our project will use SLF, but I certainly think that it looks interesting.&lt;/p&gt;&lt;/div&gt;</description><author>wageoghe</author><pubDate>Fri, 20 Aug 2010 19:52:13 GMT</pubDate><guid isPermaLink="false">New Post: callsite is lost through NLogFacade 20100820075213P</guid></item><item><title>New Post: Provide TraceSource Support in SLF Core</title><link>http://slf.codeplex.com/Thread/View.aspx?ThreadId=76892</link><description>&lt;div style="line-height: normal;"&gt;&lt;p&gt;I am late to comment on this, but I have just started looking in detail at SLF.&amp;nbsp; I think it is a good idea to provide a TraceSource support in SLF.&amp;nbsp; The one additional suggestion that I would make is to consider support for hierarchical logger naming (maybe your existing hierarchical logger naming support elsewhere in SLF would be sufficient???).&amp;nbsp; Castle provides a TraceSource-based logging facility (maybe facility is more of a NInject term, I don't can't remember) that supports hierarchical naming.&amp;nbsp; In essence, if logger &amp;quot;ABC.123.xyz&amp;quot; is requested and there is not a TraceSource with that exact name (case insensitive) that was configured in the app.config file, then it backs up to &amp;quot;ABC.123&amp;quot;, &amp;quot;ABC&amp;quot;, and, finally &amp;quot;&amp;quot;&amp;nbsp;until it finds a TraceSource that was configured.&amp;nbsp; If it finds an ancestor, then the TraceSource with the requested name is configured to have the same properties (Switch, TraceListener(s)) as the ancestor.&amp;nbsp; In other words, if &amp;quot;ABC&amp;quot; was configured in the app.config, then requestes for &amp;quot;ABC.123&amp;quot; and &amp;quot;ABC.123.xyz&amp;quot; would yield TraceSources with the same properties as the first-found parent.&lt;/p&gt;
&lt;p&gt;If none are found, then a &amp;quot;Default&amp;quot; TraceSource is used.&amp;nbsp; The way Castle checks to see if a TraceSource with the given name was configured in the app.config is to check the returned TraceSource's properties.&amp;nbsp; If the returned TraceSource has exactly 1 TraceListener and that TraceListener is the DefaultTraceListener and the name is &amp;quot;Default&amp;quot;, then a TraceSource with that name is assumed to have not been configured.&lt;/p&gt;
&lt;p&gt;Castle also keeps a&amp;nbsp;dictionary of all created TraceSources, checking the dictionary first for a TraceSource and then delegating to app.config (TraceSource ts = new TraceSource(&amp;quot;xyz&amp;quot;)) if they haven't already created that TraceSource.&lt;/p&gt;
&lt;p&gt;So, with what you outlined above and with hierarchical naming support, you could write logging code like this:&lt;/p&gt;
&lt;div style="color:black;background-color:white"&gt;
&lt;pre&gt;&lt;span style="color:green"&gt;// If TraceSource &amp;quot;Foo&amp;quot; is configured in app.config and the others are not, &amp;quot;Foo.Bar&amp;quot; and &amp;quot;Foo.Bar.What&amp;quot; will yield TraceSources configured identically to &amp;quot;Foo&amp;quot;.&lt;/span&gt;
&lt;span style="color:green"&gt;// If TraceSource &amp;quot;Foo&amp;quot; and &amp;quot;Foo.Bar.What&amp;quot; are configured in app.config and &amp;quot;Foo.Bar&amp;quot; is not, &amp;quot;Foo.Bar&amp;quot; will yield a TraceSource configured identically to &amp;quot;Foo&amp;quot;.&lt;/span&gt;
&lt;span style="color:green"&gt;// If TraceSource &amp;quot;Foo&amp;quot; and &amp;quot;Foo.Bar&amp;quot; are configured in app.config and &amp;quot;Foo.Bar.What&amp;quot; is not, &amp;quot;Foo.Bar.What&amp;quot; yield yield a TraceSource configured identically to &amp;quot;Foo.Bar&amp;quot;.&lt;/span&gt;

&lt;span style="color:blue"&gt;var&lt;/span&gt; logger1 = LoggerService.GetLogger(&lt;span style="color:#a31515"&gt;&amp;quot;Foo&amp;quot;&lt;/span&gt;);
&lt;span style="color:blue"&gt;var&lt;/span&gt; logger2 = LoggerService.GetLogger(&lt;span style="color:#a31515"&gt;&amp;quot;Foo.Bar&amp;quot;&lt;/span&gt;);
&lt;span style="color:blue"&gt;var&lt;/span&gt; logger3 = LoggerService.GetLogger(&lt;span style="color:#a31515"&gt;&amp;quot;Foo.Bar.What&amp;quot;&lt;/span&gt;);

logger1.Warn(&lt;span style="color:#a31515"&gt;&amp;quot;Hello from Foo&amp;quot;&lt;/span&gt;);
logger2.Info(&lt;span style="color:#a31515"&gt;&amp;quot;Hello from Foo.Bar&amp;quot;&lt;/span&gt;);
logger3.Error(&lt;span style="color:#a31515"&gt;&amp;quot;Hello from Foo.Bar.What&amp;quot;&lt;/span&gt;);
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;You can see exactly what they did here:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://github.com/castleproject/Castle.Core/blob/master/src/Castle.Core/Core/Logging/TraceLogger.cs"&gt;http://github.com/castleproject/Castle.Core/blob/master/src/Castle.Core/Core/Logging/TraceLogger.cs&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Note that I have not used Castle so I can't comment on how good or not this approach is from experience, but it looks like a pretty good approach.&lt;/p&gt;
&lt;p&gt;I will also make a comment about formatting the log messages.&amp;nbsp; There are extensions to System.Diagnostics (such as Ukadc.Diagnostics here&amp;nbsp;on codeplex &lt;a href="http://ukadcdiagnostics.codeplex.com/"&gt;http://ukadcdiagnostics.codeplex.com/&lt;/a&gt;) that support formatting similar to how log4net and NLog support formatting (via a formatting string in the app.config file).&amp;nbsp; For Ukadc.Diagnostics, the formatting support is implemented in the TraceListener.&amp;nbsp; Formatting tokens are supported for the message, event id, time, timestamp, machine, thread, process, etc.&amp;nbsp; Depending on what FormatItem (in the Log method) does to build the message string that is sent to TraceSource.TraceEvent, could there be a conflict with the formatting that will be applied later by Ukadc.Diagnostics?&amp;nbsp; For example, if FormatItem adds the time so that &amp;quot;Hello World!&amp;quot; becomes &amp;quot;20-Aug-2010 12:32 pm, Hello World!&amp;quot;, then when Ukadc.Diagnostics formats the message, it might apply the date/time (if specified in the formatting string), resulting in a message that might look like: &amp;quot;20-Aug-2010 12:32 pm, 20-Aug-2010 12:32 pm, Hello World!&amp;quot;.&amp;nbsp; I guess that FormatItem might not do anything, so &amp;quot;formatting&amp;quot; a message that has &amp;quot;Hello World!&amp;quot; might just return &amp;quot;Hello World!&amp;quot; and everything would be ok.&lt;/p&gt;&lt;/div&gt;</description><author>wageoghe</author><pubDate>Fri, 20 Aug 2010 17:40:21 GMT</pubDate><guid isPermaLink="false">New Post: Provide TraceSource Support in SLF Core 20100820054021P</guid></item><item><title>New Post: callsite is lost through NLogFacade</title><link>http://slf.codeplex.com/Thread/View.aspx?ThreadId=210075</link><description>&lt;div style="line-height: normal;"&gt;Hey Colin, Any Idea about when will a new version be released?

Regards,
Mário&lt;/div&gt;</description><author>mfpinhal</author><pubDate>Thu, 27 May 2010 13:43:03 GMT</pubDate><guid isPermaLink="false">New Post: callsite is lost through NLogFacade 20100527014303P</guid></item><item><title>New Post: Factory for BitLaboratory (Object Guy's) Logging Framework?</title><link>http://slf.codeplex.com/Thread/View.aspx?ThreadId=211851</link><description>&lt;div style="line-height: normal;"&gt;&lt;p&gt;I decided to try this Logging Facade because it claimed support for BitLaboratory's Logging framework.&amp;nbsp; However, and maybe a simple fact is escaping me, but it appears that the BitLaboratory facade adapter is missing a crucial piece - the Factory.&lt;/p&gt;
&lt;p&gt;I am attempting to configure my logging declaratively in the config file, and as I look at the examples and the source code it appears this would not be possible without a factory.&lt;/p&gt;
&lt;p&gt;I can see where the default Resolver after a reset on the LoggerService is the AppConfigFactoryResolver.&amp;nbsp; I also see how this creates a dictionary of Factories keyed by the logger names, and how it matches the name argument to LoggerService.GetLogger(string name) to those logger keys in order to resolve and return a factory.&amp;nbsp; Then the actual logger is created through a method call to the factory.&lt;/p&gt;
&lt;p&gt;So, the way it appears to me, to the best of my understanding, is that I will have to create a Factory that delegates to BitLaboratory's Library's ConfigLogger.Instance.&lt;/p&gt;
&lt;p&gt;Am I missing something?&amp;nbsp; Something that allows me to configure SLF to use the BitLaboratory's Logging Framework, all configured declaratively through the app/web config's?&lt;/p&gt;
&lt;p&gt;After looking a little closer, I do see this ability to configure BitLaboratory's Framework declaratively is a newer feature, and perhaps SLF simply hasn't been updated.&amp;nbsp; As an aside, since this task is somewhat trivial, may I submit my Factory to be included in future releases of SLF?&amp;nbsp; I would feel much better about using this facade for my company if this particular usage scenario was specifically supported by the official build of SLF.&lt;/p&gt;&lt;/div&gt;</description><author>qstarin</author><pubDate>Thu, 06 May 2010 22:18:27 GMT</pubDate><guid isPermaLink="false">New Post: Factory for BitLaboratory (Object Guy's) Logging Framework? 20100506101827P</guid></item><item><title>New Post: callsite is lost through NLogFacade</title><link>http://slf.codeplex.com/Thread/View.aspx?ThreadId=210075</link><description>&lt;div style="line-height: normal;"&gt;&lt;p&gt;Hi Mario,&lt;/p&gt;
&lt;p&gt;No problem - if you have any more feedback, let me know. I think we will release a new version quite soon. We do not have many pending new features (we are keeping SLF simple!), so I will probably bundle this with just one or two other changes shortly.&lt;/p&gt;
&lt;p&gt;Regards, Colin E.&lt;/p&gt;&lt;/div&gt;</description><author>ColinEber</author><pubDate>Wed, 05 May 2010 07:21:31 GMT</pubDate><guid isPermaLink="false">New Post: callsite is lost through NLogFacade 20100505072131A</guid></item></channel></rss>