Skip to content

Commit e1255a0

Browse files
committed
Added support for customising date in filename by including {Date} placeholder.
This commit simply adds support to include date at the start (instead of the end) of filename whenever needed. Relevant Tests were also added For PathRoller.cs in TemplatedPathRollerTests.cs This commit partially addresses serilog#243
1 parent 5697cc1 commit e1255a0

File tree

2 files changed

+124
-12
lines changed

2 files changed

+124
-12
lines changed

src/Serilog.Sinks.File/Sinks/File/PathRoller.cs

+44-10
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,9 @@ public PathRoller(string path, RollingInterval interval)
4343
_directory = Path.GetFullPath(pathDirectory);
4444
_filenamePrefix = Path.GetFileNameWithoutExtension(path);
4545
_filenameSuffix = Path.GetExtension(path);
46-
_filenameMatcher = new Regex(
47-
"^" +
48-
Regex.Escape(_filenamePrefix) +
49-
"(?<" + PeriodMatchGroup + ">\\d{" + _periodFormat.Length + "})" +
50-
"(?<" + SequenceNumberMatchGroup + ">_[0-9]{3,}){0,1}" +
51-
Regex.Escape(_filenameSuffix) +
52-
"$",
53-
RegexOptions.Compiled);
46+
_filenameMatcher = GetFileNameMatcher();
5447

55-
DirectorySearchPattern = $"{_filenamePrefix}*{_filenameSuffix}";
48+
DirectorySearchPattern = GetDirectorySearchPattern();
5649
}
5750

5851
public string LogFileDirectory => _directory;
@@ -68,7 +61,12 @@ public void GetLogFilePath(DateTime date, int? sequenceNumber, out string path)
6861
if (sequenceNumber != null)
6962
tok += "_" + sequenceNumber.Value.ToString("000", CultureInfo.InvariantCulture);
7063

71-
path = Path.Combine(_directory, _filenamePrefix + tok + _filenameSuffix);
64+
string fileNameReplaced = ReplaceDatePlaceholder(_filenamePrefix, tok);
65+
66+
if (string.Equals(_filenamePrefix, fileNameReplaced, StringComparison.InvariantCultureIgnoreCase))
67+
fileNameReplaced += tok;
68+
69+
path = Path.Combine(_directory, fileNameReplaced + _filenameSuffix);
7270
}
7371

7472
public IEnumerable<RollingLogFile> SelectMatches(IEnumerable<string> filenames)
@@ -110,4 +108,40 @@ public IEnumerable<RollingLogFile> SelectMatches(IEnumerable<string> filenames)
110108
public DateTime? GetCurrentCheckpoint(DateTime instant) => _interval.GetCurrentCheckpoint(instant);
111109

112110
public DateTime? GetNextCheckpoint(DateTime instant) => _interval.GetNextCheckpoint(instant);
111+
112+
Regex GetFileNameMatcher()
113+
{
114+
if (_filenamePrefix.StartsWith("{Date}", StringComparison.InvariantCultureIgnoreCase))
115+
{
116+
return new Regex(
117+
"^" +
118+
"(?<" + PeriodMatchGroup + ">\\d{" + _periodFormat.Length + "})" +
119+
"(?<" + SequenceNumberMatchGroup + ">_[0-9]{3,}){0,1}" +
120+
Regex.Escape(ReplaceDatePlaceholder(_filenamePrefix, string.Empty)) +
121+
Regex.Escape(_filenameSuffix) +
122+
"$",
123+
RegexOptions.Compiled);
124+
}
125+
126+
return new Regex(
127+
"^" +
128+
Regex.Escape(_filenamePrefix) +
129+
"(?<" + PeriodMatchGroup + ">\\d{" + _periodFormat.Length + "})" +
130+
"(?<" + SequenceNumberMatchGroup + ">_[0-9]{3,}){0,1}" +
131+
Regex.Escape(_filenameSuffix) +
132+
"$",
133+
RegexOptions.Compiled);
134+
}
135+
136+
string GetDirectorySearchPattern()
137+
{
138+
return _filenamePrefix.StartsWith("{Date}", StringComparison.InvariantCultureIgnoreCase)
139+
? $"*{ReplaceDatePlaceholder(_filenamePrefix, string.Empty)}{_filenameSuffix}"
140+
: $"{_filenamePrefix}*{_filenameSuffix}";
141+
}
142+
143+
static string ReplaceDatePlaceholder(string filenamePrefix, string dateString)
144+
{
145+
return Regex.Replace(filenamePrefix, @"\{Date}", dateString, RegexOptions.IgnoreCase);
146+
}
113147
}

test/Serilog.Sinks.File.Tests/TemplatedPathRollerTests.cs

+80-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,42 @@
1-
using Xunit;
1+
using System.Globalization;
2+
using Xunit;
23

34
namespace Serilog.Sinks.File.Tests;
45

56
public class PathRollerTests
67
{
8+
[Theory]
9+
[InlineData(null)]
10+
[InlineData(2)]
11+
public void GetLogFilePath_WhenPathContainsDateTokenAtStart_ShouldReplaceDateToken(int? sequenceNumber)
12+
{
13+
var now = new DateTime(2013, 7, 14, 3, 24, 9, 980);
14+
string expectedName = sequenceNumber is null
15+
? $"{now:yyyyMMdd}-logs.txt"
16+
: $"{now:yyyyMMdd}_{sequenceNumber.Value.ToString("000", CultureInfo.InvariantCulture)}-logs.txt";
17+
18+
var roller = new PathRoller(Path.Combine("Logs", "{date}-logs.txt"), RollingInterval.Day);
19+
roller.GetLogFilePath(now, sequenceNumber, out string actualName);
20+
21+
AssertEqualAbsolute(Path.Combine("Logs", expectedName), actualName);
22+
}
23+
24+
[Theory]
25+
[InlineData(null)]
26+
[InlineData(2)]
27+
public void GetLogFilePath_WhenPathContainsDateTokenAtEnd_ShouldReplaceDateToken(int? sequenceNumber)
28+
{
29+
var now = new DateTime(2013, 7, 14, 3, 24, 9, 980);
30+
string expectedName = sequenceNumber is null
31+
? $"logs-{now:yyyyMMdd}.txt"
32+
: $"logs-{now:yyyyMMdd}_{sequenceNumber.Value.ToString("000", CultureInfo.InvariantCulture)}.txt";
33+
34+
var roller = new PathRoller(Path.Combine("Logs", "logs-{Date}.txt"), RollingInterval.Day);
35+
roller.GetLogFilePath(now, sequenceNumber, out string actualName);
36+
37+
AssertEqualAbsolute(Path.Combine("Logs", expectedName), actualName);
38+
}
39+
740
[Fact]
841
public void TheLogFileIncludesDateToken()
942
{
@@ -22,6 +55,15 @@ public void ANonZeroIncrementIsIncludedAndPadded()
2255
AssertEqualAbsolute(Path.Combine("Logs", "log-20130714_012.txt"), path);
2356
}
2457

58+
[Fact]
59+
public void ANonZeroIncrementIsIncludedAndPaddedWhenDatePlaceHolderExists()
60+
{
61+
var roller = new PathRoller(Path.Combine("Logs", "{Date}-log.txt"), RollingInterval.Day);
62+
var now = new DateTime(2013, 7, 14, 3, 24, 9, 980);
63+
roller.GetLogFilePath(now, 12, out var path);
64+
AssertEqualAbsolute(Path.Combine("Logs", "20130714_012-log.txt"), path);
65+
}
66+
2567
static void AssertEqualAbsolute(string path1, string path2)
2668
{
2769
var abs1 = Path.GetFullPath(path1);
@@ -36,6 +78,13 @@ public void TheRollerReturnsTheLogFileDirectory()
3678
AssertEqualAbsolute("Logs", roller.LogFileDirectory);
3779
}
3880

81+
[Fact]
82+
public void TheRollerReturnsTheLogFileDirectoryWhenDatePlaceHolderExists()
83+
{
84+
var roller = new PathRoller(Path.Combine("Logs", "{Date}-log.txt"), RollingInterval.Day);
85+
AssertEqualAbsolute("Logs", roller.LogFileDirectory);
86+
}
87+
3988
[Fact]
4089
public void TheLogFileIsNotRequiredToIncludeAnExtension()
4190
{
@@ -45,6 +94,15 @@ public void TheLogFileIsNotRequiredToIncludeAnExtension()
4594
AssertEqualAbsolute(Path.Combine("Logs", "log-20130714"), path);
4695
}
4796

97+
[Fact]
98+
public void TheLogFileIsNotRequiredToIncludeAnExtensionWhenDatePlaceHolderExists()
99+
{
100+
var roller = new PathRoller(Path.Combine("Logs", "{Date}-log"), RollingInterval.Day);
101+
var now = new DateTime(2013, 7, 14, 3, 24, 9, 980);
102+
roller.GetLogFilePath(now, null, out var path);
103+
AssertEqualAbsolute(Path.Combine("Logs", "20130714-log"), path);
104+
}
105+
48106
[Fact]
49107
public void TheLogFileIsNotRequiredToIncludeADirectory()
50108
{
@@ -54,13 +112,24 @@ public void TheLogFileIsNotRequiredToIncludeADirectory()
54112
AssertEqualAbsolute("log-20130714", path);
55113
}
56114

115+
[Fact]
116+
public void TheLogFileIsNotRequiredToIncludeADirectoryWhenDatePlaceHolderExists()
117+
{
118+
var roller = new PathRoller("{Date}-log", RollingInterval.Day);
119+
var now = new DateTime(2013, 7, 14, 3, 24, 9, 980);
120+
roller.GetLogFilePath(now, null, out var path);
121+
AssertEqualAbsolute("20130714-log", path);
122+
}
123+
57124
[Fact]
58125
public void MatchingExcludesSimilarButNonMatchingFiles()
59126
{
60127
var roller = new PathRoller("log-.txt", RollingInterval.Day);
61128
const string similar1 = "log-0.txt";
62129
const string similar2 = "log-hello.txt";
63-
var matched = roller.SelectMatches(new[] { similar1, similar2 });
130+
const string similar3 = "0-log.txt";
131+
const string similar4 = "hello-log.txt";
132+
var matched = roller.SelectMatches(new[] { similar1, similar2, similar3, similar4 });
64133
Assert.Empty(matched);
65134
}
66135

@@ -71,9 +140,17 @@ public void TheDirectorSearchPatternUsesWildcardInPlaceOfDate()
71140
Assert.Equal("log-*.txt", roller.DirectorySearchPattern);
72141
}
73142

143+
[Fact]
144+
public void TheDirectorSearchPatternUsesWildcardInPlaceOfDateWhenDatePlaceHolderExists()
145+
{
146+
var roller = new PathRoller(Path.Combine("Logs", "{Date}-log.txt"), RollingInterval.Day);
147+
Assert.Equal("*-log.txt", roller.DirectorySearchPattern);
148+
}
149+
74150
[Theory]
75151
[InlineData("log-.txt", "log-20131210.txt", "log-20131210_031.txt", RollingInterval.Day)]
76152
[InlineData("log-.txt", "log-2013121013.txt", "log-2013121013_031.txt", RollingInterval.Hour)]
153+
[InlineData("{Date}-log.txt", "2013121013-log.txt", "2013121013_031-log.txt", RollingInterval.Hour)]
77154
public void MatchingSelectsFiles(string template, string zeroth, string thirtyFirst, RollingInterval interval)
78155
{
79156
var roller = new PathRoller(template, interval);
@@ -86,6 +163,7 @@ public void MatchingSelectsFiles(string template, string zeroth, string thirtyFi
86163
[Theory]
87164
[InlineData("log-.txt", "log-20150101.txt", "log-20141231.txt", RollingInterval.Day)]
88165
[InlineData("log-.txt", "log-2015010110.txt", "log-2015010109.txt", RollingInterval.Hour)]
166+
[InlineData("{Date}-log.txt", "2015010110-log.txt", "2015010109-log.txt", RollingInterval.Hour)]
89167
public void MatchingParsesSubstitutions(string template, string newer, string older, RollingInterval interval)
90168
{
91169
var roller = new PathRoller(template, interval);

0 commit comments

Comments
 (0)