Customize log4net Output Path

The default log4net output path is relative to the startup directory of your executable. To customize the output path, you can override the base Appender’s File property in your own Appender class. The following example describes how to route the log files relative to the temp folder :

   public class MyOwnAppender : log4net.Appender.RollingFileAppender
   {
         public override string File
         {
             get
             {
                 return base.File;
             }

            set
            {
                if (Path.IsPathRooted(value))
                {
                    base.File = value;
                }
                else
                {
                    base.File = Path.Combine(Path.GetTempPath(), value);
                }
            }
        }
    }

Your log4net config file must be modified so that log4net can locate and use your custom Appender. If MyOwnAppender is in MyNamespace and you have implemented it in MyLoggerLib.dll :


Career Advice

The value of any advice is tied to the degree of its relevance to your particular situation and circumstances. Very specific advice, like legal and medical advice, is very expensive. It is very relevant to the individual’s situation and therefore quite valuable. The degree of relevance of inexpensive/free advice to your specific circumstances is usually very low. Inexpensive/free advice, as in sayings and quotes, but also in everyday personal and business communication, is very generic. The same message is usually perceived differently by different people. Especially when the entire message is very succinct and pithy. Various aspects of the message are accentuated differently as it is filtered through individual perception.

  • Developing a sense of how generic advice applies to your individual situation is invaluable.
  • Experience, observation and reading feeds the awareness.
  • Trying and learning from mistakes is essential.
  • Applying the lessons completes the circle.

One of the best career advice I ever got was from reading Spencer Johnson’s Who Moved My Cheese ? The message in this book is timeless. I had been through many significant changes in my life and I think I have handled those changes quite well. After reading this book in 2001, I became consciously aware of the existence of change and my own patterns of behavior and responses to events of change. This awareness has helped me anticipate change, prepare better, make better decisions and handle change more productively.

Leveraging XPATH Axes

XPATH axes come in very handy when nodes need to be selected based on (attribute’s or child element’s) values that must match those of other nodes elsewhere in the xml tree. Consider the following log4net configuration file :


<?xml version="1.0"?>

<configuration>
    <configSections>
        <section name="nhibernate"
            type="System.Configuration.NameValueSectionHandler, System,
            Version=2.0.0.0,Culture=neutral, PublicKeyToken=b77a5c561934e089" />
        <section name="log4net"
            type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
    </configSections>
    <nhibernate>
        <add key="hibernate.connection.provider"
            value="NHibernate.Connection.DriverConnectionProvider" />
        <add key="hibernate.connection.driver_class"
            value="NHibernate.Driver.SqlClientDriver" />
        <add key="hibernate.connection.connection_string"
            value="Server=servername; Database=dbname;
            User=username; Password=secret;" />
        <add key="hibernate.connection.isolation" value="ReadCommitted" />
        <add key="hibernate.dialect"
            value="NHibernate.Dialect.MsSql2000Dialect" />
    </nhibernate>

    <log4net>
        <appender name="NHibernateFileLog"
        type="log4net.Appender.RollingFileAppender">
            <file value="Logs/nhibernate.txt" />
            <appendToFile value="true" />
            <rollingStyle value="Size" />
            <maxSizeRollBackups value="10" />
            <maximumFileSize value="100KB" />
            <staticLogFileName value="true" />
            <layout type="log4net.Layout.PatternLayout">
                <conversionPattern
                value="%d{HH:mm:ss.fff} [%t] %-5p %c - %m%n"  />
            </layout>
        </appender>

        <appender name="GeneralLog"
            type="log4net.Appender.RollingFileAppender">
            <file value="Logs/general.txt" />
            <appendToFile value="true" />
            <maximumFileSize value="100KB" />
            <rollingStyle value="Size" />
            <maxSizeRollBackups value="5" />
            <layout type="log4net.Layout.PatternLayout">
                <conversionPattern
                value="%d{HH:mm:ss.fff} [%t] %-5p %c - %m%n"  />
            </layout>
        </appender>
        <appender name="DataLog"
            type="log4net.Appender.RollingFileAppender">
            <file value="Logs/data.txt" />
            <appendToFile value="true" />
            <maximumFileSize value="100KB" />
            <rollingStyle value="Size" />
            <maxSizeRollBackups value="5" />
            <layout type="log4net.Layout.PatternLayout">
                <conversionPattern
                value="%d{HH:mm:ss.fff} [%t] %-5p %c - %m%n"  />
            </layout>
        </appender>

        <!-- levels: DEBUG, INFO, WARN, ERROR, FATAL -->

        <root>
            <level value="DEBUG"/>
            <appender-ref ref="GeneralLog" />
        </root>

        <logger name="NHibernate" additivity="false">
            <level value="DEBUG"/>
            <appender-ref ref="NHibernateFileLog"/>
        </logger>
        <logger name="Pushable.Data" additivity="false">
            <level value="DEBUG"/>
            <appender-ref ref="DataLog"/>
        </logger>
    </log4net>
</configuration>


The <appender>s are referenced by <logger>s using ‘ref’ attribute of their ‘appender-ref’ child elements, using the same value as the ‘name’ attribute of the <appender>. This type of linking is quite common in xml documents. Now, The first question is : How to list files that are referenced by <logger>s ?
In order to solve this problem you will need to reach the <appender>s that are referenced by each <logger> and then extract the ‘value’ of their <file>s.


Solution:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="1.0">

    <xsl:output method="text"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="log4net">
        <xsl:apply-templates
            select="appender[@name=parent::log4net/logger/appender-ref/@ref]"/>
    </xsl:template>

    <xsl:template match="appender">
        <xsl:value-of
            select="file/@value"/> <xsl:text>&#10;</xsl:text>
    </xsl:template>

</xsl:stylesheet>


The second question is : How to write an xslt script to transform this xml document into an html document with a table that looks like this –

NHibernate Logs/nhibernate.txt
Pushable.Data Logs/data.txt

Solution:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="1.0">

    <xsl:output method="html"/>

    <xsl:template match="log4net">
        <HTML>
            <HEAD>
                <TITLE>www.tewari.info : using xpath axes</TITLE>
            </HEAD>
            <BODY>
                <TABLE border="1" width="25%">
                    <TR><TH>Logger</TH><TH>File</TH></TR>
                    <xsl:apply-templates select="logger"/>
                </TABLE>
            </BODY>
        </HTML>
    </xsl:template>

    <xsl:template match="logger">
            <xsl:variable name="aName" select="appender-ref/@ref"/>
            <TR>
            <TD><xsl:value-of select="@name"/></TD>
            <TD><xsl:value-of
                select="parent::log4net/appender[@name=$aName]/file/@value"/></TD>
            </TR>
    </xsl:template>

</xsl:stylesheet>


Credits :

  • SketchPath is a brilliant tool to play with xpath. I love the “New Context” button : Click on a node and hit “New Context” to change the context for the xpath query processor !