diff --git a/Build.ps1 b/Build.ps1
index e0eebae..06a36af 100644
--- a/Build.ps1
+++ b/Build.ps1
@@ -1,46 +1,42 @@
-echo "build: Build started"
+Write-Output "build: Build started"
Push-Location $PSScriptRoot
if(Test-Path .\artifacts) {
- echo "build: Cleaning .\artifacts"
- Remove-Item .\artifacts -Force -Recurse
+ Write-Output "build: Cleaning ./artifacts"
+ Remove-Item ./artifacts -Force -Recurse
}
& dotnet restore --no-cache
-$branch = @{ $true = $env:APPVEYOR_REPO_BRANCH; $false = $(git symbolic-ref --short -q HEAD) }[$env:APPVEYOR_REPO_BRANCH -ne $NULL];
-$revision = @{ $true = "{0:00000}" -f [convert]::ToInt32("0" + $env:APPVEYOR_BUILD_NUMBER, 10); $false = "local" }[$env:APPVEYOR_BUILD_NUMBER -ne $NULL];
+$branch = @{ $true = $env:APPVEYOR_REPO_BRANCH; $false = $(git symbolic-ref --short -q HEAD) }[$NULL -ne $env:APPVEYOR_REPO_BRANCH];
+$revision = @{ $true = "{0:00000}" -f [convert]::ToInt32("0" + $env:APPVEYOR_BUILD_NUMBER, 10); $false = "local" }[$NULL -ne $env:APPVEYOR_BUILD_NUMBER];
$suffix = @{ $true = ""; $false = "$($branch.Substring(0, [math]::Min(10,$branch.Length)))-$revision"}[$branch -eq "main" -and $revision -ne "local"]
-$commitHash = $(git rev-parse --short HEAD)
-$buildSuffix = @{ $true = "$($suffix)-$($commitHash)"; $false = "$($branch)-$($commitHash)" }[$suffix -ne ""]
-echo "build: Package version suffix is $suffix"
-echo "build: Build version suffix is $buildSuffix"
+Write-Output "build: Package version suffix is $suffix"
-foreach ($src in ls src/*) {
+foreach ($src in Get-ChildItem src/*) {
Push-Location $src
- echo "build: Packaging project in $src"
+ Write-Output "build: Packaging project in $src"
- & dotnet build -c Release --version-suffix=$buildSuffix -p:EnableSourceLink=true
if ($suffix) {
- & dotnet pack -c Release -o ..\..\artifacts --version-suffix=$suffix --no-build
+ & dotnet pack -c Release --include-source -o ../../artifacts --version-suffix=$suffix
} else {
- & dotnet pack -c Release -o ..\..\artifacts --no-build
+ & dotnet pack -c Release --include-source -o ../../artifacts
}
- if($LASTEXITCODE -ne 0) { exit 1 }
+ if($LASTEXITCODE -ne 0) { throw "Packaging failed" }
Pop-Location
}
-foreach ($test in ls test/*.Tests) {
+foreach ($test in Get-ChildItem test/*.Tests) {
Push-Location $test
- echo "build: Testing project in $test"
+ Write-Output "build: Testing project in $test"
& dotnet test -c Release
- if($LASTEXITCODE -ne 0) { exit 3 }
+ if($LASTEXITCODE -ne 0) { throw "Testing failed" }
Pop-Location
}
diff --git a/Directory.Build.props b/Directory.Build.props
index d54992d..0248539 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -7,6 +7,7 @@
$(MSBuildThisFileDirectory)assets/Serilog.snk
enable
enable
+ latest
diff --git a/README.md b/README.md
index bdc3654..1ac6ed7 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@ Writes [Serilog](https://serilog.net) events to one or more text files.
Install the [Serilog.Sinks.File](https://www.nuget.org/packages/Serilog.Sinks.File/) package from NuGet:
```powershell
-Install-Package Serilog.Sinks.File
+dotnet add package Serilog.Sinks.File
```
To configure the sink in C# code, call `WriteTo.File()` during logger configuration:
@@ -36,7 +36,7 @@ The limit can be changed or removed using the `fileSizeLimitBytes` parameter.
```csharp
.WriteTo.File("log.txt", fileSizeLimitBytes: null)
-```
+```
For the same reason, only **the most recent 31 files** are retained by default (i.e. one long month). To change or remove this limit, pass the `retainedFileCountLimit` parameter.
diff --git a/appveyor.yml b/appveyor.yml
index c15a72e..42f5a75 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -2,9 +2,9 @@ version: '{build}'
skip_tags: true
image:
- Visual Studio 2022
- - Ubuntu
+ - Ubuntu2204
build_script:
-- ps: ./Build.ps1
+- pwsh: ./Build.ps1
for:
-
matrix:
@@ -19,7 +19,7 @@ artifacts:
deploy:
- provider: NuGet
api_key:
- secure: LE+O+3Zs0nz2F/+M4eDvKBhEBUpUV0t864vN/2dxwa7aIVqeU3pKSMjWRX+JWJ49
+ secure: sDnchSg4TZIOK7oIUI6BJwFPNENTOZrGNsroGO1hehLJSvlHpFmpTwiX8+bgPD+Q
on:
branch: /^(main|dev)$/
- provider: GitHub
diff --git a/example/Sample/Program.cs b/example/Sample/Program.cs
index d980bd8..660ca72 100644
--- a/example/Sample/Program.cs
+++ b/example/Sample/Program.cs
@@ -1,35 +1,27 @@
using Serilog;
using Serilog.Debugging;
-namespace Sample;
+SelfLog.Enable(Console.Out);
-public class Program
-{
- public static void Main(string[] args)
- {
- SelfLog.Enable(Console.Out);
-
- var sw = System.Diagnostics.Stopwatch.StartNew();
+var sw = System.Diagnostics.Stopwatch.StartNew();
- Log.Logger = new LoggerConfiguration()
- .WriteTo.File("log.txt")
- .CreateLogger();
+Log.Logger = new LoggerConfiguration()
+ .WriteTo.File("log.txt")
+ .CreateLogger();
- for (var i = 0; i < 1000000; ++i)
- {
- Log.Information("Hello, file logger!");
- }
+for (var i = 0; i < 1000000; ++i)
+{
+ Log.Information("Hello, file logger!");
+}
- Log.CloseAndFlush();
+Log.CloseAndFlush();
- sw.Stop();
+sw.Stop();
- Console.WriteLine($"Elapsed: {sw.ElapsedMilliseconds} ms");
- Console.WriteLine($"Size: {new FileInfo("log.txt").Length}");
+Console.WriteLine($"Elapsed: {sw.ElapsedMilliseconds} ms");
+Console.WriteLine($"Size: {new FileInfo("log.txt").Length}");
- Console.WriteLine("Press any key to delete the temporary log file...");
- Console.ReadKey(true);
+Console.WriteLine("Press any key to delete the temporary log file...");
+Console.ReadKey(true);
- File.Delete("log.txt");
- }
-}
+File.Delete("log.txt");
diff --git a/example/Sample/Sample.csproj b/example/Sample/Sample.csproj
index a05ad36..fa9016e 100644
--- a/example/Sample/Sample.csproj
+++ b/example/Sample/Sample.csproj
@@ -1,7 +1,7 @@
- net48;net6.0
+ net48;net8.0
Exe
true
diff --git a/src/Serilog.Sinks.File/FileLoggerConfigurationExtensions.cs b/src/Serilog.Sinks.File/FileLoggerConfigurationExtensions.cs
index 42e21cb..5440792 100644
--- a/src/Serilog.Sinks.File/FileLoggerConfigurationExtensions.cs
+++ b/src/Serilog.Sinks.File/FileLoggerConfigurationExtensions.cs
@@ -518,8 +518,8 @@ static LoggerConfiguration ConfigureFile(
if (addSink == null) throw new ArgumentNullException(nameof(addSink));
if (formatter == null) throw new ArgumentNullException(nameof(formatter));
if (path == null) throw new ArgumentNullException(nameof(path));
- if (fileSizeLimitBytes.HasValue && fileSizeLimitBytes < 1) throw new ArgumentException("Invalid value provided; file size limit must be at least 1 byte, or null.", nameof(fileSizeLimitBytes));
- if (retainedFileCountLimit.HasValue && retainedFileCountLimit < 1) throw new ArgumentException("At least one file must be retained.", nameof(retainedFileCountLimit));
+ if (fileSizeLimitBytes is < 1) throw new ArgumentException("Invalid value provided; file size limit must be at least 1 byte, or null.", nameof(fileSizeLimitBytes));
+ if (retainedFileCountLimit is < 1) throw new ArgumentException("At least one file must be retained.", nameof(retainedFileCountLimit));
if (retainedFileTimeLimit.HasValue && retainedFileTimeLimit < TimeSpan.Zero) throw new ArgumentException("Negative value provided; retained file time limit must be non-negative.", nameof(retainedFileTimeLimit));
if (shared && buffered) throw new ArgumentException("Buffered writes are not available when file sharing is enabled.", nameof(buffered));
if (shared && hooks != null) throw new ArgumentException("File lifecycle hooks are not currently supported for shared log files.", nameof(hooks));
diff --git a/src/Serilog.Sinks.File/Serilog.Sinks.File.csproj b/src/Serilog.Sinks.File/Serilog.Sinks.File.csproj
index e9edc97..a7629b8 100644
--- a/src/Serilog.Sinks.File/Serilog.Sinks.File.csproj
+++ b/src/Serilog.Sinks.File/Serilog.Sinks.File.csproj
@@ -2,42 +2,53 @@
Write Serilog events to text files in plain or JSON format.
- 5.0.1
+ 6.0.0
Serilog Contributors
- net45;netstandard1.3;netstandard2.0;netstandard2.1;net5.0;net6.0
+
+ net471;net462
+
+ $(TargetFrameworks);net8.0;net6.0;netstandard2.0
true
serilog;file
- images\icon.png
+ serilog-sink-nuget.png
https://serilog.net/images/serilog-sink-nuget.png
https://github.com/serilog/serilog-sinks-file
Apache-2.0
https://github.com/serilog/serilog-sinks-file
git
Serilog
- true
- false
true
- $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb
True
snupkg
+ README.md
-
-
+
-
+
$(DefineConstants);ATOMIC_APPEND;HRESULTS
-
+
$(DefineConstants);OS_MUTEX
+
+ $(DefineConstants);ENUMERABLE_MAXBY
+
+
+
+ $(DefineConstants);ENUMERABLE_MAXBY
+
+
-
+
+
diff --git a/src/Serilog.Sinks.File/Sinks/File/FileLifeCycleHookChain.cs b/src/Serilog.Sinks.File/Sinks/File/FileLifeCycleHookChain.cs
index 2c3034c..b7eb06e 100644
--- a/src/Serilog.Sinks.File/Sinks/File/FileLifeCycleHookChain.cs
+++ b/src/Serilog.Sinks.File/Sinks/File/FileLifeCycleHookChain.cs
@@ -16,10 +16,10 @@
namespace Serilog.Sinks.File;
-class FileLifeCycleHookChain : FileLifecycleHooks
+sealed class FileLifeCycleHookChain : FileLifecycleHooks
{
- private readonly FileLifecycleHooks _first;
- private readonly FileLifecycleHooks _second;
+ readonly FileLifecycleHooks _first;
+ readonly FileLifecycleHooks _second;
public FileLifeCycleHookChain(FileLifecycleHooks first, FileLifecycleHooks second)
{
diff --git a/src/Serilog.Sinks.File/Sinks/File/FileLifecycleHooks.cs b/src/Serilog.Sinks.File/Sinks/File/FileLifecycleHooks.cs
index ac6df00..d83926a 100644
--- a/src/Serilog.Sinks.File/Sinks/File/FileLifecycleHooks.cs
+++ b/src/Serilog.Sinks.File/Sinks/File/FileLifecycleHooks.cs
@@ -13,6 +13,7 @@
// limitations under the License.
using System.Text;
+// ReSharper disable UnusedMember.Global
namespace Serilog.Sinks.File;
diff --git a/src/Serilog.Sinks.File/Sinks/File/FileSink.cs b/src/Serilog.Sinks.File/Sinks/File/FileSink.cs
index 9e39892..a246b66 100644
--- a/src/Serilog.Sinks.File/Sinks/File/FileSink.cs
+++ b/src/Serilog.Sinks.File/Sinks/File/FileSink.cs
@@ -67,7 +67,7 @@ internal FileSink(
FileLifecycleHooks? hooks)
{
if (path == null) throw new ArgumentNullException(nameof(path));
- if (fileSizeLimitBytes.HasValue && fileSizeLimitBytes < 1) throw new ArgumentException("Invalid value provided; file size limit must be at least 1 byte, or null.");
+ if (fileSizeLimitBytes is < 1) throw new ArgumentException("Invalid value provided; file size limit must be at least 1 byte, or null.");
_textFormatter = textFormatter ?? throw new ArgumentNullException(nameof(textFormatter));
_fileSizeLimitBytes = fileSizeLimitBytes;
_buffered = buffered;
diff --git a/src/Serilog.Sinks.File/Sinks/File/NullSink.cs b/src/Serilog.Sinks.File/Sinks/File/NullSink.cs
index 8992197..386bab0 100644
--- a/src/Serilog.Sinks.File/Sinks/File/NullSink.cs
+++ b/src/Serilog.Sinks.File/Sinks/File/NullSink.cs
@@ -21,9 +21,9 @@ namespace Serilog.Sinks.File;
/// An instance of this sink may be substituted when an instance of the
/// is unable to be constructed.
///
-class NullSink : ILogEventSink
+sealed class NullSink : ILogEventSink
{
public void Emit(LogEvent logEvent)
{
}
-}
\ No newline at end of file
+}
diff --git a/src/Serilog.Sinks.File/Sinks/File/PathRoller.cs b/src/Serilog.Sinks.File/Sinks/File/PathRoller.cs
index 922682d..e6773eb 100644
--- a/src/Serilog.Sinks.File/Sinks/File/PathRoller.cs
+++ b/src/Serilog.Sinks.File/Sinks/File/PathRoller.cs
@@ -17,7 +17,7 @@
namespace Serilog.Sinks.File;
-class PathRoller
+sealed class PathRoller
{
const string PeriodMatchGroup = "period";
const string SequenceNumberMatchGroup = "sequence";
diff --git a/src/Serilog.Sinks.File/Sinks/File/RollingFileSink.cs b/src/Serilog.Sinks.File/Sinks/File/RollingFileSink.cs
index 373a97e..6c55d44 100644
--- a/src/Serilog.Sinks.File/Sinks/File/RollingFileSink.cs
+++ b/src/Serilog.Sinks.File/Sinks/File/RollingFileSink.cs
@@ -52,8 +52,8 @@ public RollingFileSink(string path,
TimeSpan? retainedFileTimeLimit)
{
if (path == null) throw new ArgumentNullException(nameof(path));
- if (fileSizeLimitBytes.HasValue && fileSizeLimitBytes < 1) throw new ArgumentException("Invalid value provided; file size limit must be at least 1 byte, or null.");
- if (retainedFileCountLimit.HasValue && retainedFileCountLimit < 1) throw new ArgumentException("Zero or negative value provided; retained file count limit must be at least 1");
+ if (fileSizeLimitBytes is < 1) throw new ArgumentException("Invalid value provided; file size limit must be at least 1 byte, or null.");
+ if (retainedFileCountLimit is < 1) throw new ArgumentException("Zero or negative value provided; retained file count limit must be at least 1.");
if (retainedFileTimeLimit.HasValue && retainedFileTimeLimit < TimeSpan.Zero) throw new ArgumentException("Negative value provided; retained file time limit must be non-negative.", nameof(retainedFileTimeLimit));
_roller = new PathRoller(path, rollingInterval);
@@ -121,8 +121,9 @@ void OpenFile(DateTime now, int? minSequence = null)
{
if (Directory.Exists(_roller.LogFileDirectory))
{
+ // ReSharper disable once ConvertClosureToMethodGroup
existingFiles = Directory.GetFiles(_roller.LogFileDirectory, _roller.DirectorySearchPattern)
- .Select(f => Path.GetFileName(f));
+ .Select(f => Path.GetFileName(f));
}
}
catch (DirectoryNotFoundException) { }
@@ -130,8 +131,12 @@ void OpenFile(DateTime now, int? minSequence = null)
var latestForThisCheckpoint = _roller
.SelectMatches(existingFiles)
.Where(m => m.DateTime == currentCheckpoint)
+#if ENUMERABLE_MAXBY
+ .MaxBy(m => m.SequenceNumber);
+#else
.OrderByDescending(m => m.SequenceNumber)
.FirstOrDefault();
+#endif
var sequence = latestForThisCheckpoint?.SequenceNumber;
if (minSequence != null)
@@ -149,7 +154,7 @@ void OpenFile(DateTime now, int? minSequence = null)
{
_currentFile = _shared ?
#pragma warning disable 618
- (IFileSink)new SharedFileSink(path, _textFormatter, _fileSizeLimitBytes, _encoding) :
+ new SharedFileSink(path, _textFormatter, _fileSizeLimitBytes, _encoding) :
#pragma warning restore 618
new FileSink(path, _textFormatter, _fileSizeLimitBytes, _encoding, _buffered, _hooks);
@@ -180,6 +185,7 @@ void ApplyRetentionPolicy(string currentFilePath, DateTime now)
// We consider the current file to exist, even if nothing's been written yet,
// because files are only opened on response to an event being processed.
+ // ReSharper disable once ConvertClosureToMethodGroup
var potentialMatches = Directory.GetFiles(_roller.LogFileDirectory, _roller.DirectorySearchPattern)
.Select(f => Path.GetFileName(f))
.Union(new[] { currentFileName });
diff --git a/src/Serilog.Sinks.File/Sinks/File/RollingIntervalExtensions.cs b/src/Serilog.Sinks.File/Sinks/File/RollingIntervalExtensions.cs
index 98ffb42..a469abe 100644
--- a/src/Serilog.Sinks.File/Sinks/File/RollingIntervalExtensions.cs
+++ b/src/Serilog.Sinks.File/Sinks/File/RollingIntervalExtensions.cs
@@ -18,44 +18,30 @@ static class RollingIntervalExtensions
{
public static string GetFormat(this RollingInterval interval)
{
- switch (interval)
+ return interval switch
{
- 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");
- }
+ RollingInterval.Infinite => "",
+ RollingInterval.Year => "yyyy",
+ RollingInterval.Month => "yyyyMM",
+ RollingInterval.Day => "yyyyMMdd",
+ RollingInterval.Hour => "yyyyMMddHH",
+ RollingInterval.Minute => "yyyyMMddHHmm",
+ _ => throw new ArgumentException("Invalid rolling interval.")
+ };
}
public static DateTime? GetCurrentCheckpoint(this RollingInterval interval, DateTime instant)
{
- switch (interval)
+ return interval switch
{
- 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");
- }
+ RollingInterval.Infinite => null,
+ RollingInterval.Year => new DateTime(instant.Year, 1, 1, 0, 0, 0, instant.Kind),
+ RollingInterval.Month => new DateTime(instant.Year, instant.Month, 1, 0, 0, 0, instant.Kind),
+ RollingInterval.Day => new DateTime(instant.Year, instant.Month, instant.Day, 0, 0, 0, instant.Kind),
+ RollingInterval.Hour => new DateTime(instant.Year, instant.Month, instant.Day, instant.Hour, 0, 0, instant.Kind),
+ RollingInterval.Minute => new DateTime(instant.Year, instant.Month, instant.Day, instant.Hour, instant.Minute, 0, instant.Kind),
+ _ => throw new ArgumentException("Invalid rolling interval.")
+ };
}
public static DateTime? GetNextCheckpoint(this RollingInterval interval, DateTime instant)
@@ -64,20 +50,14 @@ public static string GetFormat(this RollingInterval interval)
if (current == null)
return null;
- switch (interval)
+ return interval switch
{
- 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");
- }
+ RollingInterval.Year => current.Value.AddYears(1),
+ RollingInterval.Month => current.Value.AddMonths(1),
+ RollingInterval.Day => current.Value.AddDays(1),
+ RollingInterval.Hour => current.Value.AddHours(1),
+ RollingInterval.Minute => current.Value.AddMinutes(1),
+ _ => throw new ArgumentException("Invalid rolling interval.")
+ };
}
}
diff --git a/src/Serilog.Sinks.File/Sinks/File/RollingLogFile.cs b/src/Serilog.Sinks.File/Sinks/File/RollingLogFile.cs
index 6441627..3a5b493 100644
--- a/src/Serilog.Sinks.File/Sinks/File/RollingLogFile.cs
+++ b/src/Serilog.Sinks.File/Sinks/File/RollingLogFile.cs
@@ -15,19 +15,9 @@
namespace Serilog.Sinks.File;
-class RollingLogFile
+class RollingLogFile(string filename, DateTime? dateTime, int? sequenceNumber)
{
- public RollingLogFile(string filename, DateTime? dateTime, int? sequenceNumber)
- {
- Filename = filename;
- DateTime = dateTime;
- SequenceNumber = sequenceNumber;
- }
-
- public string Filename { get; }
-
- public DateTime? DateTime { get; }
-
- public int? SequenceNumber { get; }
+ public string Filename { get; } = filename;
+ public DateTime? DateTime { get; } = dateTime;
+ public int? SequenceNumber { get; } = sequenceNumber;
}
-
diff --git a/src/Serilog.Sinks.File/Sinks/File/SharedFileSink.AtomicAppend.cs b/src/Serilog.Sinks.File/Sinks/File/SharedFileSink.AtomicAppend.cs
index 6cf55cb..c753e46 100644
--- a/src/Serilog.Sinks.File/Sinks/File/SharedFileSink.AtomicAppend.cs
+++ b/src/Serilog.Sinks.File/Sinks/File/SharedFileSink.AtomicAppend.cs
@@ -14,163 +14,160 @@
#if ATOMIC_APPEND
-using System;
-using System.IO;
using System.Security.AccessControl;
using System.Text;
using Serilog.Events;
using Serilog.Formatting;
-namespace Serilog.Sinks.File
+namespace Serilog.Sinks.File;
+
+///
+/// Write log events to a disk file.
+///
+[Obsolete("This type will be removed from the public API in a future version; use `WriteTo.File(shared: true)` instead.")]
+public sealed class SharedFileSink : IFileSink, IDisposable
{
- ///
- /// Write log events to a disk file.
- ///
- [Obsolete("This type will be removed from the public API in a future version; use `WriteTo.File(shared: true)` instead.")]
- public sealed class SharedFileSink : IFileSink, IDisposable
+ readonly MemoryStream _writeBuffer;
+ readonly string _path;
+ readonly TextWriter _output;
+ readonly ITextFormatter _textFormatter;
+ readonly long? _fileSizeLimitBytes;
+ readonly object _syncRoot = new();
+
+ // The stream is reopened with a larger buffer if atomic writes beyond the current buffer size are needed.
+ FileStream _fileOutput;
+ int _fileStreamBufferLength = DefaultFileStreamBufferLength;
+
+ const int DefaultFileStreamBufferLength = 4096;
+
+ /// Construct a .
+ /// Path to the file.
+ /// Formatter used to convert log events to text.
+ /// The approximate maximum size, in bytes, to which a log file will be allowed to grow.
+ /// For unrestricted growth, pass null. The default is 1 GB. To avoid writing partial events, the last event within the limit
+ /// will be written in full even if it exceeds the limit.
+ /// Character encoding used to write the text file. The default is UTF-8 without BOM.
+ /// Configuration object allowing method chaining.
+ /// When is null
+ /// When is null
+ ///
+ ///
+ ///
+ /// When is too long
+ /// The caller does not have the required permission to access the
+ /// Invalid
+ public SharedFileSink(string path, ITextFormatter textFormatter, long? fileSizeLimitBytes, Encoding? encoding = null)
{
- readonly MemoryStream _writeBuffer;
- readonly string _path;
- readonly TextWriter _output;
- readonly ITextFormatter _textFormatter;
- readonly long? _fileSizeLimitBytes;
- readonly object _syncRoot = new object();
-
- // The stream is reopened with a larger buffer if atomic writes beyond the current buffer size are needed.
- FileStream _fileOutput;
- int _fileStreamBufferLength = DefaultFileStreamBufferLength;
-
- const int DefaultFileStreamBufferLength = 4096;
-
- /// Construct a .
- /// Path to the file.
- /// Formatter used to convert log events to text.
- /// The approximate maximum size, in bytes, to which a log file will be allowed to grow.
- /// For unrestricted growth, pass null. The default is 1 GB. To avoid writing partial events, the last event within the limit
- /// will be written in full even if it exceeds the limit.
- /// Character encoding used to write the text file. The default is UTF-8 without BOM.
- /// Configuration object allowing method chaining.
- /// When is null
- /// When is null
- ///
- ///
- ///
- /// When is too long
- /// The caller does not have the required permission to access the
- /// Invalid
- public SharedFileSink(string path, ITextFormatter textFormatter, long? fileSizeLimitBytes, Encoding? encoding = null)
- {
- if (fileSizeLimitBytes.HasValue && fileSizeLimitBytes < 1)
- throw new ArgumentException("Invalid value provided; file size limit must be at least 1 byte, or null");
+ if (fileSizeLimitBytes.HasValue && fileSizeLimitBytes < 1)
+ throw new ArgumentException("Invalid value provided; file size limit must be at least 1 byte, or null");
- _path = path ?? throw new ArgumentNullException(nameof(path));
- _textFormatter = textFormatter ?? throw new ArgumentNullException(nameof(textFormatter));
- _fileSizeLimitBytes = fileSizeLimitBytes;
+ _path = path ?? throw new ArgumentNullException(nameof(path));
+ _textFormatter = textFormatter ?? throw new ArgumentNullException(nameof(textFormatter));
+ _fileSizeLimitBytes = fileSizeLimitBytes;
- var directory = Path.GetDirectoryName(path);
- if (!string.IsNullOrWhiteSpace(directory) && !Directory.Exists(directory))
- {
- Directory.CreateDirectory(directory);
- }
-
- // FileSystemRights.AppendData sets the Win32 FILE_APPEND_DATA flag. On Linux this is O_APPEND, but that API is not yet
- // exposed by .NET Core.
- _fileOutput = new FileStream(
- path,
- FileMode.Append,
- FileSystemRights.AppendData,
- FileShare.ReadWrite,
- _fileStreamBufferLength,
- FileOptions.None);
-
- _writeBuffer = new MemoryStream();
- _output = new StreamWriter(_writeBuffer,
- encoding ?? new UTF8Encoding(encoderShouldEmitUTF8Identifier: false));
+ var directory = Path.GetDirectoryName(path);
+ if (!string.IsNullOrWhiteSpace(directory) && !Directory.Exists(directory))
+ {
+ Directory.CreateDirectory(directory);
}
- bool IFileSink.EmitOrOverflow(LogEvent logEvent)
- {
- if (logEvent == null) throw new ArgumentNullException(nameof(logEvent));
+ // FileSystemRights.AppendData sets the Win32 FILE_APPEND_DATA flag. On Linux this is O_APPEND, but that API is not yet
+ // exposed by .NET Core.
+ _fileOutput = new FileStream(
+ path,
+ FileMode.Append,
+ FileSystemRights.AppendData,
+ FileShare.ReadWrite,
+ _fileStreamBufferLength,
+ FileOptions.None);
+
+ _writeBuffer = new MemoryStream();
+ _output = new StreamWriter(_writeBuffer,
+ encoding ?? new UTF8Encoding(encoderShouldEmitUTF8Identifier: false));
+ }
+
+ bool IFileSink.EmitOrOverflow(LogEvent logEvent)
+ {
+ if (logEvent == null) throw new ArgumentNullException(nameof(logEvent));
- lock (_syncRoot)
+ lock (_syncRoot)
+ {
+ try
{
- try
+ _textFormatter.Format(logEvent, _output);
+ _output.Flush();
+ var bytes = _writeBuffer.GetBuffer();
+ var length = (int) _writeBuffer.Length;
+ if (length > _fileStreamBufferLength)
{
- _textFormatter.Format(logEvent, _output);
- _output.Flush();
- var bytes = _writeBuffer.GetBuffer();
- var length = (int) _writeBuffer.Length;
- if (length > _fileStreamBufferLength)
- {
- var oldOutput = _fileOutput;
-
- _fileOutput = new FileStream(
- _path,
- FileMode.Append,
- FileSystemRights.AppendData,
- FileShare.ReadWrite,
- length,
- FileOptions.None);
- _fileStreamBufferLength = length;
-
- oldOutput.Dispose();
- }
+ var oldOutput = _fileOutput;
+
+ _fileOutput = new FileStream(
+ _path,
+ FileMode.Append,
+ FileSystemRights.AppendData,
+ FileShare.ReadWrite,
+ length,
+ FileOptions.None);
+ _fileStreamBufferLength = length;
+
+ oldOutput.Dispose();
+ }
- if (_fileSizeLimitBytes != null)
+ if (_fileSizeLimitBytes != null)
+ {
+ try
{
- try
- {
- if (_fileOutput.Length >= _fileSizeLimitBytes.Value)
- return false;
- }
- catch (FileNotFoundException) { } // Cheaper and more reliable than checking existence
+ if (_fileOutput.Length >= _fileSizeLimitBytes.Value)
+ return false;
}
-
- _fileOutput.Write(bytes, 0, length);
- _fileOutput.Flush();
- return true;
- }
- catch
- {
- // Make sure there's no leftover cruft in there.
- _output.Flush();
- throw;
- }
- finally
- {
- _writeBuffer.Position = 0;
- _writeBuffer.SetLength(0);
+ catch (FileNotFoundException) { } // Cheaper and more reliable than checking existence
}
+
+ _fileOutput.Write(bytes, 0, length);
+ _fileOutput.Flush();
+ return true;
+ }
+ catch
+ {
+ // Make sure there's no leftover cruft in there.
+ _output.Flush();
+ throw;
+ }
+ finally
+ {
+ _writeBuffer.Position = 0;
+ _writeBuffer.SetLength(0);
}
}
+ }
- ///
- /// Emit the provided log event to the sink.
- ///
- /// The log event to write.
- /// When is null
- public void Emit(LogEvent logEvent)
- {
- ((IFileSink)this).EmitOrOverflow(logEvent);
- }
+ ///
+ /// Emit the provided log event to the sink.
+ ///
+ /// The log event to write.
+ /// When is null
+ public void Emit(LogEvent logEvent)
+ {
+ ((IFileSink)this).EmitOrOverflow(logEvent);
+ }
- ///
- public void Dispose()
+ ///
+ public void Dispose()
+ {
+ lock (_syncRoot)
{
- lock (_syncRoot)
- {
- _fileOutput.Dispose();
- }
+ _fileOutput.Dispose();
}
+ }
- ///
- public void FlushToDisk()
+ ///
+ public void FlushToDisk()
+ {
+ lock (_syncRoot)
{
- lock (_syncRoot)
- {
- _output.Flush();
- _fileOutput.Flush(true);
- }
+ _output.Flush();
+ _fileOutput.Flush(true);
}
}
}
diff --git a/src/Serilog.Sinks.File/Sinks/File/SharedFileSink.OSMutex.cs b/src/Serilog.Sinks.File/Sinks/File/SharedFileSink.OSMutex.cs
index 0038c6b..6f5dc5c 100644
--- a/src/Serilog.Sinks.File/Sinks/File/SharedFileSink.OSMutex.cs
+++ b/src/Serilog.Sinks.File/Sinks/File/SharedFileSink.OSMutex.cs
@@ -14,12 +14,9 @@
#if OS_MUTEX
-using System;
-using System.IO;
using System.Text;
using Serilog.Events;
using Serilog.Formatting;
-using System.Threading;
using Serilog.Debugging;
namespace Serilog.Sinks.File;
@@ -60,7 +57,7 @@ public sealed class SharedFileSink : IFileSink, IDisposable
public SharedFileSink(string path, ITextFormatter textFormatter, long? fileSizeLimitBytes, Encoding? encoding = null)
{
if (path == null) throw new ArgumentNullException(nameof(path));
- if (fileSizeLimitBytes.HasValue && fileSizeLimitBytes < 1)
+ if (fileSizeLimitBytes is < 1)
throw new ArgumentException("Invalid value provided; file size limit must be at least 1 byte, or null.");
_textFormatter = textFormatter ?? throw new ArgumentNullException(nameof(textFormatter));
_fileSizeLimitBytes = fileSizeLimitBytes;
diff --git a/src/Serilog.Sinks.File/Sinks/File/WriteCountingStream.cs b/src/Serilog.Sinks.File/Sinks/File/WriteCountingStream.cs
index e95d80f..39eec07 100644
--- a/src/Serilog.Sinks.File/Sinks/File/WriteCountingStream.cs
+++ b/src/Serilog.Sinks.File/Sinks/File/WriteCountingStream.cs
@@ -46,7 +46,6 @@ public override void Write(byte[] buffer, int offset, int count)
public override bool CanWrite => true;
public override long Length => _stream.Length;
-
public override long Position
{
get => _stream.Position;
diff --git a/test/Serilog.Sinks.File.Tests/FileLoggerConfigurationExtensionsTests.cs b/test/Serilog.Sinks.File.Tests/FileLoggerConfigurationExtensionsTests.cs
index 9c32200..b3ce3e2 100644
--- a/test/Serilog.Sinks.File.Tests/FileLoggerConfigurationExtensionsTests.cs
+++ b/test/Serilog.Sinks.File.Tests/FileLoggerConfigurationExtensionsTests.cs
@@ -29,52 +29,44 @@ public void WhenAuditingCreationExceptionsPropagate()
[Fact]
public void WhenWritingLoggingExceptionsAreSuppressed()
{
- using (var tmp = TempFolder.ForCaller())
- using (var log = new LoggerConfiguration()
+ using var tmp = TempFolder.ForCaller();
+ using var log = new LoggerConfiguration()
.WriteTo.File(new ThrowingLogEventFormatter(), tmp.AllocateFilename())
- .CreateLogger())
- {
- log.Information("Hello");
- }
+ .CreateLogger();
+ log.Information("Hello");
}
[Fact]
public void WhenAuditingLoggingExceptionsPropagate()
{
- using (var tmp = TempFolder.ForCaller())
- using (var log = new LoggerConfiguration()
+ using var tmp = TempFolder.ForCaller();
+ using var log = new LoggerConfiguration()
.AuditTo.File(new ThrowingLogEventFormatter(), tmp.AllocateFilename())
- .CreateLogger())
- {
- var ex = Assert.Throws(() => log.Information("Hello"));
- Assert.IsType(ex.GetBaseException());
- }
+ .CreateLogger();
+ var ex = Assert.Throws(() => log.Information("Hello"));
+ Assert.IsType(ex.GetBaseException());
}
[Fact]
public void WhenFlushingToDiskReportedFileSinkCanBeCreatedAndDisposed()
{
- using (var tmp = TempFolder.ForCaller())
- using (var log = new LoggerConfiguration()
+ using var tmp = TempFolder.ForCaller();
+ using var log = new LoggerConfiguration()
.WriteTo.File(tmp.AllocateFilename(), flushToDiskInterval: TimeSpan.FromMilliseconds(500))
- .CreateLogger())
- {
- log.Information("Hello");
- Thread.Sleep(TimeSpan.FromSeconds(1));
- }
+ .CreateLogger();
+ log.Information("Hello");
+ Thread.Sleep(TimeSpan.FromSeconds(1));
}
[Fact]
public void WhenFlushingToDiskReportedSharedFileSinkCanBeCreatedAndDisposed()
{
- using (var tmp = TempFolder.ForCaller())
- using (var log = new LoggerConfiguration()
+ using var tmp = TempFolder.ForCaller();
+ using var log = new LoggerConfiguration()
.WriteTo.File(tmp.AllocateFilename(), shared: true, flushToDiskInterval: TimeSpan.FromMilliseconds(500))
- .CreateLogger())
- {
- log.Information("Hello");
- Thread.Sleep(TimeSpan.FromSeconds(1));
- }
+ .CreateLogger();
+ log.Information("Hello");
+ Thread.Sleep(TimeSpan.FromSeconds(1));
}
[Fact]
@@ -98,19 +90,17 @@ public void HooksAreNotAvailableWhenSharingEnabled()
[InlineData(true)]
public void SpecifiedEncodingIsPropagated(bool shared)
{
- using (var tmp = TempFolder.ForCaller())
- {
- var filename = tmp.AllocateFilename("txt");
-
- using (var log = new LoggerConfiguration()
- .WriteTo.File(filename, outputTemplate: "{Message}", encoding: Encoding.Unicode, shared: shared)
- .CreateLogger())
- {
- log.Information("ten chars.");
- }
+ using var tmp = TempFolder.ForCaller();
+ var filename = tmp.AllocateFilename("txt");
- // Don't forget the two-byte BOM :-)
- Assert.Equal(22, System.IO.File.ReadAllBytes(filename).Length);
+ using (var log = new LoggerConfiguration()
+ .WriteTo.File(filename, outputTemplate: "{Message}", encoding: Encoding.Unicode, shared: shared)
+ .CreateLogger())
+ {
+ log.Information("ten chars.");
}
+
+ // Don't forget the two-byte BOM :-)
+ Assert.Equal(22, System.IO.File.ReadAllBytes(filename).Length);
}
}
diff --git a/test/Serilog.Sinks.File.Tests/FileSinkTests.cs b/test/Serilog.Sinks.File.Tests/FileSinkTests.cs
index af5c8f5..0c76349 100644
--- a/test/Serilog.Sinks.File.Tests/FileSinkTests.cs
+++ b/test/Serilog.Sinks.File.Tests/FileSinkTests.cs
@@ -14,43 +14,39 @@ public class FileSinkTests
[Fact]
public void FileIsWrittenIfNonexistent()
{
- using (var tmp = TempFolder.ForCaller())
- {
- var nonexistent = tmp.AllocateFilename("txt");
- var evt = Some.LogEvent("Hello, world!");
-
- using (var sink = new FileSink(nonexistent, new JsonFormatter(), null))
- {
- sink.Emit(evt);
- }
+ using var tmp = TempFolder.ForCaller();
+ var nonexistent = tmp.AllocateFilename("txt");
+ var evt = Some.LogEvent("Hello, world!");
- var lines = System.IO.File.ReadAllLines(nonexistent);
- Assert.Contains("Hello, world!", lines[0]);
+ using (var sink = new FileSink(nonexistent, new JsonFormatter(), null))
+ {
+ sink.Emit(evt);
}
+
+ var lines = System.IO.File.ReadAllLines(nonexistent);
+ Assert.Contains("Hello, world!", lines[0]);
}
[Fact]
public void FileIsAppendedToWhenAlreadyCreated()
{
- using (var tmp = TempFolder.ForCaller())
- {
- var path = tmp.AllocateFilename("txt");
- var evt = Some.LogEvent("Hello, world!");
+ using var tmp = TempFolder.ForCaller();
+ var path = tmp.AllocateFilename("txt");
+ var evt = Some.LogEvent("Hello, world!");
- using (var sink = new FileSink(path, new JsonFormatter(), null))
- {
- sink.Emit(evt);
- }
-
- using (var sink = new FileSink(path, new JsonFormatter(), null))
- {
- sink.Emit(evt);
- }
+ using (var sink = new FileSink(path, new JsonFormatter(), null))
+ {
+ sink.Emit(evt);
+ }
- var lines = System.IO.File.ReadAllLines(path);
- Assert.Contains("Hello, world!", lines[0]);
- Assert.Contains("Hello, world!", lines[1]);
+ using (var sink = new FileSink(path, new JsonFormatter(), null))
+ {
+ sink.Emit(evt);
}
+
+ var lines = System.IO.File.ReadAllLines(path);
+ Assert.Contains("Hello, world!", lines[0]);
+ Assert.Contains("Hello, world!", lines[1]);
}
[Fact]
@@ -59,23 +55,21 @@ public void WhenLimitIsSpecifiedFileSizeIsRestricted()
const int maxBytes = 5000;
const int eventsToLimit = 10;
- using (var tmp = TempFolder.ForCaller())
- {
- var path = tmp.AllocateFilename("txt");
- var evt = Some.LogEvent(new string('n', maxBytes / eventsToLimit));
+ using var tmp = TempFolder.ForCaller();
+ var path = tmp.AllocateFilename("txt");
+ var evt = Some.LogEvent(new string('n', maxBytes / eventsToLimit));
- using (var sink = new FileSink(path, new JsonFormatter(), maxBytes))
+ using (var sink = new FileSink(path, new JsonFormatter(), maxBytes))
+ {
+ for (var i = 0; i < eventsToLimit * 2; i++)
{
- for (var i = 0; i < eventsToLimit * 2; i++)
- {
- sink.Emit(evt);
- }
+ sink.Emit(evt);
}
-
- var size = new FileInfo(path).Length;
- Assert.True(size > maxBytes);
- Assert.True(size < maxBytes * 2);
}
+
+ var size = new FileInfo(path).Length;
+ Assert.True(size > maxBytes);
+ Assert.True(size < maxBytes * 2);
}
[Fact]
@@ -84,22 +78,20 @@ public void WhenLimitIsNotSpecifiedFileSizeIsNotRestricted()
const int maxBytes = 5000;
const int eventsToLimit = 10;
- using (var tmp = TempFolder.ForCaller())
- {
- var path = tmp.AllocateFilename("txt");
- var evt = Some.LogEvent(new string('n', maxBytes / eventsToLimit));
+ using var tmp = TempFolder.ForCaller();
+ var path = tmp.AllocateFilename("txt");
+ var evt = Some.LogEvent(new string('n', maxBytes / eventsToLimit));
- using (var sink = new FileSink(path, new JsonFormatter(), null))
+ using (var sink = new FileSink(path, new JsonFormatter(), null))
+ {
+ for (var i = 0; i < eventsToLimit * 2; i++)
{
- for (var i = 0; i < eventsToLimit * 2; i++)
- {
- sink.Emit(evt);
- }
+ sink.Emit(evt);
}
-
- var size = new FileInfo(path).Length;
- Assert.True(size > maxBytes * 2);
}
+
+ var size = new FileInfo(path).Length;
+ Assert.True(size > maxBytes * 2);
}
@@ -146,132 +138,122 @@ public void OnOpenedLifecycleHookCanWrapUnderlyingStream()
{
var gzipWrapper = new GZipHooks();
- using (var tmp = TempFolder.ForCaller())
- {
- var path = tmp.AllocateFilename("txt");
- var evt = Some.LogEvent("Hello, world!");
+ using var tmp = TempFolder.ForCaller();
+ var path = tmp.AllocateFilename("txt");
+ var evt = Some.LogEvent("Hello, world!");
- using (var sink = new FileSink(path, new JsonFormatter(), null, null, false, gzipWrapper))
- {
- sink.Emit(evt);
- sink.Emit(evt);
- }
+ using (var sink = new FileSink(path, new JsonFormatter(), null, null, false, gzipWrapper))
+ {
+ sink.Emit(evt);
+ sink.Emit(evt);
+ }
- // Ensure the data was written through the wrapping GZipStream, by decompressing and comparing against
- // what we wrote
- List lines;
- using (var textStream = new MemoryStream())
+ // Ensure the data was written through the wrapping GZipStream, by decompressing and comparing against
+ // what we wrote
+ List lines;
+ using (var textStream = new MemoryStream())
+ {
+ using (var fs = System.IO.File.OpenRead(path))
+ using (var decompressStream = new GZipStream(fs, CompressionMode.Decompress))
{
- using (var fs = System.IO.File.OpenRead(path))
- using (var decompressStream = new GZipStream(fs, CompressionMode.Decompress))
- {
- decompressStream.CopyTo(textStream);
- }
-
- textStream.Position = 0;
- lines = textStream.ReadAllLines();
+ decompressStream.CopyTo(textStream);
}
- Assert.Equal(2, lines.Count);
- Assert.Contains("Hello, world!", lines[0]);
+ textStream.Position = 0;
+ lines = textStream.ReadAllLines();
}
+
+ Assert.Equal(2, lines.Count);
+ Assert.Contains("Hello, world!", lines[0]);
}
[Fact]
public static void OnOpenedLifecycleHookCanWriteFileHeader()
{
- using (var tmp = TempFolder.ForCaller())
- {
- var headerWriter = new FileHeaderWriter("This is the file header");
+ using var tmp = TempFolder.ForCaller();
+ var headerWriter = new FileHeaderWriter("This is the file header");
- var path = tmp.AllocateFilename("txt");
- using (new FileSink(path, new JsonFormatter(), null, new UTF8Encoding(false), false, headerWriter))
- {
- // Open and write header
- }
+ var path = tmp.AllocateFilename("txt");
+ using (new FileSink(path, new JsonFormatter(), null, new UTF8Encoding(false), false, headerWriter))
+ {
+ // Open and write header
+ }
- using (var sink = new FileSink(path, new JsonFormatter(), null, new UTF8Encoding(false), false, headerWriter))
- {
- // Length check should prevent duplicate header here
- sink.Emit(Some.LogEvent());
- }
+ using (var sink = new FileSink(path, new JsonFormatter(), null, new UTF8Encoding(false), false, headerWriter))
+ {
+ // Length check should prevent duplicate header here
+ sink.Emit(Some.LogEvent());
+ }
- var lines = System.IO.File.ReadAllLines(path);
+ var lines = System.IO.File.ReadAllLines(path);
- Assert.Equal(2, lines.Length);
- Assert.Equal(headerWriter.Header, lines[0]);
- Assert.Equal('{', lines[1][0]);
- }
+ Assert.Equal(2, lines.Length);
+ Assert.Equal(headerWriter.Header, lines[0]);
+ Assert.Equal('{', lines[1][0]);
}
[Fact]
public static void OnOpenedLifecycleHookCanCaptureFilePath()
{
- using (var tmp = TempFolder.ForCaller())
- {
- var capturePath = new CaptureFilePathHook();
+ using var tmp = TempFolder.ForCaller();
+ var capturePath = new CaptureFilePathHook();
- var path = tmp.AllocateFilename("txt");
- using (new FileSink(path, new JsonFormatter(), null, new UTF8Encoding(false), false, capturePath))
- {
- // Open and capture the log file path
- }
-
- Assert.Equal(path, capturePath.Path);
+ var path = tmp.AllocateFilename("txt");
+ using (new FileSink(path, new JsonFormatter(), null, new UTF8Encoding(false), false, capturePath))
+ {
+ // Open and capture the log file path
}
+
+ Assert.Equal(path, capturePath.Path);
}
[Fact]
public static void OnOpenedLifecycleHookCanEmptyTheFileContents()
{
- using (var tmp = TempFolder.ForCaller())
- {
- var emptyFileHook = new TruncateFileHook();
+ using var tmp = TempFolder.ForCaller();
+ var emptyFileHook = new TruncateFileHook();
- var path = tmp.AllocateFilename("txt");
- using (var sink = new FileSink(path, new JsonFormatter(), fileSizeLimitBytes: null, encoding: new UTF8Encoding(false), buffered: false))
- {
- sink.Emit(Some.LogEvent());
- }
+ var path = tmp.AllocateFilename("txt");
+ using (var sink = new FileSink(path, new JsonFormatter(), fileSizeLimitBytes: null, encoding: new UTF8Encoding(false), buffered: false))
+ {
+ sink.Emit(Some.LogEvent());
+ }
- using (var sink = new FileSink(path, new JsonFormatter(), fileSizeLimitBytes: null, encoding: new UTF8Encoding(false), buffered: false, hooks: emptyFileHook))
- {
- // Hook will clear the contents of the file before emitting the log events
- sink.Emit(Some.LogEvent());
- }
+ using (var sink = new FileSink(path, new JsonFormatter(), fileSizeLimitBytes: null, encoding: new UTF8Encoding(false), buffered: false, hooks: emptyFileHook))
+ {
+ // Hook will clear the contents of the file before emitting the log events
+ sink.Emit(Some.LogEvent());
+ }
- var lines = System.IO.File.ReadAllLines(path);
+ var lines = System.IO.File.ReadAllLines(path);
- Assert.Single(lines);
- Assert.Equal('{', lines[0][0]);
- }
+ Assert.Single(lines);
+ Assert.Equal('{', lines[0][0]);
}
static void WriteTwoEventsAndCheckOutputFileLength(long? maxBytes, Encoding encoding)
{
- using (var tmp = TempFolder.ForCaller())
+ using var tmp = TempFolder.ForCaller();
+ var path = tmp.AllocateFilename("txt");
+ var evt = Some.LogEvent("Irrelevant as it will be replaced by the formatter");
+ const string actualEventOutput = "x";
+ var formatter = new FixedOutputFormatter(actualEventOutput);
+ var eventOuputLength = encoding.GetByteCount(actualEventOutput);
+
+ using (var sink = new FileSink(path, formatter, maxBytes, encoding: encoding))
{
- var path = tmp.AllocateFilename("txt");
- var evt = Some.LogEvent("Irrelevant as it will be replaced by the formatter");
- const string actualEventOutput = "x";
- var formatter = new FixedOutputFormatter(actualEventOutput);
- var eventOuputLength = encoding.GetByteCount(actualEventOutput);
-
- using (var sink = new FileSink(path, formatter, maxBytes, encoding: encoding))
- {
- sink.Emit(evt);
- }
- var size = new FileInfo(path).Length;
- Assert.Equal(encoding.GetPreamble().Length + eventOuputLength, size);
-
- //write a second event to the same file
- using (var sink = new FileSink(path, formatter, maxBytes, encoding: encoding))
- {
- sink.Emit(evt);
- }
+ sink.Emit(evt);
+ }
+ var size = new FileInfo(path).Length;
+ Assert.Equal(encoding.GetPreamble().Length + eventOuputLength, size);
- size = new FileInfo(path).Length;
- Assert.Equal(encoding.GetPreamble().Length + eventOuputLength * 2, size);
+ //write a second event to the same file
+ using (var sink = new FileSink(path, formatter, maxBytes, encoding: encoding))
+ {
+ sink.Emit(evt);
}
+
+ size = new FileInfo(path).Length;
+ Assert.Equal(encoding.GetPreamble().Length + eventOuputLength * 2, size);
}
}
diff --git a/test/Serilog.Sinks.File.Tests/RollingIntervalExtensionsTests.cs b/test/Serilog.Sinks.File.Tests/RollingIntervalExtensionsTests.cs
index a7b307b..7572067 100644
--- a/test/Serilog.Sinks.File.Tests/RollingIntervalExtensionsTests.cs
+++ b/test/Serilog.Sinks.File.Tests/RollingIntervalExtensionsTests.cs
@@ -4,20 +4,20 @@ namespace Serilog.Sinks.File.Tests;
public class RollingIntervalExtensionsTests
{
- public static object?[][] IntervalInstantCurrentNextCheckpoint => new[]
- {
- new object?[]{ RollingInterval.Infinite, new DateTime(2018, 01, 01), null, null },
- new object?[]{ RollingInterval.Year, new DateTime(2018, 01, 01), new DateTime(2018, 01, 01), new DateTime(2019, 01, 01) },
- new object?[]{ RollingInterval.Year, new DateTime(2018, 06, 01), new DateTime(2018, 01, 01), new DateTime(2019, 01, 01) },
- new object?[]{ RollingInterval.Month, new DateTime(2018, 01, 01), new DateTime(2018, 01, 01), new DateTime(2018, 02, 01) },
- new object?[]{ RollingInterval.Month, new DateTime(2018, 01, 14), new DateTime(2018, 01, 01), new DateTime(2018, 02, 01) },
- new object?[]{ RollingInterval.Day, new DateTime(2018, 01, 01), new DateTime(2018, 01, 01), new DateTime(2018, 01, 02) },
- new object?[]{ RollingInterval.Day, new DateTime(2018, 01, 01, 12, 0, 0), new DateTime(2018, 01, 01), new DateTime(2018, 01, 02) },
- new object?[]{ RollingInterval.Hour, new DateTime(2018, 01, 01, 0, 0, 0), new DateTime(2018, 01, 01), new DateTime(2018, 01, 01, 1, 0, 0) },
- new object?[]{ RollingInterval.Hour, new DateTime(2018, 01, 01, 0, 30, 0), new DateTime(2018, 01, 01), new DateTime(2018, 01, 01, 1, 0, 0) },
- new object?[]{ RollingInterval.Minute, new DateTime(2018, 01, 01, 0, 0, 0), new DateTime(2018, 01, 01), new DateTime(2018, 01, 01, 0, 1, 0) },
- new object?[]{ RollingInterval.Minute, new DateTime(2018, 01, 01, 0, 0, 30), new DateTime(2018, 01, 01), new DateTime(2018, 01, 01, 0, 1, 0) }
- };
+ public static object?[][] IntervalInstantCurrentNextCheckpoint =>
+ [
+ [RollingInterval.Infinite, new DateTime(2018, 01, 01), null, null],
+ [RollingInterval.Year, new DateTime(2018, 01, 01), new DateTime(2018, 01, 01), new DateTime(2019, 01, 01)],
+ [RollingInterval.Year, new DateTime(2018, 06, 01), new DateTime(2018, 01, 01), new DateTime(2019, 01, 01)],
+ [RollingInterval.Month, new DateTime(2018, 01, 01), new DateTime(2018, 01, 01), new DateTime(2018, 02, 01)],
+ [RollingInterval.Month, new DateTime(2018, 01, 14), new DateTime(2018, 01, 01), new DateTime(2018, 02, 01)],
+ [RollingInterval.Day, new DateTime(2018, 01, 01), new DateTime(2018, 01, 01), new DateTime(2018, 01, 02)],
+ [RollingInterval.Day, new DateTime(2018, 01, 01, 12, 0, 0), new DateTime(2018, 01, 01), new DateTime(2018, 01, 02)],
+ [RollingInterval.Hour, new DateTime(2018, 01, 01, 0, 0, 0), new DateTime(2018, 01, 01), new DateTime(2018, 01, 01, 1, 0, 0)],
+ [RollingInterval.Hour, new DateTime(2018, 01, 01, 0, 30, 0), new DateTime(2018, 01, 01), new DateTime(2018, 01, 01, 1, 0, 0)],
+ [RollingInterval.Minute, new DateTime(2018, 01, 01, 0, 0, 0), new DateTime(2018, 01, 01), new DateTime(2018, 01, 01, 0, 1, 0)],
+ [RollingInterval.Minute, new DateTime(2018, 01, 01, 0, 0, 30), new DateTime(2018, 01, 01), new DateTime(2018, 01, 01, 0, 1, 0)]
+ ];
[Theory]
[MemberData(nameof(IntervalInstantCurrentNextCheckpoint))]
diff --git a/test/Serilog.Sinks.File.Tests/Serilog.Sinks.File.Tests.csproj b/test/Serilog.Sinks.File.Tests/Serilog.Sinks.File.Tests.csproj
index 5d5af8c..9ad3db7 100644
--- a/test/Serilog.Sinks.File.Tests/Serilog.Sinks.File.Tests.csproj
+++ b/test/Serilog.Sinks.File.Tests/Serilog.Sinks.File.Tests.csproj
@@ -1,7 +1,7 @@
- net48;net6.0
+ net48;net8.0
true
@@ -10,12 +10,12 @@
-
-
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
diff --git a/test/Serilog.Sinks.File.Tests/SharedFileSinkTests.cs b/test/Serilog.Sinks.File.Tests/SharedFileSinkTests.cs
index ec90f25..dff0a0d 100644
--- a/test/Serilog.Sinks.File.Tests/SharedFileSinkTests.cs
+++ b/test/Serilog.Sinks.File.Tests/SharedFileSinkTests.cs
@@ -11,43 +11,39 @@ public class SharedFileSinkTests
[Fact]
public void FileIsWrittenIfNonexistent()
{
- using (var tmp = TempFolder.ForCaller())
- {
- var nonexistent = tmp.AllocateFilename("txt");
- var evt = Some.LogEvent("Hello, world!");
-
- using (var sink = new SharedFileSink(nonexistent, new JsonFormatter(), null))
- {
- sink.Emit(evt);
- }
+ using var tmp = TempFolder.ForCaller();
+ var nonexistent = tmp.AllocateFilename("txt");
+ var evt = Some.LogEvent("Hello, world!");
- var lines = System.IO.File.ReadAllLines(nonexistent);
- Assert.Contains("Hello, world!", lines[0]);
+ using (var sink = new SharedFileSink(nonexistent, new JsonFormatter(), null))
+ {
+ sink.Emit(evt);
}
+
+ var lines = System.IO.File.ReadAllLines(nonexistent);
+ Assert.Contains("Hello, world!", lines[0]);
}
[Fact]
public void FileIsAppendedToWhenAlreadyCreated()
{
- using (var tmp = TempFolder.ForCaller())
- {
- var path = tmp.AllocateFilename("txt");
- var evt = Some.LogEvent("Hello, world!");
+ using var tmp = TempFolder.ForCaller();
+ var path = tmp.AllocateFilename("txt");
+ var evt = Some.LogEvent("Hello, world!");
- using (var sink = new SharedFileSink(path, new JsonFormatter(), null))
- {
- sink.Emit(evt);
- }
-
- using (var sink = new SharedFileSink(path, new JsonFormatter(), null))
- {
- sink.Emit(evt);
- }
+ using (var sink = new SharedFileSink(path, new JsonFormatter(), null))
+ {
+ sink.Emit(evt);
+ }
- var lines = System.IO.File.ReadAllLines(path);
- Assert.Contains("Hello, world!", lines[0]);
- Assert.Contains("Hello, world!", lines[1]);
+ using (var sink = new SharedFileSink(path, new JsonFormatter(), null))
+ {
+ sink.Emit(evt);
}
+
+ var lines = System.IO.File.ReadAllLines(path);
+ Assert.Contains("Hello, world!", lines[0]);
+ Assert.Contains("Hello, world!", lines[1]);
}
[Fact]
@@ -56,23 +52,21 @@ public void WhenLimitIsSpecifiedFileSizeIsRestricted()
const int maxBytes = 5000;
const int eventsToLimit = 10;
- using (var tmp = TempFolder.ForCaller())
- {
- var path = tmp.AllocateFilename("txt");
- var evt = Some.LogEvent(new string('n', maxBytes / eventsToLimit));
+ using var tmp = TempFolder.ForCaller();
+ var path = tmp.AllocateFilename("txt");
+ var evt = Some.LogEvent(new string('n', maxBytes / eventsToLimit));
- using (var sink = new SharedFileSink(path, new JsonFormatter(), maxBytes))
+ using (var sink = new SharedFileSink(path, new JsonFormatter(), maxBytes))
+ {
+ for (var i = 0; i < eventsToLimit * 2; i++)
{
- for (var i = 0; i < eventsToLimit * 2; i++)
- {
- sink.Emit(evt);
- }
+ sink.Emit(evt);
}
-
- var size = new FileInfo(path).Length;
- Assert.True(size > maxBytes);
- Assert.True(size < maxBytes * 2);
}
+
+ var size = new FileInfo(path).Length;
+ Assert.True(size > maxBytes);
+ Assert.True(size < maxBytes * 2);
}
[Fact]
@@ -81,21 +75,19 @@ public void WhenLimitIsNotSpecifiedFileSizeIsNotRestricted()
const int maxBytes = 5000;
const int eventsToLimit = 10;
- using (var tmp = TempFolder.ForCaller())
- {
- var path = tmp.AllocateFilename("txt");
- var evt = Some.LogEvent(new string('n', maxBytes / eventsToLimit));
+ using var tmp = TempFolder.ForCaller();
+ var path = tmp.AllocateFilename("txt");
+ var evt = Some.LogEvent(new string('n', maxBytes / eventsToLimit));
- using (var sink = new SharedFileSink(path, new JsonFormatter(), null))
+ using (var sink = new SharedFileSink(path, new JsonFormatter(), null))
+ {
+ for (var i = 0; i < eventsToLimit * 2; i++)
{
- for (var i = 0; i < eventsToLimit * 2; i++)
- {
- sink.Emit(evt);
- }
+ sink.Emit(evt);
}
-
- var size = new FileInfo(path).Length;
- Assert.True(size > maxBytes * 2);
}
+
+ var size = new FileInfo(path).Length;
+ Assert.True(size > maxBytes * 2);
}
}
diff --git a/test/Serilog.Sinks.File.Tests/Support/ArchiveOldLogsHook.cs b/test/Serilog.Sinks.File.Tests/Support/ArchiveOldLogsHook.cs
index 566b5ba..c8b93a8 100644
--- a/test/Serilog.Sinks.File.Tests/Support/ArchiveOldLogsHook.cs
+++ b/test/Serilog.Sinks.File.Tests/Support/ArchiveOldLogsHook.cs
@@ -1,8 +1,8 @@
namespace Serilog.Sinks.File.Tests.Support;
-internal class ArchiveOldLogsHook : FileLifecycleHooks
+class ArchiveOldLogsHook : FileLifecycleHooks
{
- private readonly string _relativeArchiveDir;
+ readonly string _relativeArchiveDir;
public ArchiveOldLogsHook(string relativeArchiveDir)
{
diff --git a/test/Serilog.Sinks.File.Tests/Support/DelegateDisposable.cs b/test/Serilog.Sinks.File.Tests/Support/DelegateDisposable.cs
index 3386a4f..81a480c 100644
--- a/test/Serilog.Sinks.File.Tests/Support/DelegateDisposable.cs
+++ b/test/Serilog.Sinks.File.Tests/Support/DelegateDisposable.cs
@@ -2,8 +2,8 @@ namespace Serilog.Sinks.File.Tests.Support;
public class DelegateDisposable : IDisposable
{
- private readonly Action _disposeAction;
- private bool _disposed;
+ readonly Action _disposeAction;
+ bool _disposed;
public DelegateDisposable(Action disposeAction)
{
diff --git a/test/Serilog.Sinks.File.Tests/Support/DisposableLogger.cs b/test/Serilog.Sinks.File.Tests/Support/DisposableLogger.cs
deleted file mode 100644
index ff8cf35..0000000
--- a/test/Serilog.Sinks.File.Tests/Support/DisposableLogger.cs
+++ /dev/null
@@ -1,419 +0,0 @@
-using Serilog.Core;
-using Serilog.Events;
-
-namespace Serilog.Sinks.File.Tests.Support;
-
-public class DisposableLogger : ILogger, IDisposable
-{
- public bool Disposed { get; set; }
-
- public void Dispose()
- {
- Disposed = true;
- }
-
- public ILogger ForContext(ILogEventEnricher enricher)
- {
- throw new NotImplementedException();
- }
-
- public ILogger ForContext(IEnumerable enrichers)
- {
- throw new NotImplementedException();
- }
-
- public ILogger ForContext(string propertyName, object value, bool destructureObjects = false)
- {
- throw new NotImplementedException();
- }
-
- public ILogger ForContext()
- {
- throw new NotImplementedException();
- }
-
- public ILogger ForContext(Type source)
- {
- throw new NotImplementedException();
- }
-
- public void Write(LogEvent logEvent)
- {
- throw new NotImplementedException();
- }
-
- public void Write(LogEventLevel level, string messageTemplate)
- {
- throw new NotImplementedException();
- }
-
- public void Write(LogEventLevel level, string messageTemplate, T propertyValue)
- {
- throw new NotImplementedException();
- }
-
- public void Write(LogEventLevel level, string messageTemplate, T0 propertyValue0, T1 propertyValue1)
- {
- throw new NotImplementedException();
- }
-
- public void Write(LogEventLevel level, string messageTemplate, T0 propertyValue0, T1 propertyValue1,
- T2 propertyValue2)
- {
- throw new NotImplementedException();
- }
-
- public void Write(LogEventLevel level, string messageTemplate, params object[] propertyValues)
- {
- throw new NotImplementedException();
- }
-
- public void Write(LogEventLevel level, Exception exception, string messageTemplate)
- {
- throw new NotImplementedException();
- }
-
- public void Write(LogEventLevel level, Exception exception, string messageTemplate, T propertyValue)
- {
- throw new NotImplementedException();
- }
-
- public void Write(LogEventLevel level, Exception exception, string messageTemplate, T0 propertyValue0,
- T1 propertyValue1)
- {
- throw new NotImplementedException();
- }
-
- public void Write(LogEventLevel level, Exception exception, string messageTemplate, T0 propertyValue0,
- T1 propertyValue1, T2 propertyValue2)
- {
- throw new NotImplementedException();
- }
-
- public void Write(LogEventLevel level, Exception exception, string messageTemplate, params object[] propertyValues)
- {
- throw new NotImplementedException();
- }
-
- public bool IsEnabled(LogEventLevel level)
- {
- throw new NotImplementedException();
- }
-
- public void Verbose(string messageTemplate)
- {
- throw new NotImplementedException();
- }
-
- public void Verbose(string messageTemplate, T propertyValue)
- {
- throw new NotImplementedException();
- }
-
- public void Verbose(string messageTemplate, T0 propertyValue0, T1 propertyValue1)
- {
- throw new NotImplementedException();
- }
-
- public void Verbose(string messageTemplate, T0 propertyValue0, T1 propertyValue1, T2 propertyValue2)
- {
- throw new NotImplementedException();
- }
-
- public void Verbose(string messageTemplate, params object[] propertyValues)
- {
- throw new NotImplementedException();
- }
-
- public void Verbose(Exception exception, string messageTemplate)
- {
- throw new NotImplementedException();
- }
-
- public void Verbose(Exception exception, string messageTemplate, T propertyValue)
- {
- throw new NotImplementedException();
- }
-
- public void Verbose(Exception exception, string messageTemplate, T0 propertyValue0, T1 propertyValue1)
- {
- throw new NotImplementedException();
- }
-
- public void Verbose(Exception exception, string messageTemplate, T0 propertyValue0, T1 propertyValue1,
- T2 propertyValue2)
- {
- throw new NotImplementedException();
- }
-
- public void Verbose(Exception exception, string messageTemplate, params object[] propertyValues)
- {
- throw new NotImplementedException();
- }
-
- public void Debug(string messageTemplate)
- {
- throw new NotImplementedException();
- }
-
- public void Debug(string messageTemplate, T propertyValue)
- {
- throw new NotImplementedException();
- }
-
- public void Debug(string messageTemplate, T0 propertyValue0, T1 propertyValue1)
- {
- throw new NotImplementedException();
- }
-
- public void Debug(string messageTemplate, T0 propertyValue0, T1 propertyValue1, T2 propertyValue2)
- {
- throw new NotImplementedException();
- }
-
- public void Debug(string messageTemplate, params object[] propertyValues)
- {
- throw new NotImplementedException();
- }
-
- public void Debug(Exception exception, string messageTemplate)
- {
- throw new NotImplementedException();
- }
-
- public void Debug(Exception exception, string messageTemplate, T propertyValue)
- {
- throw new NotImplementedException();
- }
-
- public void Debug(Exception exception, string messageTemplate, T0 propertyValue0, T1 propertyValue1)
- {
- throw new NotImplementedException();
- }
-
- public void Debug(Exception exception, string messageTemplate, T0 propertyValue0, T1 propertyValue1,
- T2 propertyValue2)
- {
- throw new NotImplementedException();
- }
-
- public void Debug(Exception exception, string messageTemplate, params object[] propertyValues)
- {
- throw new NotImplementedException();
- }
-
- public void Information(string messageTemplate)
- {
- throw new NotImplementedException();
- }
-
- public void Information(string messageTemplate, T propertyValue)
- {
- throw new NotImplementedException();
- }
-
- public void Information(string messageTemplate, T0 propertyValue0, T1 propertyValue1)
- {
- throw new NotImplementedException();
- }
-
- public void Information(string messageTemplate, T0 propertyValue0, T1 propertyValue1, T2 propertyValue2)
- {
- throw new NotImplementedException();
- }
-
- public void Information(string messageTemplate, params object[] propertyValues)
- {
- throw new NotImplementedException();
- }
-
- public void Information(Exception exception, string messageTemplate)
- {
- throw new NotImplementedException();
- }
-
- public void Information(Exception exception, string messageTemplate, T propertyValue)
- {
- throw new NotImplementedException();
- }
-
- public void Information(Exception exception, string messageTemplate, T0 propertyValue0, T1 propertyValue1)
- {
- throw new NotImplementedException();
- }
-
- public void Information(Exception exception, string messageTemplate, T0 propertyValue0, T1 propertyValue1,
- T2 propertyValue2)
- {
- throw new NotImplementedException();
- }
-
- public void Information(Exception exception, string messageTemplate, params object[] propertyValues)
- {
- throw new NotImplementedException();
- }
-
- public void Warning(string messageTemplate)
- {
- throw new NotImplementedException();
- }
-
- public void Warning(string messageTemplate, T propertyValue)
- {
- throw new NotImplementedException();
- }
-
- public void Warning(string messageTemplate, T0 propertyValue0, T1 propertyValue1)
- {
- throw new NotImplementedException();
- }
-
- public void Warning(string messageTemplate, T0 propertyValue0, T1 propertyValue1, T2 propertyValue2)
- {
- throw new NotImplementedException();
- }
-
- public void Warning(string messageTemplate, params object[] propertyValues)
- {
- throw new NotImplementedException();
- }
-
- public void Warning(Exception exception, string messageTemplate)
- {
- throw new NotImplementedException();
- }
-
- public void Warning(Exception exception, string messageTemplate, T propertyValue)
- {
- throw new NotImplementedException();
- }
-
- public void Warning(Exception exception, string messageTemplate, T0 propertyValue0, T1 propertyValue1)
- {
- throw new NotImplementedException();
- }
-
- public void Warning(Exception exception, string messageTemplate, T0 propertyValue0, T1 propertyValue1,
- T2 propertyValue2)
- {
- throw new NotImplementedException();
- }
-
- public void Warning(Exception exception, string messageTemplate, params object[] propertyValues)
- {
- throw new NotImplementedException();
- }
-
- public void Error(string messageTemplate)
- {
- throw new NotImplementedException();
- }
-
- public void Error(string messageTemplate, T propertyValue)
- {
- throw new NotImplementedException();
- }
-
- public void Error(string messageTemplate, T0 propertyValue0, T1 propertyValue1)
- {
- throw new NotImplementedException();
- }
-
- public void Error(string messageTemplate, T0 propertyValue0, T1 propertyValue1, T2 propertyValue2)
- {
- throw new NotImplementedException();
- }
-
- public void Error(string messageTemplate, params object[] propertyValues)
- {
- throw new NotImplementedException();
- }
-
- public void Error(Exception exception, string messageTemplate)
- {
- throw new NotImplementedException();
- }
-
- public void Error(Exception exception, string messageTemplate, T propertyValue)
- {
- throw new NotImplementedException();
- }
-
- public void Error(Exception exception, string messageTemplate, T0 propertyValue0, T1 propertyValue1)
- {
- throw new NotImplementedException();
- }
-
- public void Error(Exception exception, string messageTemplate, T0 propertyValue0, T1 propertyValue1,
- T2 propertyValue2)
- {
- throw new NotImplementedException();
- }
-
- public void Error(Exception exception, string messageTemplate, params object[] propertyValues)
- {
- throw new NotImplementedException();
- }
-
- public void Fatal(string messageTemplate)
- {
- throw new NotImplementedException();
- }
-
- public void Fatal(string messageTemplate, T propertyValue)
- {
- throw new NotImplementedException();
- }
-
- public void Fatal(string messageTemplate, T0 propertyValue0, T1 propertyValue1)
- {
- throw new NotImplementedException();
- }
-
- public void Fatal(string messageTemplate, T0 propertyValue0, T1 propertyValue1, T2 propertyValue2)
- {
- throw new NotImplementedException();
- }
-
- public void Fatal(string messageTemplate, params object[] propertyValues)
- {
- throw new NotImplementedException();
- }
-
- public void Fatal(Exception exception, string messageTemplate)
- {
- throw new NotImplementedException();
- }
-
- public void Fatal(Exception exception, string messageTemplate, T propertyValue)
- {
- throw new NotImplementedException();
- }
-
- public void Fatal(Exception exception, string messageTemplate, T0 propertyValue0, T1 propertyValue1)
- {
- throw new NotImplementedException();
- }
-
- public void Fatal(Exception exception, string messageTemplate, T0 propertyValue0, T1 propertyValue1,
- T2 propertyValue2)
- {
- throw new NotImplementedException();
- }
-
- public void Fatal(Exception exception, string messageTemplate, params object[] propertyValues)
- {
- throw new NotImplementedException();
- }
-
- public bool BindMessageTemplate(string messageTemplate, object[] propertyValues, out MessageTemplate parsedTemplate,
- out IEnumerable boundProperties)
- {
- throw new NotImplementedException();
- }
-
- public bool BindProperty(string propertyName, object value, bool destructureObjects, out LogEventProperty property)
- {
- throw new NotImplementedException();
- }
-}
diff --git a/test/Serilog.Sinks.File.Tests/Support/Extensions.cs b/test/Serilog.Sinks.File.Tests/Support/Extensions.cs
index 3fd7a15..db8781b 100644
--- a/test/Serilog.Sinks.File.Tests/Support/Extensions.cs
+++ b/test/Serilog.Sinks.File.Tests/Support/Extensions.cs
@@ -4,7 +4,7 @@ namespace Serilog.Sinks.File.Tests.Support;
public static class Extensions
{
- public static object LiteralValue(this LogEventPropertyValue @this)
+ public static object? LiteralValue(this LogEventPropertyValue @this)
{
return ((ScalarValue)@this).Value;
}
@@ -13,13 +13,11 @@ public static List ReadAllLines(this Stream @this)
{
var lines = new List();
- using (var reader = new StreamReader(@this))
+ using var reader = new StreamReader(@this);
+ string? line;
+ while ((line = reader.ReadLine()) != null)
{
- string? line;
- while ((line = reader.ReadLine()) != null)
- {
- lines.Add(line);
- }
+ lines.Add(line);
}
return lines;