Skip to content

Commit d8ea12f

Browse files
authored
Merge pull request #18 from serilog/dev
3.0.0 Release
2 parents 3de698a + ead53d0 commit d8ea12f

File tree

6 files changed

+63
-20
lines changed

6 files changed

+63
-20
lines changed

Diff for: README.md

+6
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,12 @@ To write events to the file in an alternative format such as JSON, pass an `ITex
146146
.WriteTo.RollingFile(new JsonFormatter(), "log-{Date}.txt")
147147
```
148148

149+
### Performance
150+
151+
By default, the rolling file sink will flush each event written through it to disk. To improve write performance, specifying `buffered: true` will permit the underlying stream to buffer writes.
152+
153+
The [Serilog.Sinks.Async](https://github.com/serilog/serilog-sinks-async) package can be used to wrap the rolling file sink and perform all disk accss on a background worker thread.
154+
149155
### Alternatives
150156

151157
The default rolling file sink is designed to suit most applications. So that we can keep it maintainable and reliable, it does not provide a large range of optional behavior. Check out alternative implemementations like [this one](https://github.com/BedeGaming/sinks-rollingfile) if your needs aren't met by the default version.

Diff for: src/Serilog.Sinks.RollingFile/RollingFileLoggerConfigurationExtensions.cs

+14-6
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,9 @@ public static class RollingFileLoggerConfigurationExtensions
5353
/// including the current log file. For unlimited retention, pass null. The default is 31.</param>
5454
/// <param name="buffered">Indicates if flushing to the output file can be buffered or not. The default
5555
/// is false.</param>
56+
/// <param name="shared">Allow the log files to be shared by multiple processes. The default is false.</param>
5657
/// <returns>Configuration object allowing method chaining.</returns>
57-
/// <remarks>The file will be written using the UTF-8 character set.</remarks>
58+
/// <remarks>The file will be written using the UTF-8 encoding without a byte-order mark.</remarks>
5859
public static LoggerConfiguration RollingFile(
5960
this LoggerSinkConfiguration sinkConfiguration,
6061
string pathFormat,
@@ -64,11 +65,12 @@ public static LoggerConfiguration RollingFile(
6465
long? fileSizeLimitBytes = DefaultFileSizeLimitBytes,
6566
int? retainedFileCountLimit = DefaultRetainedFileCountLimit,
6667
LoggingLevelSwitch levelSwitch = null,
67-
bool buffered = false)
68+
bool buffered = false,
69+
bool shared = false)
6870
{
6971
var formatter = new MessageTemplateTextFormatter(outputTemplate, formatProvider);
7072
return RollingFile(sinkConfiguration, formatter, pathFormat, restrictedToMinimumLevel, fileSizeLimitBytes,
71-
retainedFileCountLimit, levelSwitch, buffered);
73+
retainedFileCountLimit, levelSwitch, buffered, shared);
7274
}
7375

7476
/// <summary>
@@ -92,8 +94,9 @@ public static LoggerConfiguration RollingFile(
9294
/// including the current log file. For unlimited retention, pass null. The default is 31.</param>
9395
/// <param name="buffered">Indicates if flushing to the output file can be buffered or not. The default
9496
/// is false.</param>
97+
/// <param name="shared">Allow the log files to be shared by multiple processes. The default is false.</param>
9598
/// <returns>Configuration object allowing method chaining.</returns>
96-
/// <remarks>The file will be written using the UTF-8 character set.</remarks>
99+
/// <remarks>The file will be written using the UTF-8 encoding without a byte-order mark.</remarks>
97100
public static LoggerConfiguration RollingFile(
98101
this LoggerSinkConfiguration sinkConfiguration,
99102
ITextFormatter formatter,
@@ -102,11 +105,16 @@ public static LoggerConfiguration RollingFile(
102105
long? fileSizeLimitBytes = DefaultFileSizeLimitBytes,
103106
int? retainedFileCountLimit = DefaultRetainedFileCountLimit,
104107
LoggingLevelSwitch levelSwitch = null,
105-
bool buffered = false)
108+
bool buffered = false,
109+
bool shared = false)
106110
{
107111
if (sinkConfiguration == null) throw new ArgumentNullException(nameof(sinkConfiguration));
108112
if (formatter == null) throw new ArgumentNullException(nameof(formatter));
109-
var sink = new RollingFileSink(pathFormat, formatter, fileSizeLimitBytes, retainedFileCountLimit, buffered: buffered);
113+
114+
if (shared && buffered)
115+
throw new ArgumentException("Buffered writes are not available when file sharing is enabled.", nameof(buffered));
116+
117+
var sink = new RollingFileSink(pathFormat, formatter, fileSizeLimitBytes, retainedFileCountLimit, buffered: buffered, shared: shared);
110118
return sinkConfiguration.Sink(sink, restrictedToMinimumLevel, levelSwitch);
111119
}
112120
}

Diff for: src/Serilog.Sinks.RollingFile/Sinks/RollingFile/RollingFileSink.cs

+21-7
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,12 @@ public sealed class RollingFileSink : ILogEventSink, IDisposable
3939
readonly int? _retainedFileCountLimit;
4040
readonly Encoding _encoding;
4141
readonly bool _buffered;
42+
readonly bool _shared;
4243
readonly object _syncRoot = new object();
4344

4445
bool _isDisposed;
4546
DateTime? _nextCheckpoint;
46-
FileSink _currentFile;
47+
ILogEventSink _currentFile;
4748

4849
/// <summary>Construct a <see cref="RollingFileSink"/>.</summary>
4950
/// <param name="pathFormat">String describing the location of the log files,
@@ -54,28 +55,36 @@ public sealed class RollingFileSink : ILogEventSink, IDisposable
5455
/// For unrestricted growth, pass null. The default is 1 GB.</param>
5556
/// <param name="retainedFileCountLimit">The maximum number of log files that will be retained,
5657
/// including the current log file. For unlimited retention, pass null. The default is 31.</param>
57-
/// <param name="encoding">Character encoding used to write the text file. The default is UTF-8.</param>
58+
/// <param name="encoding">Character encoding used to write the text file. The default is UTF-8 without BOM.</param>
5859
/// <param name="buffered">Indicates if flushing to the output file can be buffered or not. The default
5960
/// is false.</param>
61+
/// <param name="shared">Allow the log files to be shared by multiple processes. The default is false.</param>
6062
/// <returns>Configuration object allowing method chaining.</returns>
6163
/// <remarks>The file will be written using the UTF-8 character set.</remarks>
6264
public RollingFileSink(string pathFormat,
6365
ITextFormatter textFormatter,
6466
long? fileSizeLimitBytes,
6567
int? retainedFileCountLimit,
6668
Encoding encoding = null,
67-
bool buffered = false)
69+
bool buffered = false,
70+
bool shared = false)
6871
{
6972
if (pathFormat == null) throw new ArgumentNullException(nameof(pathFormat));
7073
if (fileSizeLimitBytes.HasValue && fileSizeLimitBytes < 0) throw new ArgumentException("Negative value provided; file size limit must be non-negative");
7174
if (retainedFileCountLimit.HasValue && retainedFileCountLimit < 1) throw new ArgumentException("Zero or negative value provided; retained file count limit must be at least 1");
7275

76+
#if !SHARING
77+
if (shared)
78+
throw new NotSupportedException("File sharing is not supported on this platform.");
79+
#endif
80+
7381
_roller = new TemplatedPathRoller(pathFormat);
7482
_textFormatter = textFormatter;
7583
_fileSizeLimitBytes = fileSizeLimitBytes;
7684
_retainedFileCountLimit = retainedFileCountLimit;
77-
_encoding = encoding ?? new UTF8Encoding(encoderShouldEmitUTF8Identifier: false);
85+
_encoding = encoding;
7886
_buffered = buffered;
87+
_shared = shared;
7988
}
8089

8190
/// <summary>
@@ -98,8 +107,7 @@ public void Emit(LogEvent logEvent)
98107
// If the file was unable to be opened on the last attempt, it will remain
99108
// null until the next checkpoint passes, at which time another attempt will be made to
100109
// open it.
101-
if (_currentFile != null)
102-
_currentFile.Emit(logEvent);
110+
_currentFile?.Emit(logEvent);
103111
}
104112
}
105113

@@ -148,7 +156,13 @@ void OpenFile(DateTime now)
148156

149157
try
150158
{
159+
#if SHARING
160+
_currentFile = _shared ?
161+
(ILogEventSink)new SharedFileSink(path, _textFormatter, _fileSizeLimitBytes, _encoding) :
162+
new FileSink(path, _textFormatter, _fileSizeLimitBytes, _encoding, _buffered);
163+
#else
151164
_currentFile = new FileSink(path, _textFormatter, _fileSizeLimitBytes, _encoding, _buffered);
165+
#endif
152166
}
153167
catch (IOException ex)
154168
{
@@ -223,7 +237,7 @@ void CloseFile()
223237
{
224238
if (_currentFile != null)
225239
{
226-
_currentFile.Dispose();
240+
(_currentFile as IDisposable)?.Dispose();
227241
_currentFile = null;
228242
}
229243

Diff for: src/Serilog.Sinks.RollingFile/project.json

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"version": "2.2.0-*",
2+
"version": "3.0.0-*",
33
"description": "The rolling file sink for Serilog - Simple .NET logging with fully-structured events",
44
"authors": [ "Serilog Contributors" ],
55
"packOptions": {
@@ -9,16 +9,17 @@
99
"iconUrl": "http://serilog.net/images/serilog-sink-nuget.png"
1010
},
1111
"dependencies": {
12-
"Serilog": "2.0.0",
13-
"Serilog.Sinks.File": "2.0.0"
12+
"Serilog.Sinks.File": "3.0.0"
1413
},
1514
"buildOptions": {
1615
"keyFile": "../../assets/Serilog.snk",
1716
"xmlDoc": true,
1817
"warningsAsErrors": true
1918
},
2019
"frameworks": {
21-
"net4.5": {},
20+
"net4.5": {
21+
"buildOptions": {"define": ["SHARING"]}
22+
},
2223
"netstandard1.3": {
2324
"dependencies": {
2425
"System.IO": "4.1.0",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System;
2+
using Xunit;
3+
4+
namespace Serilog.Tests
5+
{
6+
public class RollingFileLoggerConfigurationExtensionsTests
7+
{
8+
[Fact]
9+
public void BuffferingIsNotAvailableWhenSharingEnabled()
10+
{
11+
Assert.Throws<ArgumentException>(() =>
12+
new LoggerConfiguration()
13+
.WriteTo.RollingFile("logs", buffered: true, shared: true));
14+
}
15+
}
16+
}

Diff for: test/Serilog.Sinks.RollingFile.Tests/project.json

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
{
2-
"version": "2.0.0",
32
"testRunner": "xunit",
43
"dependencies": {
54
"Serilog.Sinks.RollingFile": { "target": "project" },
65
"xunit": "2.1.0",
7-
"dotnet-test-xunit": "1.0.0-rc2-build10025",
8-
"Serilog.Sinks.File": "2.0.0"
6+
"dotnet-test-xunit": "1.0.0-rc2-build10025"
97
},
108
"buildOptions": {
119
"keyFile": "../../assets/Serilog.snk",

0 commit comments

Comments
 (0)