diff --git a/src/Serilog.Sinks.File/FileLoggerConfigurationExtensions.cs b/src/Serilog.Sinks.File/FileLoggerConfigurationExtensions.cs
index 3518322..0e59f2a 100644
--- a/src/Serilog.Sinks.File/FileLoggerConfigurationExtensions.cs
+++ b/src/Serilog.Sinks.File/FileLoggerConfigurationExtensions.cs
@@ -23,6 +23,7 @@
using Serilog.Formatting;
using Serilog.Formatting.Display;
using Serilog.Formatting.Json;
+using Serilog.Interval;
using Serilog.Sinks.File;
// ReSharper disable RedundantArgumentDefaultValue, MethodOverloadWithOptionalParameter
@@ -151,7 +152,7 @@ public static LoggerConfiguration File(
bool buffered,
bool shared,
TimeSpan? flushToDiskInterval,
- RollingInterval rollingInterval,
+ Interval.RollingInterval rollingInterval,
bool rollOnFileSizeLimit,
int? retainedFileCountLimit,
Encoding encoding)
@@ -166,7 +167,7 @@ public static LoggerConfiguration File(
/// Logger sink configuration.
/// A formatter, such as , to convert the log events into
/// text for the file. If control of regular text formatting is required, use the other
- /// overload of
+ /// overload of
/// and specify the outputTemplate parameter instead.
///
/// Path to the file.
@@ -199,7 +200,7 @@ public static LoggerConfiguration File(
bool buffered,
bool shared,
TimeSpan? flushToDiskInterval,
- RollingInterval rollingInterval,
+ Interval.RollingInterval rollingInterval,
bool rollOnFileSizeLimit,
int? retainedFileCountLimit,
Encoding encoding)
@@ -259,7 +260,7 @@ public static LoggerConfiguration File(
bool buffered = false,
bool shared = false,
TimeSpan? flushToDiskInterval = null,
- RollingInterval rollingInterval = RollingInterval.Infinite,
+ Interval.RollingInterval rollingInterval = null,
bool rollOnFileSizeLimit = false,
int? retainedFileCountLimit = DefaultRetainedFileCountLimit,
Encoding? encoding = null,
@@ -282,7 +283,7 @@ public static LoggerConfiguration File(
/// Logger sink configuration.
/// A formatter, such as , to convert the log events into
/// text for the file. If control of regular text formatting is required, use the other
- /// overload of
+ /// overload of
/// and specify the outputTemplate parameter instead.
///
/// Path to the file.
@@ -328,7 +329,7 @@ public static LoggerConfiguration File(
bool buffered = false,
bool shared = false,
TimeSpan? flushToDiskInterval = null,
- RollingInterval rollingInterval = RollingInterval.Infinite,
+ Interval.RollingInterval rollingInterval = null,
bool rollOnFileSizeLimit = false,
int? retainedFileCountLimit = DefaultRetainedFileCountLimit,
Encoding? encoding = null,
@@ -340,7 +341,7 @@ public static LoggerConfiguration File(
if (path == null) throw new ArgumentNullException(nameof(path));
return ConfigureFile(sinkConfiguration.Sink, formatter, path, restrictedToMinimumLevel, fileSizeLimitBytes, levelSwitch,
- buffered, false, shared, flushToDiskInterval, encoding, rollingInterval, rollOnFileSizeLimit,
+ buffered, false, shared, flushToDiskInterval, encoding, rollingInterval ?? new InfiniteRollingInterval(), rollOnFileSizeLimit,
retainedFileCountLimit, hooks, retainedFileTimeLimit);
}
@@ -510,8 +511,8 @@ static LoggerConfiguration ConfigureFile(
bool propagateExceptions,
bool shared,
TimeSpan? flushToDiskInterval,
- Encoding? encoding,
- RollingInterval rollingInterval,
+ Encoding encoding,
+ Interval.RollingInterval rollingInterval,
bool rollOnFileSizeLimit,
int? retainedFileCountLimit,
FileLifecycleHooks? hooks,
@@ -530,7 +531,7 @@ static LoggerConfiguration ConfigureFile(
try
{
- if (rollOnFileSizeLimit || rollingInterval != RollingInterval.Infinite)
+ if (rollOnFileSizeLimit || !(rollingInterval is InfiniteRollingInterval))
{
sink = new RollingFileSink(path, formatter, fileSizeLimitBytes, retainedFileCountLimit, encoding, buffered, shared, rollingInterval, rollOnFileSizeLimit, hooks, retainedFileTimeLimit);
}
diff --git a/src/Serilog.Sinks.File/Interval/DayRollingInterval.cs b/src/Serilog.Sinks.File/Interval/DayRollingInterval.cs
new file mode 100644
index 0000000..46c5747
--- /dev/null
+++ b/src/Serilog.Sinks.File/Interval/DayRollingInterval.cs
@@ -0,0 +1,27 @@
+using System;
+
+namespace Serilog.Interval
+{
+ ///
+ /// Day Rolling Interval
+ ///
+ public class DayRollingInterval : RollingInterval
+ {
+ ///
+ /// Format of rolling file name
+ ///
+ public override string Format => "yyyyMMdd";
+
+ ///
+ /// Normalize time to current checkpoint
+ ///
+ public override DateTime? CurrentCheckpoint(DateTime instant) => Normalize(instant);
+
+ ///
+ /// Calculate next checkpoint from time
+ ///
+ public override DateTime? NextCheckpoint(DateTime instant) => Normalize(instant).AddDays(1);
+
+ private static DateTime Normalize(DateTime instant) => new DateTime(instant.Year, instant.Month, instant.Day, 0, 0, 0, instant.Kind);
+ }
+}
diff --git a/src/Serilog.Sinks.File/Interval/HourRollingInterval.cs b/src/Serilog.Sinks.File/Interval/HourRollingInterval.cs
new file mode 100644
index 0000000..de953ef
--- /dev/null
+++ b/src/Serilog.Sinks.File/Interval/HourRollingInterval.cs
@@ -0,0 +1,27 @@
+using System;
+
+namespace Serilog.Interval
+{
+ ///
+ /// Hour Rolling Interval
+ ///
+ public class HourRollingInterval : RollingInterval
+ {
+ ///
+ /// Format of rolling file name
+ ///
+ public override string Format => "yyyyMMddHH";
+
+ ///
+ /// Normalize time to current checkpoint
+ ///
+ public override DateTime? CurrentCheckpoint(DateTime instant) => Normalize(instant);
+
+ ///
+ /// Calculate next checkpoint from time
+ ///
+ public override DateTime? NextCheckpoint(DateTime instant) => Normalize(instant).AddHours(1);
+
+ private static DateTime Normalize(DateTime instant) => new DateTime(instant.Year, instant.Month, instant.Day, instant.Hour, 0, 0, instant.Kind);
+ }
+}
diff --git a/src/Serilog.Sinks.File/Interval/InfiniteRollingInterval.cs b/src/Serilog.Sinks.File/Interval/InfiniteRollingInterval.cs
new file mode 100644
index 0000000..1fa4af6
--- /dev/null
+++ b/src/Serilog.Sinks.File/Interval/InfiniteRollingInterval.cs
@@ -0,0 +1,25 @@
+using System;
+
+namespace Serilog.Interval
+{
+ ///
+ /// Infinite Rolling Interval
+ ///
+ public class InfiniteRollingInterval : RollingInterval
+ {
+ ///
+ /// Format of rolling file name
+ ///
+ public override string Format => string.Empty;
+
+ ///
+ /// Normalize time to current checkpoint
+ ///
+ public override DateTime? CurrentCheckpoint(DateTime instant) => null;
+
+ ///
+ /// Calculate next checkpoint from time
+ ///
+ public override DateTime? NextCheckpoint(DateTime instant) => null;
+ }
+}
diff --git a/src/Serilog.Sinks.File/Interval/MinuteRollingInterval.cs b/src/Serilog.Sinks.File/Interval/MinuteRollingInterval.cs
new file mode 100644
index 0000000..1b49b2c
--- /dev/null
+++ b/src/Serilog.Sinks.File/Interval/MinuteRollingInterval.cs
@@ -0,0 +1,27 @@
+using System;
+
+namespace Serilog.Interval
+{
+ ///
+ /// Minute Rolling Interval
+ ///
+ public class MinuteRollingInterval : RollingInterval
+ {
+ ///
+ /// Format of rolling file name
+ ///
+ public override string Format => "yyyyMMddHHmm";
+
+ ///
+ /// Normalize time to current checkpoint
+ ///
+ public override DateTime? CurrentCheckpoint(DateTime instant) => Normalize(instant);
+
+ ///
+ /// Calculate next checkpoint from time
+ ///
+ public override DateTime? NextCheckpoint(DateTime instant) => Normalize(instant).AddMinutes(1);
+
+ private static DateTime Normalize(DateTime instant) => new DateTime(instant.Year, instant.Month, instant.Day, instant.Hour, instant.Minute, 0, instant.Kind);
+ }
+}
diff --git a/src/Serilog.Sinks.File/Interval/MonthRollingInterval.cs b/src/Serilog.Sinks.File/Interval/MonthRollingInterval.cs
new file mode 100644
index 0000000..19591ee
--- /dev/null
+++ b/src/Serilog.Sinks.File/Interval/MonthRollingInterval.cs
@@ -0,0 +1,27 @@
+using System;
+
+namespace Serilog.Interval
+{
+ ///
+ /// Month Rolling Interval
+ ///
+ public class MonthRollingInterval : RollingInterval
+ {
+ ///
+ /// Format of rolling file name
+ ///
+ public override string Format => "yyyyMM";
+
+ ///
+ /// Normalize time to current checkpoint
+ ///
+ public override DateTime? CurrentCheckpoint(DateTime instant) => Normalize(instant);
+
+ ///
+ /// Calculate next checkpoint from time
+ ///
+ public override DateTime? NextCheckpoint(DateTime instant) => Normalize(instant).AddMonths(1);
+
+ private static DateTime Normalize(DateTime instant) => new DateTime(instant.Year, instant.Month, 1, 0, 0, 0, instant.Kind);
+ }
+}
diff --git a/src/Serilog.Sinks.File/Interval/RollingInterval.cs b/src/Serilog.Sinks.File/Interval/RollingInterval.cs
new file mode 100644
index 0000000..3c9a298
--- /dev/null
+++ b/src/Serilog.Sinks.File/Interval/RollingInterval.cs
@@ -0,0 +1,55 @@
+using System;
+
+namespace Serilog.Interval
+{
+ ///
+ /// Specifies the frequency at which the log file should roll.
+ ///
+ public abstract class RollingInterval
+ {
+ ///
+ /// Format of rolling file name
+ ///
+ public abstract string Format { get; }
+
+ ///
+ /// Normalize time to current checkpoint (year, month and etc)
+ ///
+ ///
+ ///
+ public abstract DateTime? CurrentCheckpoint(DateTime instant);
+
+ ///
+ /// Calculate next checkpoint from time
+ ///
+ ///
+ ///
+ public abstract DateTime? NextCheckpoint(DateTime instant);
+
+ ///
+ /// Create RollInterval
+ ///
+ ///
+ ///
+ public static implicit operator RollingInterval(Serilog.RollingInterval intervalType)
+ {
+ switch (intervalType)
+ {
+ case Serilog.RollingInterval.Infinite:
+ return new InfiniteRollingInterval();
+ case Serilog.RollingInterval.Year:
+ return new YearRollingInterval();
+ case Serilog.RollingInterval.Month:
+ return new MonthRollingInterval();
+ case Serilog.RollingInterval.Day:
+ return new DayRollingInterval();
+ case Serilog.RollingInterval.Hour:
+ return new HourRollingInterval();
+ case Serilog.RollingInterval.Minute:
+ return new MinuteRollingInterval();
+ default:
+ throw new ArgumentException("Invalid rolling interval");
+ }
+ }
+ }
+}
diff --git a/src/Serilog.Sinks.File/Interval/YearRollingInterval.cs b/src/Serilog.Sinks.File/Interval/YearRollingInterval.cs
new file mode 100644
index 0000000..7771c3b
--- /dev/null
+++ b/src/Serilog.Sinks.File/Interval/YearRollingInterval.cs
@@ -0,0 +1,27 @@
+using System;
+
+namespace Serilog.Interval
+{
+ ///
+ /// Year Rolling Interval
+ ///
+ public class YearRollingInterval : RollingInterval
+ {
+ ///
+ /// Format of rolling file name
+ ///
+ public override string Format => "yyyy";
+
+ ///
+ /// Normalize time to current checkpoint
+ ///
+ public override DateTime? CurrentCheckpoint(DateTime instant) => Normalize(instant);
+
+ ///
+ /// Calculate next checkpoint from time
+ ///
+ public override DateTime? NextCheckpoint(DateTime instant) => Normalize(instant).AddYears(1);
+
+ private static DateTime Normalize(DateTime instant) => new DateTime(instant.Year, 1, 1, 0, 0, 0, instant.Kind);
+ }
+}
diff --git a/src/Serilog.Sinks.File/Sinks/File/PathRoller.cs b/src/Serilog.Sinks.File/Sinks/File/PathRoller.cs
index 79a6915..e618298 100644
--- a/src/Serilog.Sinks.File/Sinks/File/PathRoller.cs
+++ b/src/Serilog.Sinks.File/Sinks/File/PathRoller.cs
@@ -30,14 +30,14 @@ class PathRoller
readonly string _filenameSuffix;
readonly Regex _filenameMatcher;
- readonly RollingInterval _interval;
+ readonly Interval.RollingInterval _interval;
readonly string _periodFormat;
- public PathRoller(string path, RollingInterval interval)
+ public PathRoller(string path, Interval.RollingInterval interval)
{
if (path == null) throw new ArgumentNullException(nameof(path));
_interval = interval;
- _periodFormat = interval.GetFormat();
+ _periodFormat = interval.Format;
var pathDirectory = Path.GetDirectoryName(path);
if (string.IsNullOrEmpty(pathDirectory))
@@ -110,8 +110,8 @@ public IEnumerable SelectMatches(IEnumerable filenames)
}
}
- public DateTime? GetCurrentCheckpoint(DateTime instant) => _interval.GetCurrentCheckpoint(instant);
+ public DateTime? GetCurrentCheckpoint(DateTime instant) => _interval.CurrentCheckpoint(instant);
- public DateTime? GetNextCheckpoint(DateTime instant) => _interval.GetNextCheckpoint(instant);
+ public DateTime? GetNextCheckpoint(DateTime instant) => _interval.NextCheckpoint(instant);
}
}
diff --git a/src/Serilog.Sinks.File/Sinks/File/RollingFileSink.cs b/src/Serilog.Sinks.File/Sinks/File/RollingFileSink.cs
index dccb802..44e94f2 100644
--- a/src/Serilog.Sinks.File/Sinks/File/RollingFileSink.cs
+++ b/src/Serilog.Sinks.File/Sinks/File/RollingFileSink.cs
@@ -49,7 +49,7 @@ public RollingFileSink(string path,
Encoding? encoding,
bool buffered,
bool shared,
- RollingInterval rollingInterval,
+ Interval.RollingInterval rollingInterval,
bool rollOnFileSizeLimit,
FileLifecycleHooks? hooks,
TimeSpan? retainedFileTimeLimit)
diff --git a/src/Serilog.Sinks.File/Sinks/File/RollingIntervalExtensions.cs b/src/Serilog.Sinks.File/Sinks/File/RollingIntervalExtensions.cs
deleted file mode 100644
index 2c9e2fd..0000000
--- a/src/Serilog.Sinks.File/Sinks/File/RollingIntervalExtensions.cs
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright 2017 Serilog Contributors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-
-namespace Serilog.Sinks.File
-{
- static class RollingIntervalExtensions
- {
- public static string GetFormat(this RollingInterval interval)
- {
- switch (interval)
- {
- case RollingInterval.Infinite:
- return "";
- case RollingInterval.Year:
- return "yyyy";
- case RollingInterval.Month:
- return "yyyyMM";
- case RollingInterval.Day:
- return "yyyyMMdd";
- case RollingInterval.Hour:
- return "yyyyMMddHH";
- case RollingInterval.Minute:
- return "yyyyMMddHHmm";
- default:
- throw new ArgumentException("Invalid rolling interval");
- }
- }
-
- public static DateTime? GetCurrentCheckpoint(this RollingInterval interval, DateTime instant)
- {
- switch (interval)
- {
- case RollingInterval.Infinite:
- return null;
- case RollingInterval.Year:
- return new DateTime(instant.Year, 1, 1, 0, 0, 0, instant.Kind);
- case RollingInterval.Month:
- return new DateTime(instant.Year, instant.Month, 1, 0, 0, 0, instant.Kind);
- case RollingInterval.Day:
- return new DateTime(instant.Year, instant.Month, instant.Day, 0, 0, 0, instant.Kind);
- case RollingInterval.Hour:
- return new DateTime(instant.Year, instant.Month, instant.Day, instant.Hour, 0, 0, instant.Kind);
- case RollingInterval.Minute:
- return new DateTime(instant.Year, instant.Month, instant.Day, instant.Hour, instant.Minute, 0, instant.Kind);
- default:
- throw new ArgumentException("Invalid rolling interval");
- }
- }
-
- public static DateTime? GetNextCheckpoint(this RollingInterval interval, DateTime instant)
- {
- var current = GetCurrentCheckpoint(interval, instant);
- if (current == null)
- return null;
-
- switch (interval)
- {
- case RollingInterval.Year:
- return current.Value.AddYears(1);
- case RollingInterval.Month:
- return current.Value.AddMonths(1);
- case RollingInterval.Day:
- return current.Value.AddDays(1);
- case RollingInterval.Hour:
- return current.Value.AddHours(1);
- case RollingInterval.Minute:
- return current.Value.AddMinutes(1);
- default:
- throw new ArgumentException("Invalid rolling interval");
- }
- }
- }
-}
diff --git a/test/Serilog.Sinks.File.Tests/RollingIntervalExtensionsTests.cs b/test/Serilog.Sinks.File.Tests/RollingIntervalExtensionsTests.cs
index 404d5b4..069fb9d 100644
--- a/test/Serilog.Sinks.File.Tests/RollingIntervalExtensionsTests.cs
+++ b/test/Serilog.Sinks.File.Tests/RollingIntervalExtensionsTests.cs
@@ -24,10 +24,11 @@ public class RollingIntervalExtensionsTests
[MemberData(nameof(IntervalInstantCurrentNextCheckpoint))]
public void NextIntervalTests(RollingInterval interval, DateTime instant, DateTime? currentCheckpoint, DateTime? nextCheckpoint)
{
- var current = interval.GetCurrentCheckpoint(instant);
+ Interval.RollingInterval rollingInterval = interval;
+ var current = rollingInterval.CurrentCheckpoint(instant);
Assert.Equal(currentCheckpoint, current);
- var next = interval.GetNextCheckpoint(instant);
+ var next = rollingInterval.NextCheckpoint(instant);
Assert.Equal(nextCheckpoint, next);
}
}