Skip to content

Support AuditTo in configuration #87

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Feb 10, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion serilog-settings-configuration.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26228.10
VisualStudioVersion = 15.0.27130.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{4E41FD57-5FAB-4E3C-B16E-463DE98338BC}"
EndProject
Expand All @@ -24,6 +24,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Serilog.Settings.Configurat
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample", "sample\Sample\Sample.csproj", "{A00E5E32-54F9-401A-BBA1-2F6FCB6366CD}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestDummies", "test\TestDummies\TestDummies.csproj", "{B7CF5068-DD19-4868-A268-5280BDE90361}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -42,6 +44,10 @@ Global
{A00E5E32-54F9-401A-BBA1-2F6FCB6366CD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A00E5E32-54F9-401A-BBA1-2F6FCB6366CD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A00E5E32-54F9-401A-BBA1-2F6FCB6366CD}.Release|Any CPU.Build.0 = Release|Any CPU
{B7CF5068-DD19-4868-A268-5280BDE90361}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B7CF5068-DD19-4868-A268-5280BDE90361}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B7CF5068-DD19-4868-A268-5280BDE90361}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B7CF5068-DD19-4868-A268-5280BDE90361}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -50,5 +56,9 @@ Global
{21FF98ED-E68C-4A67-B241-C8D6122FAD7D} = {4E41FD57-5FAB-4E3C-B16E-463DE98338BC}
{F793C6E8-C40A-4018-8884-C97E2BE38A54} = {D551DCB0-7771-4D01-BEBD-F7B57D1CF0E3}
{A00E5E32-54F9-401A-BBA1-2F6FCB6366CD} = {D24872B9-57F3-42A7-BC8D-F9DA222FCE1B}
{B7CF5068-DD19-4868-A268-5280BDE90361} = {D551DCB0-7771-4D01-BEBD-F7B57D1CF0E3}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {485F8843-42D7-4267-B5FB-20FE9181DEE9}
EndGlobalSection
EndGlobal
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,20 @@
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
<PackageId>Serilog.Settings.Configuration</PackageId>
<PackageTags>serilog;json</PackageTags>
<PackageIconUrl>http://serilog.net/images/serilog-configuration-nuget.png</PackageIconUrl>
<PackageProjectUrl>http://serilog.net</PackageProjectUrl>
<PackageLicenseUrl>http://www.apache.org/licenses/LICENSE-2.0</PackageLicenseUrl>
<PackageIconUrl>https://serilog.net/images/serilog-configuration-nuget.png</PackageIconUrl>
<PackageProjectUrl>https://github.com/serilog/serilog-settings-configuration</PackageProjectUrl>
<PackageLicenseUrl>https://www.apache.org/licenses/LICENSE-2.0</PackageLicenseUrl>

<!-- Don't reference the full NETStandard.Library -->
<DisableImplicitFrameworkReferences>true</DisableImplicitFrameworkReferences>
<RootNamespace>Serilog</RootNamespace>
<Version>2.5.0</Version>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="1.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="1.0.0" />
<PackageReference Include="Serilog" Version="2.0.0" />
<PackageReference Include="Serilog" Version="2.6.0" />
</ItemGroup>

<PropertyGroup Condition=" '$(TargetFramework)' == 'net451' ">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public void Configure(LoggerConfiguration loggerConfiguration)
ApplyEnrichment(loggerConfiguration);
ApplyFilters(loggerConfiguration);
ApplySinks(loggerConfiguration);
ApplyAuditSinks(loggerConfiguration);
}

void ApplyMinimumLevel(LoggerConfiguration loggerConfiguration)
Expand Down Expand Up @@ -98,6 +99,16 @@ void ApplySinks(LoggerConfiguration loggerConfiguration)
}
}

void ApplyAuditSinks(LoggerConfiguration loggerConfiguration)
{
var auditToDirective = _configuration.GetSection("AuditTo");
if (auditToDirective != null)
{
var methodCalls = GetMethodCalls(auditToDirective);
CallConfigurationMethods(methodCalls, FindAuditSinkConfigurationMethods(_configurationAssemblies), loggerConfiguration.AuditTo);
}
}

void IConfigurationReader.ApplySinks(LoggerSinkConfiguration loggerSinkConfiguration)
{
var methodCalls = GetMethodCalls(_configuration);
Expand Down Expand Up @@ -260,6 +271,13 @@ internal static IList<MethodInfo> FindSinkConfigurationMethods(IEnumerable<Assem
return found;
}

internal static IList<MethodInfo> FindAuditSinkConfigurationMethods(IEnumerable<Assembly> configurationAssemblies)
{
var found = FindConfigurationMethods(configurationAssemblies, typeof(LoggerAuditSinkConfiguration));
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All the other methods somehow used found.Add(GetSurrogateConfigurationMethod<T> , but I was not sure whether that was needed for Audit ..

Copy link
Contributor

@skomis-mm skomis-mm Feb 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tsimbalar GetSurrogateConfigurationMethod<T> is for methods mimicking static methods (extensions) and used just to get MethodInfo using expressions without reflection, but implementation I did is overcomplicated and just realized you can get MehtodInfo right out of method group after casting to appropriate delegate type:
((Func<LoggerFilterConfiguration, ILogEventFilter, LoggerConfiguration>)With).MethodInfo

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh I see. I guess it might not be necessary for AuditTo

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it'd be needed for AuditTo.Logger() .. but this seems like a bit of a fringe case.


return found;
}

internal static IList<MethodInfo> FindFilterConfigurationMethods(IEnumerable<Assembly> configurationAssemblies)
{
var found = FindConfigurationMethods(configurationAssemblies, typeof(LoggerFilterConfiguration));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
using System;
using Microsoft.Extensions.Configuration;
using Serilog.Events;
using Serilog.Settings.Configuration.Tests.Support;
using TestDummies;
using TestDummies.Console;
using TestDummies.Console.Themes;
using Xunit;

namespace Serilog.Settings.Configuration.Tests
{
public class ConfigurationSettingsTests
{
private static LoggerConfiguration ConfigFromJson(string jsonString)
{
var config = new ConfigurationBuilder().AddJsonString(jsonString).Build();
return new LoggerConfiguration()
.ReadFrom.Configuration(config);
}

[Fact]
public void PropertyEnrichmentIsApplied()
{
LogEvent evt = null;

var json = @"{
""Serilog"": {
""Properties"": {
""App"": ""Test""
}
}
}";

var log = ConfigFromJson(json)
.WriteTo.Sink(new DelegatingSink(e => evt = e))
.CreateLogger();

log.Information("Has a test property");

Assert.NotNull(evt);
Assert.Equal("Test", evt.Properties["App"].LiteralValue());
}

[Theory]
[InlineData("extended syntax",
@"{
""Serilog"": {
""Using"": [""TestDummies""],
""WriteTo"": [
{ ""Name"": ""DummyConsole""},
{ ""Name"": ""DummyWithLevelSwitch""},
]
}
}")]
[InlineData("simplified syntax",
@"{
""Serilog"": {
""Using"": [""TestDummies""],
""WriteTo"": [""DummyConsole"", ""DummyWithLevelSwitch"" ]
}
}")]
public void ParameterlessSinksAreConfigured(string syntax, string json)
{
var log = ConfigFromJson(json)
.CreateLogger();

DummyConsoleSink.Emitted.Clear();
DummyWithLevelSwitchSink.Emitted.Clear();

log.Write(Some.InformationEvent());

Assert.Equal(1, DummyConsoleSink.Emitted.Count);
Assert.Equal(1, DummyWithLevelSwitchSink.Emitted.Count);
}

[Fact]
public void SinksAreConfigured()
{
var json = @"{
""Serilog"": {
""Using"": [""TestDummies""],
""WriteTo"": [{
""Name"": ""DummyRollingFile"",
""Args"": {""pathFormat"" : ""C:\\""}
}]
}
}";

var log = ConfigFromJson(json)
.CreateLogger();

DummyRollingFileSink.Emitted.Clear();
DummyRollingFileAuditSink.Emitted.Clear();

log.Write(Some.InformationEvent());

Assert.Equal(1, DummyRollingFileSink.Emitted.Count);
Assert.Equal(0, DummyRollingFileAuditSink.Emitted.Count);
}

[Fact]
public void AuditSinksAreConfigured()
{
var json = @"{
""Serilog"": {
""Using"": [""TestDummies""],
""AuditTo"": [{
""Name"": ""DummyRollingFile"",
""Args"": {""pathFormat"" : ""C:\\""}
}]
}
}";

var log = ConfigFromJson(json)
.CreateLogger();

DummyRollingFileSink.Emitted.Clear();
DummyRollingFileAuditSink.Emitted.Clear();

log.Write(Some.InformationEvent());

Assert.Equal(0, DummyRollingFileSink.Emitted.Count);
Assert.Equal(1, DummyRollingFileAuditSink.Emitted.Count);
}

[Fact]
public void TestMinimumLevelOverrides()
{
var json = @"{
""Serilog"": {
""MinimumLevel"" : {
""Override"" : {
""System"" : ""Warning""
}
}
}
}";

LogEvent evt = null;

var log = ConfigFromJson(json)
.WriteTo.Sink(new DelegatingSink(e => evt = e))
.CreateLogger();

var systemLogger = log.ForContext<WeakReference>();
systemLogger.Write(Some.InformationEvent());

Assert.Null(evt);

systemLogger.Warning("Bad things");
Assert.NotNull(evt);

evt = null;
log.Write(Some.InformationEvent());
Assert.NotNull(evt);
}

[Fact]
public void SinksWithAbstractParamsAreConfiguredWithTypeName()
{
var json = @"{
""Serilog"": {
""Using"": [""TestDummies""],
""WriteTo"": [{
""Name"": ""DummyConsole"",
""Args"": {""theme"" : ""Serilog.Settings.Configuration.Tests.Support.CustomConsoleTheme, Serilog.Settings.Configuration.Tests""}
}]
}
}";

DummyConsoleSink.Theme = null;

ConfigFromJson(json)
.CreateLogger();

Assert.NotNull(DummyConsoleSink.Theme);
Assert.IsType<CustomConsoleTheme>(DummyConsoleSink.Theme);
}

[Fact]
public void SinksAreConfiguredWithStaticMember()
{
var json = @"{
""Serilog"": {
""Using"": [""TestDummies""],
""WriteTo"": [{
""Name"": ""DummyConsole"",
""Args"": {""theme"" : ""TestDummies.Console.Themes.ConsoleThemes::Theme1, TestDummies""}
}]
}
}";

DummyConsoleSink.Theme = null;

ConfigFromJson(json)
.CreateLogger();

Assert.Equal(ConsoleThemes.Theme1, DummyConsoleSink.Theme);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

<ItemGroup>
<ProjectReference Include="..\..\src\Serilog.Settings.Configuration\Serilog.Settings.Configuration.csproj" />
<ProjectReference Include="..\TestDummies\TestDummies.csproj" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using Microsoft.Extensions.Configuration;

namespace Serilog.Settings.Configuration.Tests.Support
{
public static class ConfigurationBuilderExtensions
{
public static IConfigurationBuilder AddJsonString(this IConfigurationBuilder builder, string json)
{
return builder.Add(new JsonStringConfigSource(json));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using TestDummies.Console.Themes;

namespace Serilog.Settings.Configuration.Tests.Support
{
class CustomConsoleTheme : ConsoleTheme
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using System;
using Serilog.Core;
using Serilog.Events;

namespace Serilog.Settings.Configuration.Tests.Support
{
public class DelegatingSink : ILogEventSink
{
readonly Action<LogEvent> _write;

public DelegatingSink(Action<LogEvent> write)
{
if (write == null) throw new ArgumentNullException(nameof(write));
_write = write;
}

public void Emit(LogEvent logEvent)
{
_write(logEvent);
}

public static LogEvent GetLogEvent(Action<ILogger> writeAction)
{
LogEvent result = null;
var l = new LoggerConfiguration()
.MinimumLevel.Verbose()
.WriteTo.Sink(new DelegatingSink(le => result = le))
.CreateLogger();

writeAction(l);
return result;
}
}
}
12 changes: 12 additions & 0 deletions test/Serilog.Settings.Configuration.Tests/Support/Extensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using Serilog.Events;

namespace Serilog.Settings.Configuration.Tests.Support
{
public static class Extensions
{
public static object LiteralValue(this LogEventPropertyValue @this)
{
return ((ScalarValue)@this).Value;
}
}
}
Loading