Skip to content

Commit

Permalink
Merge pull request #30 from serilog/dev
Browse files Browse the repository at this point in the history
3.2.0 Release
  • Loading branch information
nblumhardt authored Jan 3, 2017
2 parents 7be22d6 + 8c866ab commit c8418ed
Show file tree
Hide file tree
Showing 15 changed files with 258 additions and 36 deletions.
13 changes: 12 additions & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
root=true
root = true

[*]
trim_trailing_whitespace = true
insert_final_newline = true
indent_style = space
indent_size = 4

[*.{csproj,json,config,yml}]
indent_size = 2

[*.sh]
end_of_line = lf

[*.{cmd, bat}]
end_of_line = crlf
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -234,3 +234,4 @@ _Pvt_Extensions

# FAKE - F# Make
.fake/
example/Sample/log.txt
49 changes: 49 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
language: csharp

#dotnet cli require Ubuntu 14.04
sudo: required
dist: trusty

#dotnet cli require OSX 10.10
osx_image: xcode7.1

addons:
apt:
packages:
- gettext
- libcurl4-openssl-dev
- libicu-dev
- libssl-dev
- libunwind8
- zlib1g

os:
- linux

env:
global:
- DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
- TMP: /tmp

matrix:
- CLI_VERSION=1.0.0-preview2-003121
- CLI_VERSION=Latest

matrix:
allow_failures:
- env: CLI_VERSION=Latest

before_install:
- if test "$TRAVIS_OS_NAME" == "osx"; then brew update; brew install openssl; brew link --force openssl; fi
# Download script to install dotnet cli
- if test "$CLI_OBTAIN_URL" == ""; then export CLI_OBTAIN_URL="https://raw.githubusercontent.com/dotnet/cli/rel/1.0.0-preview2/scripts/obtain/dotnet-install.sh"; fi
- curl -L --create-dirs $CLI_OBTAIN_URL -o ./scripts/obtain/install.sh
- find ./scripts -name "*.sh" -exec chmod +x {} \;
- export DOTNET_INSTALL_DIR="$PWD/.dotnetcli"
# use bash to workaround bug https://github.com/dotnet/cli/issues/1725
- sudo bash ./scripts/obtain/install.sh --channel "preview" --version "$CLI_VERSION" --install-dir "$DOTNET_INSTALL_DIR" --no-path
# add dotnet to PATH
- export PATH="$DOTNET_INSTALL_DIR:$PATH"

script:
- ./build.sh
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Serilog.Sinks.File [![Build status](https://ci.appveyor.com/api/projects/status/hh9gymy0n6tne46j?svg=true)](https://ci.appveyor.com/project/serilog/serilog-sinks-file) [![NuGet Version](http://img.shields.io/nuget/v/Serilog.Sinks.File.svg?style=flat)](https://www.nuget.org/packages/Serilog.Sinks.File/) [![Documentation](https://img.shields.io/badge/docs-wiki-yellow.svg)](https://github.com/serilog/serilog/wiki) [![Join the chat at https://gitter.im/serilog/serilog](https://img.shields.io/gitter/room/serilog/serilog.svg)](https://gitter.im/serilog/serilog)
# Serilog.Sinks.File [![Build status](https://ci.appveyor.com/api/projects/status/hh9gymy0n6tne46j?svg=true)](https://ci.appveyor.com/project/serilog/serilog-sinks-file) [![Travis build](https://travis-ci.org/serilog/serilog-sinks-file.svg)](https://travis-ci.org/serilog/serilog-sinks-file) [![NuGet Version](http://img.shields.io/nuget/v/Serilog.Sinks.File.svg?style=flat)](https://www.nuget.org/packages/Serilog.Sinks.File/) [![Documentation](https://img.shields.io/badge/docs-wiki-yellow.svg)](https://github.com/serilog/serilog/wiki) [![Join the chat at https://gitter.im/serilog/serilog](https://img.shields.io/gitter/room/serilog/serilog.svg)](https://gitter.im/serilog/serilog)

Writes [Serilog](https://serilog.net) events to a text file.

Expand Down
12 changes: 12 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/bash
dotnet restore --no-cache
for path in src/*/project.json; do
dirname="$(dirname "${path}")"
dotnet build ${dirname} -f netstandard1.3 -c Release
done

for path in test/*.Tests/project.json; do
dirname="$(dirname "${path}")"
dotnet build ${dirname} -f netcoreapp1.0 -c Release
dotnet test ${dirname} -f netcoreapp1.0 -c Release
done
4 changes: 2 additions & 2 deletions example/Sample/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ public static void Main(string[] args)
{
SelfLog.Enable(Console.Out);

var sw = System.Diagnostics.Stopwatch.StartNew();

Log.Logger = new LoggerConfiguration()
.WriteTo.File("log.txt")
.CreateLogger();

var sw = System.Diagnostics.Stopwatch.StartNew();

for (var i = 0; i < 1000000; ++i)
{
Log.Information("Hello, file logger!");
Expand Down
3 changes: 3 additions & 0 deletions serilog-sinks-file.sln
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{037440DE-440
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "assets", "assets", "{E9D1B5E1-DEB9-4A04-8BAB-24EC7240ADAF}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
.travis.yml = .travis.yml
appveyor.yml = appveyor.yml
Build.ps1 = Build.ps1
build.sh = build.sh
global.json = global.json
NuGet.Config = NuGet.Config
README.md = README.md
Expand Down
16 changes: 2 additions & 14 deletions src/Serilog.Sinks.File/FileLoggerConfigurationExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -180,32 +180,20 @@ static LoggerConfiguration ConfigureFile(
if (formatter == null) throw new ArgumentNullException(nameof(formatter));
if (path == null) throw new ArgumentNullException(nameof(path));
if (fileSizeLimitBytes.HasValue && fileSizeLimitBytes < 0) throw new ArgumentException("Negative value provided; file size limit must be non-negative");

if (shared)
{
#if ATOMIC_APPEND
if (buffered)
throw new ArgumentException("Buffered writes are not available when file sharing is enabled.", nameof(buffered));
#else
throw new NotSupportedException("File sharing is not supported on this platform.");
#endif
}
if (shared && buffered)
throw new ArgumentException("Buffered writes are not available when file sharing is enabled.", nameof(buffered));

ILogEventSink sink;
try
{
#if ATOMIC_APPEND
if (shared)
{
sink = new SharedFileSink(path, formatter, fileSizeLimitBytes);
}
else
{
#endif
sink = new FileSink(path, formatter, fileSizeLimitBytes, buffered: buffered);
#if ATOMIC_APPEND
}
#endif
}
catch (Exception ex)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,7 @@ public sealed class SharedFileSink : ILogEventSink, IFlushableFileSink, IDisposa
/// <returns>Configuration object allowing method chaining.</returns>
/// <remarks>The file will be written using the UTF-8 character set.</remarks>
/// <exception cref="IOException"></exception>
public SharedFileSink(string path, ITextFormatter textFormatter, long? fileSizeLimitBytes,
Encoding encoding = null)
public SharedFileSink(string path, ITextFormatter textFormatter, long? fileSizeLimitBytes, Encoding encoding = null)
{
if (path == null) throw new ArgumentNullException(nameof(path));
if (textFormatter == null) throw new ArgumentNullException(nameof(textFormatter));
Expand Down
162 changes: 162 additions & 0 deletions src/Serilog.Sinks.File/Sinks/File/SharedFileSink.OSMutex.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
// Copyright 2013-2016 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.

#if OS_MUTEX

using System;
using System.IO;
using System.Text;
using Serilog.Core;
using Serilog.Events;
using Serilog.Formatting;
using System.Threading;
using Serilog.Debugging;

namespace Serilog.Sinks.File
{
/// <summary>
/// Write log events to a disk file.
/// </summary>
public sealed class SharedFileSink : ILogEventSink, IFlushableFileSink, IDisposable
{
readonly TextWriter _output;
readonly FileStream _underlyingStream;
readonly ITextFormatter _textFormatter;
readonly long? _fileSizeLimitBytes;
readonly object _syncRoot = new object();

const string MutexNameSuffix = ".serilog";
const int MutexWaitTimeout = 10000;
readonly Mutex _mutex;

/// <summary>Construct a <see cref="FileSink"/>.</summary>
/// <param name="path">Path to the file.</param>
/// <param name="textFormatter">Formatter used to convert log events to text.</param>
/// <param name="fileSizeLimitBytes">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.</param>
/// <param name="encoding">Character encoding used to write the text file. The default is UTF-8 without BOM.</param>
/// <returns>Configuration object allowing method chaining.</returns>
/// <remarks>The file will be written using the UTF-8 character set.</remarks>
/// <exception cref="IOException"></exception>
public SharedFileSink(string path, ITextFormatter textFormatter, long? fileSizeLimitBytes, Encoding encoding = null)
{
if (path == null) throw new ArgumentNullException(nameof(path));
if (textFormatter == null) throw new ArgumentNullException(nameof(textFormatter));
if (fileSizeLimitBytes.HasValue && fileSizeLimitBytes < 0)
throw new ArgumentException("Negative value provided; file size limit must be non-negative");

_textFormatter = textFormatter;
_fileSizeLimitBytes = fileSizeLimitBytes;

var directory = Path.GetDirectoryName(path);
if (!string.IsNullOrWhiteSpace(directory) && !Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}

var mutexName = Path.GetFullPath(path).Replace(Path.DirectorySeparatorChar, ':') + MutexNameSuffix;
_mutex = new Mutex(false, mutexName);
_underlyingStream = System.IO.File.Open(path, FileMode.Append, FileAccess.Write, FileShare.ReadWrite);
_output = new StreamWriter(_underlyingStream, encoding ?? new UTF8Encoding(encoderShouldEmitUTF8Identifier: false));
}

/// <summary>
/// Emit the provided log event to the sink.
/// </summary>
/// <param name="logEvent">The log event to write.</param>
public void Emit(LogEvent logEvent)
{
if (logEvent == null) throw new ArgumentNullException(nameof(logEvent));

lock (_syncRoot)
{
if (!TryAcquireMutex())
return;

try
{
_underlyingStream.Seek(0, SeekOrigin.End);
if (_fileSizeLimitBytes != null)
{
if (_underlyingStream.Length >= _fileSizeLimitBytes.Value)
return;
}

_textFormatter.Format(logEvent, _output);
_output.Flush();
_underlyingStream.Flush();
}
finally
{
ReleaseMutex();
}
}
}

/// <inheritdoc />
public void Dispose()
{
lock (_syncRoot)
{
_output.Dispose();
_mutex.Dispose();
}
}

/// <inheritdoc />
public void FlushToDisk()
{
lock (_syncRoot)
{
if (!TryAcquireMutex())
return;

try
{
_underlyingStream.Flush(true);
}
finally
{
ReleaseMutex();
}
}
}

bool TryAcquireMutex()
{
try
{
if (!_mutex.WaitOne(MutexWaitTimeout))
{
SelfLog.WriteLine("Shared file mutex could not be acquired within {0} ms", MutexWaitTimeout);
return false;
}
}
catch (AbandonedMutexException)
{
SelfLog.WriteLine("Inherited shared file mutex after abandonment by another process");
}

return true;
}

void ReleaseMutex()
{
_mutex.ReleaseMutex();
}
}
}

#endif
6 changes: 4 additions & 2 deletions src/Serilog.Sinks.File/project.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "3.1.1-*",
"version": "3.2.0-*",
"description": "Write Serilog events to a text file in plain or JSON format.",
"authors": [ "Serilog Contributors" ],
"packOptions": {
Expand All @@ -20,12 +20,14 @@
"buildOptions": { "define": [ "ATOMIC_APPEND" ] }
},
"netstandard1.3": {
"buildOptions": { "define": [ "OS_MUTEX" ] },
"dependencies": {
"System.IO": "4.1.0",
"System.IO.FileSystem": "4.0.1",
"System.IO.FileSystem.Primitives": "4.0.1",
"System.Text.Encoding.Extensions": "4.0.11",
"System.Threading.Timer": "4.0.1"
"System.Threading.Timer": "4.0.1",
"System.Threading": "4.0.11"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
using System;
using System.Threading;
using Serilog;
using Serilog.Sinks.File.Tests.Support;
using Serilog.Tests.Support;
using Xunit;
using System.IO;

namespace Serilog.Tests
{
public class FileLoggerConfigurationExtensionsTests
{
const string InvalidPath = "/\\";
static readonly string InvalidPath = new string(Path.GetInvalidPathChars());

[Fact]
public void WhenWritingCreationExceptionsAreSuppressed()
Expand Down Expand Up @@ -66,7 +66,6 @@ public void WhenFlushingToDiskReportedFileSinkCanBeCreatedAndDisposed()
}
}

#if ATOMIC_APPEND
[Fact]
public void WhenFlushingToDiskReportedSharedFileSinkCanBeCreatedAndDisposed()
{
Expand All @@ -79,6 +78,5 @@ public void WhenFlushingToDiskReportedSharedFileSinkCanBeCreatedAndDisposed()
Thread.Sleep(TimeSpan.FromSeconds(1));
}
}
#endif
}
}
6 changes: 1 addition & 5 deletions test/Serilog.Sinks.File.Tests/SharedFileSinkTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
#if ATOMIC_APPEND

using System.IO;
using System.IO;
using Xunit;
using Serilog.Formatting.Json;
using Serilog.Sinks.File.Tests.Support;
Expand Down Expand Up @@ -102,5 +100,3 @@ public void WhenLimitIsNotSpecifiedFileSizeIsNotRestricted()
}
}
}

#endif
Loading

0 comments on commit c8418ed

Please sign in to comment.