The PatternString used for the Header and Footer is converted to a string at
configuration time using the internal PatternStringConverter class. You can
easily write your own PatternLayout:
public class HeaderFooterPatternStringLayout : PatternLayout
{
private PatternString headerPatternString;
private PatternString footerPatternString;
public override string Header
{
get
{
return headerPatternString.Format();
}
set
{
base.Header = value;
headerPatternString = new PatternString(base.Header);
}
}
public override string Footer
{
get
{
return footerPatternString.Format();
}
set
{
base.Footer = value;
footerPatternString = new PatternString(base.Footer);
}
}
}
<layout type="Company.Logging.HeaderFooterPatternStringLayout, Company.Logging">
<header value="..." />
<footer value="..." />
<conversionPattern value="..." />
</layout>
Since you're already going through the trouble of writing a custom
PatternLayout I'd go all in and provide default values:
public class DefaultHeaderFooterPatternStringLayout : PatternLayout
{
public const string DEFAULT_HEADER_PATTERN = "%newline**** Trace Opened
Local: %date{yyyy-MM-dd HH:mm:ss.fff} UTC: %utcdate{yyyy-MM-dd HH:mm:ss.fff}
****%newline";
public const string DEFAULT_FOOTER_PATTERN = "****Trace Closed
%date{yyyy-MM-dd HH:mm:ss.fff} ****%newline";
public const string DEFAULT_CONVERSION_PATTERN = "%d{dd HH:mm:ss.fff} [%4t]
%P{instance}::%M - %m%n";
private PatternString headerPatternString;
private PatternString footerPatternString;
public DefaultHeaderFooterPatternStringLayout() :
base(DEFAULT_CONVERSION_PATTERN)
{
headerPatternString = new PatternString(DEFAULT_HEADER_PATTERN);
footerPatternString = new PatternString(DEFAULT_FOOTER_PATTERN);
}
public override string Header
{
get
{
return headerPatternString.Format();
}
set
{
base.Header = value;
headerPatternString = new PatternString(base.Header);
}
}
public override string Footer
{
get
{
return footerPatternString.Format();
}
set
{
base.Footer = value;
footerPatternString = new PatternString(base.Footer);
}
}
}
so your layout is just:
<layout type="Company.Logging.DefaultHeaderFooterPatternStringLayout,
Company.Logging" />
I can't think of a good reason why the the Header and Footer properties aren't
PatternStrings that are calculated at run-time instead of once at configuration
time.
----- Original Message ----
From: Roy Chastain <[EMAIL PROTECTED]>
To: [email protected]
Sent: Wednesday, May 7, 2008 8:34:34 AM
Subject: Using log4net.Util.PatternString in a PatternLayout
I have the following layout defined for a RollingFileAppender (log4Net
1.2.10)
<layout type="log4net.Layout.PatternLayout">
<param name="Header" type="log4net.Util.PatternString"
value="%newline**** Trace Opened Local: %date{yyyy-MM-dd
HH:mm:ss.fff} UTC: %utcdate{yyyy-MM-dd HH:mm:ss.fff} ****%newline"
/>
<param name="Footer" type="log4net.Util.PatternString" value="****
Trace Closed %date{yyyy-MM-dd HH:mm:ss.fff} ****%newline" />
<param name="ConversionPattern" value="%d{dd HH:mm:ss.fff} [%4t]
%P{instance}::%M - %m%n" />
</layout>
The idea is to place the current date and time in the header and footer
of each log file as it rolls over. Instead each header and footer
receives the same date/time. (The date/time is the date/time the
original file was opened.)
This action is certainly not what was expected, and I do not believe a
useful implementation.
Can someone say that the result is has expected and, if so, please give
some pointers on how to implement a 'current date/time' for the headers
and footers?
Thanks
------------------------------------------------------------------------
----------
Roy Chastain