This project is read-only.
5

Closed

CSV header written multiple times to File target

description

When setting up a file target with a CSV layout, the CSV header is written to the file at the moment the first log message is sent by the application since it has started.
Whether the file is empty or not, the CSV header is always rewritten after restarting the application.
 

Steps to reproduce:

1) Create a console application that logs a single message with configuration file as below:
<configuration>
  <configSections>
    <section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog"/>
  </configSections>
  <nlog autoReload="true">
    <targets>
          <target
            name="AllMessages"
            type="File"
            fileName="${basedir}/log/TestLog.csv"
            archiveFileName="${basedir}/log/TestLog{##}.csv"
            archiveAboveSize="20971520"
            maxArchiveFiles="10"
            archiveNumbering="Rolling">
            <layout type="CSVLayout">
              <column name="Time" layout="${longdate}" />
              <column name="Level" layout="${level}"/>
              <column name="Logger" layout="${logger}"/>
              <column name="Message" layout="${message}" />
            </layout>
          </target>
    </targets>
    <rules>
      <logger name="*" minlevel="Trace" writeTo="AllMessages" />
    </rules>
  </nlog>
</configuration>
 
2) Run the application twice.
 

Proposed fix:

 
I found a way to fix the problem by making a small change to the 2FileTarget.cs" file. It checks whether the file is empty before writing the header.
 
I replaced the following code at line 1082:
 
if (writeHeader && !justData)
{
    byte[] headerBytes = this.GetHeaderBytes();
    if (headerBytes != null)
    {
        appenderToWrite.Write(headerBytes);
    }
}
By the following code:
 
if (writeHeader && !justData)
{
    long fileLength = 0;
    DateTime lastWriteTime;
 
    // Only write header on empty files or if file info cannot be obtained
    if (!appenderToWrite.GetFileInfo(out lastWriteTime, out fileLength) || fileLength == 0)
    {
        byte[] headerBytes = this.GetHeaderBytes();
        if (headerBytes != null)
        {
            appenderToWrite.Write(headerBytes);
        }
    }
}
Closed Oct 2, 2012 at 10:07 PM by Xharze

comments

Xharze wrote Sep 19, 2012 at 11:32 PM

This has been fixed in both the master and v2maintenance branch in the Github repository, https://github.com/NLog/NLog.

liam83 wrote Sep 21, 2012 at 3:37 PM

Has been fixed in the Github repository

wrote Oct 2, 2012 at 10:07 PM

wrote Feb 22, 2013 at 1:12 AM

wrote May 16, 2013 at 12:34 PM

GreenHex wrote Sep 27, 2013 at 6:07 PM

Where is the newest build? When I go to downloads the latest nightly build is Jan 24, 2012, Alpha

liam83 wrote Sep 21, 2012 at 9:37 AM

Has been fixed in the Github repository