Skip to content

Commit

Permalink
Merge pull request serilog#728 from adamchester/refl-not-scalar
Browse files Browse the repository at this point in the history
Allow destructuring policies to transform reflection types
  • Loading branch information
nblumhardt committed May 2, 2016
2 parents 0d2dac5 + 4869b03 commit 928dab4
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 7 deletions.
6 changes: 3 additions & 3 deletions src/Serilog/Parameters/PropertyValueConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,13 @@ public PropertyValueConverter(int maximumDestructuringDepth, IEnumerable<Type> a
new NullableScalarConversionPolicy(),
new EnumScalarConversionPolicy(),
new ByteArrayScalarConversionPolicy(),
new ReflectionTypesScalarConversionPolicy()
};

_destructuringPolicies = additionalDestructuringPolicies
.Concat(new []
.Concat(new IDestructuringPolicy []
{
new DelegateDestructuringPolicy()
new DelegateDestructuringPolicy(),
new ReflectionTypesScalarDestructuringPolicy()
})
.ToArray();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2013-2015 Serilog Contributors
// 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.
Expand All @@ -19,9 +19,9 @@

namespace Serilog.Policies
{
class ReflectionTypesScalarConversionPolicy : IScalarConversionPolicy
class ReflectionTypesScalarDestructuringPolicy : IDestructuringPolicy
{
public bool TryConvertToScalar(object value, ILogEventPropertyValueFactory propertyValueFactory, out ScalarValue result)
public bool TryDestructure(object value, ILogEventPropertyValueFactory propertyValueFactory, out LogEventPropertyValue result)
{
// These types and their subclasses are property-laden and deep;
// most sinks will convert them to strings.
Expand Down
71 changes: 71 additions & 0 deletions test/Serilog.Tests/LoggerConfigurationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Xunit;
using Serilog.Core;
using Serilog.Core.Filters;
Expand Down Expand Up @@ -109,6 +110,76 @@ public void SpecifyingThatATypeIsScalarCausesItToBeLoggedAsScalarEvenWhenDestruc
Assert.IsType<ScalarValue>(prop);
}

[Fact]
public void DestructuringSystemTypeGivesScalarByDefault()
{
var events = new List<LogEvent>();
var sink = new DelegatingSink(events.Add);

var logger = new LoggerConfiguration()
.WriteTo.Sink(sink)
.CreateLogger();

var thisType = this.GetType();
logger.Information("{@thisType}", thisType);

var ev = events.Single();
var prop = ev.Properties["thisType"];
var sv = Assert.IsAssignableFrom<ScalarValue>(prop);
Assert.Equal(thisType, sv.LiteralValue());
}

class ProjectedDestructuringPolicy : IDestructuringPolicy
{
readonly Func<Type, bool> _canApply;
readonly Func<object, object> _projection;

public ProjectedDestructuringPolicy(Func<Type, bool> canApply, Func<object, object> projection)
{
if (canApply == null) throw new ArgumentNullException(nameof(canApply));
if (projection == null) throw new ArgumentNullException(nameof(projection));
_canApply = canApply;
_projection = projection;
}

public bool TryDestructure(object value, ILogEventPropertyValueFactory propertyValueFactory, out LogEventPropertyValue result)
{
if (value == null) throw new ArgumentNullException(nameof(value));

if (!_canApply(value.GetType()))
{
result = null;
return false;
}

var projected = _projection(value);
result = propertyValueFactory.CreatePropertyValue(projected, true);
return true;
}
}

[Fact]
public void DestructuringIsPossibleForSystemTypeDerivedProperties()
{
var events = new List<LogEvent>();
var sink = new DelegatingSink(events.Add);

var logger = new LoggerConfiguration()
.Destructure.With(new ProjectedDestructuringPolicy(
canApply: t => typeof(Type).GetTypeInfo().IsAssignableFrom(t.GetTypeInfo()),
projection: o => ((Type)o).AssemblyQualifiedName))
.WriteTo.Sink(sink)
.CreateLogger();

var thisType = this.GetType();
logger.Information("{@thisType}", thisType);

var ev = events.Single();
var prop = ev.Properties["thisType"];
var sv = Assert.IsAssignableFrom<ScalarValue>(prop);
Assert.Equal(thisType.AssemblyQualifiedName, sv.LiteralValue());
}

[Fact]
public void TransformationsAreAppliedToEventProperties()
{
Expand Down
10 changes: 9 additions & 1 deletion test/Serilog.Tests/Parameters/PropertyValueConverterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,15 @@ public void FailsGracefullyWhenGettersThrow()
public void SurvivesDestructuringASystemType()
{
var pv = _converter.CreatePropertyValue(typeof(string), Destructuring.Destructure);
Assert.Equal(typeof(string), pv.LiteralValue());
Assert.Equal(typeof(string), pv.LiteralValue());
}

[Fact]
public void SurvivesDestructuringMethodBase()
{
var theMethod = System.Reflection.MethodBase.GetCurrentMethod();
var pv = _converter.CreatePropertyValue(theMethod, Destructuring.Destructure);
Assert.Equal(theMethod, pv.LiteralValue());
}

public class BaseWithProps
Expand Down

0 comments on commit 928dab4

Please sign in to comment.