I created a custom appender for CSV output. Note: i had to recompile
log4net to make the RollFile method virtual. Hope this helps.
Scott
private static DevicePointValueCsvAppender CreateCsvAppender(string
modbusMasterName, IEnumerable<DevicePointValue> values)
{
var appender = new DevicePointValueCsvAppender
{
MaxFileSize =
ConfigurationManager.AppSettings[MaxFileSizeName].IfNotNull(max =>
OptionConverter.ToFileSize(max, DefaultMaxFileSize),
DefaultMaxFileSize),
MaxSizeRollBackups =
ConfigurationManager.AppSettings[MaxSizeRollBackupsName].IfNotNull(max
=> Int32.Parse(max), DefaultMaxSizeRollBackups),
Layout = new PatternLayout { ConversionPattern =
PatternLayout.DefaultConversionPattern },
File = String.Format(CultureInfo.InvariantCulture,
FileNameFormat, modbusMasterName),
RollingStyle = RollingFileAppender.RollingMode.Composite,
PreserveLogFileNameExtension = true,
StaticLogFileName = false,
AppendToFile = false
};
appender.ActivateOptions();
return appender;
}
private class DevicePointValueCsvAppender : RollingFileAppender
{
private bool _newFile = true;
/// <summary>
/// Represents the configuration in the current log file target.
/// </summary>
public IEnumerable<DevicePointValue> CurrentConfiguration
{ get; set; }
public void WriteHeaderRow()
{
Debug.Assert(CurrentConfiguration != null, "Property
CurrentConfiguration cannot be null.");
if (!CurrentConfiguration.Any())
return;
string titleRow = new string[] { "Timestamp".DoubleQuote() }
.Concat(CurrentConfiguration.Select(dpv =>
GetEscapedCsvTitle(dpv.DevicePoint).DoubleQuote()))
.Join(",");
DoAppend(CreateLoggingEvent(titleRow));
_newFile = false;
}
public void WriteValuesRow(IEnumerable<DevicePointValue> values)
{
if (values == null)
throw new ArgumentNullException("values");
if (!values.Any())
return;
if (_newFile ||
!ConfigurationsAreEqual(CurrentConfiguration, values))
{
CurrentConfiguration = values;
if (!_newFile)
RollOverSize();
_newFile = false;
WriteHeaderRow();
}
string valueRow = new string[] {
TimeZone.CurrentTimeZone.ToLocalTime(values.First().Timestamp).ToString().DoubleQuote()
}
.Concat(values.Select(dpv =>
dpv.Value.ToString().DoubleQuote()))
.Join(",");
DoAppend(CreateLoggingEvent(valueRow));
}
/// <summary>
/// Escape any double quotes and include the unique device
point info.
/// </summary>
internal static string GetEscapedCsvTitle(DevicePoint devicePoint)
{
return String.Format(CultureInfo.InvariantCulture,
"{0} - ({1}:{2})",
devicePoint.Name.IfNotNull(name =>
name.Replace("\"", "\"\"")),
devicePoint.Address,
devicePoint.ModbusDataType);
}
/// <summary>
/// NOTE: had to recompile log4net to make this method
virtual.
/// </summary>
protected override void RollFile(string fromFile,
string toFile)
{
base.RollFile(fromFile, toFile);
_newFile = true;
}
private static bool
ConfigurationsAreEqual(IEnumerable<DevicePointValue> first,
IEnumerable<DevicePointValue> second)
{
bool areEqual = true;
if (first.Count() != second.Count())
return false;
first.ForEach(second, (left, right) =>
{
return areEqual = left.DevicePoint.Address ==
right.DevicePoint.Address && left.GetType() == right.GetType();
});
return areEqual;
}
private static LoggingEvent CreateLoggingEvent(string message)
{
if (message == null)
throw new ArgumentNullException("message");
var data = new LoggingEventData();
data.Level = Level.Info;
data.Message = message;
return new LoggingEvent(data);
}
}
On Mon, Mar 23, 2009 at 4:32 PM, Navin Mishra <[email protected]> wrote:
> More background. In my application I already use a log4net to log to a text
> file and I use a rolling file appender in the log4net.config file as:
>
>
> <
>
> root>
>
> <
>
> level value="DEBUG" />
>
> <
>
> appender-ref ref="RollingLogFileAppender" />
>
> </
>
> root>
>
>
>
>
>
> Now I want to generrate a CSV file output too but with totally different
> data. Could that be done ? Could I just create another rolling file appender
> in code and use it without the configuration file ?
>
>
>
> Thanks and regards
>
>
>
> Navin
>
> ________________________________
> From: Navin Mishra <[email protected]>
> To: [email protected]
> Sent: Monday, March 23, 2009 1:59:09 PM
> Subject: Generatinf CSV file output
>
> Hi,
>
> Is it possibel to generate a CSV file output with custom data using
> log4net ? I want to have a CSV file per day(which I could do using
> RollingFileAppender) but want to have custom comma delimited fields besides
> timestamp and message in there ? Is it possible ?
>
> Thanks in advance and regards
>
> Navin
>
>