Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FileTarget fix: CreatedDir setting when replacing file content #1446

Merged
merged 1 commit into from May 8, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
36 changes: 25 additions & 11 deletions src/NLog/Targets/FileTarget.cs
Expand Up @@ -1822,7 +1822,7 @@ private void WriteToFile(string fileName, LogEventInfo logEvent, byte[] bytes, b
{
if (this.ReplaceFileContentsOnEachWrite)
{
ReplaceFileContent(fileName, bytes);
ReplaceFileContent(fileName, bytes, true);
return;
}

Expand Down Expand Up @@ -1957,24 +1957,38 @@ private void ProcessOnStartup(string fileName, LogEventInfo logEvent)
/// </summary>
/// <param name="fileName">The name of the file to be written.</param>
/// <param name="bytes">Sequence of <see langword="byte"/> to be written in the content section of the file.</param>
/// <param name="firstAttempt">First attempt to write?</param>
/// <remarks>This method is used when the content of the log file is re-written on every write.</remarks>
private void ReplaceFileContent(string fileName, byte[] bytes)
private void ReplaceFileContent(string fileName, byte[] bytes, bool firstAttempt)
{
using (FileStream fs = File.Create(fileName))
try
{
byte[] headerBytes = this.GetHeaderBytes();
if (headerBytes != null)
using (FileStream fs = File.Create(fileName))
{
fs.Write(headerBytes, 0, headerBytes.Length);
}
byte[] headerBytes = this.GetHeaderBytes();
if (headerBytes != null)
{
fs.Write(headerBytes, 0, headerBytes.Length);
}

fs.Write(bytes, 0, bytes.Length);
fs.Write(bytes, 0, bytes.Length);

byte[] footerBytes = this.GetFooterBytes();
if (footerBytes != null)
byte[] footerBytes = this.GetFooterBytes();
if (footerBytes != null)
{
fs.Write(footerBytes, 0, footerBytes.Length);
}
}
}
catch (DirectoryNotFoundException)
{
if (!this.CreateDirs || !firstAttempt)
{
fs.Write(footerBytes, 0, footerBytes.Length);
throw;
}
Directory.CreateDirectory(Path.GetDirectoryName(fileName));
//retry.
ReplaceFileContent(fileName, bytes, false);
}
}

Expand Down
43 changes: 43 additions & 0 deletions tests/NLog.UnitTests/Targets/FileTargetTests.cs
Expand Up @@ -414,6 +414,48 @@ public void ReplaceFileContentsOnEachWriteTest(bool useHeader, bool useFooter)
}
}


[Theory]
[InlineData(true)]
[InlineData(false)]
public void ReplaceFileContentsOnEachWrite_CreateDirs(bool createDirs)
{

LogManager.ThrowExceptions = false;

var tempPath = Path.Combine(Path.GetTempPath(), "dir_" + Guid.NewGuid().ToString());
var logfile = Path.Combine(tempPath, "log.log");

try
{
var target = new FileTarget
{
FileName = logfile,
ReplaceFileContentsOnEachWrite = true,
CreateDirs = createDirs
};
var config = new LoggingConfiguration();

config.AddTarget("logfile", target);

config.AddRuleForAllLevels(target);

LogManager.Configuration = config;

ILogger logger = LogManager.GetLogger("A");
logger.Info("a");

Assert.Equal(createDirs, Directory.Exists(tempPath));
}
finally
{
if (File.Exists(logfile))
File.Delete(logfile);
if (Directory.Exists(tempPath))
Directory.Delete(tempPath, true);
}
}

[Fact]
public void CreateDirsTest()
{
Expand Down Expand Up @@ -2662,6 +2704,7 @@ public void BatchErrorHandlingTest()
Assert.NotNull(exceptions[2]);
Assert.NotNull(exceptions[3]);
}

}


Expand Down