Skip to content

Commit

Permalink
FileTarget - Validate File CreationTimeUtc when non-Windows
Browse files Browse the repository at this point in the history
  • Loading branch information
snakefoot committed Jan 24, 2017
1 parent 6ba58c8 commit c2b8b50
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 13 deletions.
12 changes: 9 additions & 3 deletions src/NLog/Internal/FileAppenders/BaseFileAppender.cs
Original file line number Diff line number Diff line change
Expand Up @@ -341,20 +341,26 @@ private void UpdateCreationTime()
{
#if !SILVERLIGHT
this.CreationTimeUtc = File.GetCreationTimeUtc(this.FileName);
if (this.CreationTimeUtc.Year < 1980)
{
// Non-Windows-FileSystems doesn't always provide correct CreationTime/BirthTime
if (!PlatformDetector.IsDesktopWin32)
{
this.CreationTimeUtc = GetFileLastWriteTimeUtc() ?? DateTime.UtcNow;
}
}
#else
this.CreationTimeUtc = File.GetCreationTime(this.FileName);
#endif
}
else
{
File.Create(this.FileName).Dispose();
this.CreationTimeUtc = DateTime.UtcNow;

#if !SILVERLIGHT
this.CreationTimeUtc = DateTime.UtcNow;
// Set the file's creation time to avoid being thwarted by Windows' Tunneling capabilities (https://support.microsoft.com/en-us/kb/172190).
File.SetCreationTimeUtc(this.FileName, this.CreationTimeUtc);
#else
this.CreationTimeUtc = File.GetCreationTime(this.FileName);
#endif
}
}
Expand Down
24 changes: 23 additions & 1 deletion src/NLog/Internal/FileAppenders/FileAppenderCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,19 @@ public Mutex GetArchiveMutex(string fileName)
result = appender.GetFileCreationTimeUtc();
if (result.HasValue)
{
if (result.Value.Year < 1980)
{
// Non-Windows-FileSystems doesn't always provide correct CreationTime/BirthTime
if (!PlatformDetector.IsDesktopWin32)
{
result = appender.CreationTimeUtc;
if (result.Value.Year < 1980)
{
result = appender.GetFileLastWriteTimeUtc();
}
}
}

// Check if cached value is still valid, and update if not (Will automatically update CreationTimeSource)
if (result.Value != appender.CreationTimeUtc)
{
Expand All @@ -439,7 +452,16 @@ public Mutex GetArchiveMutex(string fileName)
var fileInfo = new FileInfo(filePath);
if (fileInfo.Exists)
{
return Time.TimeSource.Current.FromSystemTime(fileInfo.GetCreationTimeUtc());
result = fileInfo.GetCreationTimeUtc();
if (result.Value.Year < 1980)
{
// Non-Windows-FileSystems doesn't always provide correct CreationTime/BirthTime
if (!PlatformDetector.IsDesktopWin32)
{
result = fileInfo.GetLastWriteTimeUtc();
}
}
return Time.TimeSource.Current.FromSystemTime(result.Value);
}
}

Expand Down
24 changes: 15 additions & 9 deletions src/NLog/Internal/FileAppenders/UnixMultiProcessFileAppender.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,17 @@ BaseFileAppender IFileAppenderFactory.Open(string fileName, ICreateFileParameter

public UnixMultiProcessFileAppender(string fileName, ICreateFileParameters parameters) : base(fileName, parameters)
{
UnixFileInfo fileInfo = null;
bool fileExists = false;
try
{
fileInfo = new UnixFileInfo(fileName);
fileExists = fileInfo.Exists;
}
catch
{
}

int fd = Syscall.open(fileName, OpenFlags.O_CREAT | OpenFlags.O_WRONLY | OpenFlags.O_APPEND, (FilePermissions)(6 | (6 << 3) | (6 << 6)));
if (fd == -1)
{
Expand All @@ -93,21 +104,16 @@ public UnixMultiProcessFileAppender(string fileName, ICreateFileParameters param

try
{
bool fileExists = File.Exists(fileName);

this.file = new UnixStream(fd, true);

long filePosition = this.file.Position;
if (fileExists || filePosition > 0)
{
this.CreationTimeUtc = File.GetCreationTimeUtc(this.FileName);
if (this.CreationTimeUtc < DateTime.UtcNow - TimeSpan.FromSeconds(2) && filePosition == 0)
this.CreationTimeUtc = File.GetCreationTimeUtc(fileName);
if (this.CreationTimeUtc.Year < 1980)
{
// File wasn't created "almost now".
Thread.Sleep(50);
// Having waited for a short amount of time usually means the file creation process has continued
// code execution just enough to the above point where it has fixed up the creation time.
this.CreationTimeUtc = File.GetCreationTimeUtc(this.FileName);
// Non-Windows-FileSystems doesn't always provide correct CreationTime/BirthTime. We fallback to ctime (last inode change)
this.CreationTimeUtc = fileInfo != null ? fileInfo.LastStatusChangeTimeUtc : DateTime.UtcNow;
}
}
else
Expand Down

0 comments on commit c2b8b50

Please sign in to comment.