logging-log4net-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Scott Alexander <sja...@gmail.com>
Subject Re: Generating CSV file output
Date Thu, 26 Mar 2009 00:45:33 GMT
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 <navin_mshr@yahoo.com> 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 <navin_mshr@yahoo.com>
> To: log4net-user@logging.apache.org
> 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
>
>

Mime
View raw message