public void WhenManyFormattersDefinedThenItWillBeAppliedInOrder() { var options = new CustomPolicyOptions() .AddPolicy("add hello", (p, value) => p.Name == nameof(Test.Name) && value is string word && !string.IsNullOrWhiteSpace(word), value => $"Hello {value}!"); var events = new List <LogEvent>(); var logger = new LoggerConfiguration() .Destructure.With(new CustomRuleDestructuringPolicy(options)) .WriteTo.Sink(new DelegatingSink(events.Add)) .CreateLogger(); var sut = new Test { Name = "world" }; logger.Information("Hello {@Data}", sut); Assert.That(events.Count, Is.EqualTo(1)); var logEvent = events[0]; Assert.That(logEvent.Properties, Does.ContainKey("Data")); Assert.That(logEvent.Properties["Data"], Is.TypeOf <StructureValue>()); var logProperties = ((StructureValue)logEvent.Properties["Data"]).Properties; var nameProperty = logProperties.FirstOrDefault(p => p.Name == nameof(Test.Name)); Assert.That(nameProperty, Is.Not.Null); Assert.That(nameProperty !.Value.ToString(), Is.EqualTo("\"Hello world!\"")); }
public void WhenFilteredByOneOfExcludeCallbackThenItWillNotBeIncluded() { var options = new CustomPolicyOptions() .AddPolicy("exclude non writable", isExcluded: p => !p.CanWrite) .AddPolicy("exclude field", isExcluded: p => p.GetMethod == null); var events = new List <LogEvent>(); var logger = new LoggerConfiguration() .Destructure.With(new CustomRuleDestructuringPolicy(options)) .WriteTo.Sink(new DelegatingSink(events.Add)) .CreateLogger(); var sut = new Test { Name = "my name" }; logger.Information("Hello {@Data}", sut); Assert.That(events.Count, Is.EqualTo(1)); var logEvent = events[0]; Assert.That(logEvent.Properties, Does.ContainKey("Data")); Assert.That(logEvent.Properties["Data"], Is.TypeOf <StructureValue>()); var logProperties = ((StructureValue)logEvent.Properties["Data"]).Properties; Assert.That(logProperties.Select(p => p.Name), Is.Not.SupersetOf(new[] { nameof(Test.ReadOnly), nameof(Test.Default) }).And.Contain(nameof(Test.Name))); var property = logProperties.First(p => p.Name == nameof(Test.Name)); Assert.That(property.Value.ToString(), Is.EqualTo($"\"{sut.Name}\"")); }
public void WhenApplyingCustomFormatThenItWillBuildResultFromFactory() { var options = new CustomPolicyOptions() .AddPolicy("add hello", IsStringNamePropertyName, value => $"Hello {value}!") .AddPolicy("add welcome", IsStringNamePropertyName, value => $"{value} Welcome home."); var events = new List <LogEvent>(); var logger = new LoggerConfiguration() .Destructure.With(new CustomRuleDestructuringPolicy(options)) .WriteTo.Sink(new DelegatingSink(events.Add)) .CreateLogger(); var sut = new Test { Name = "world" }; logger.Information("Hello {@Data}", sut); Assert.That(events.Count, Is.EqualTo(1)); var logEvent = events[0]; Assert.That(logEvent.Properties, Does.ContainKey("Data")); Assert.That(logEvent.Properties["Data"], Is.TypeOf <StructureValue>()); var logProperties = ((StructureValue)logEvent.Properties["Data"]).Properties; var nameProperty = logProperties.FirstOrDefault(p => p.Name == nameof(Test.Name)); Assert.That(nameProperty, Is.Not.Null); Assert.That(nameProperty !.Value.ToString(), Is.EqualTo("\"Hello world! Welcome home.\"")); }
public void WhenMaskedByDefaultWordThenItWillBeIncluded() { var options = new CustomPolicyOptions().Masking(new[] { nameof(Test.Name) }); var result = options.GetProperties(typeof(Test).GetTypeInfo()); Assert.That(result.Select(p => p.Name), Does.Contain(nameof(Test.Name))); }
/// <summary> /// Build custom rule for destructuring /// </summary> /// <param name="builder"></param> /// <param name="configure"></param> /// <returns></returns> public static LoggerConfiguration ByCustomRules(this LoggerDestructuringConfiguration builder, Action <CustomPolicyOptions> configure) { var rules = new CustomPolicyOptions(); configure(rules); return(builder.With(new CustomRuleDestructuringPolicy(rules))); }
/// <summary> /// Exclude certain property names /// </summary> /// <param name="policy"></param> /// <param name="propertyNames">Property names to be excluded</param> /// <returns></returns> public static CustomPolicyOptions Excluding(this CustomPolicyOptions policy, params string[] propertyNames) { if (propertyNames.Length == 0) { throw new ArgumentException("Please specify at least 1 property to exclude", nameof(propertyNames)); } return(policy.AddPolicy("excluding", isExcluded: p => propertyNames.Contains(p.Name))); }
public void WhenNotListedInExcludedListThenItWillBeIncluded() { var options = new CustomPolicyOptions().Excluding(nameof(Test.Name)); var result = options.GetProperties(typeof(Test).GetTypeInfo()); Assert.That(result.Select(p => p.Name), Is.EquivalentTo(new[] { nameof(Test.Generated), nameof(Test.Static) })); }
public void WhenApplyingRecordPolicyThenAllPublicPropertiesWillBeIncluded() { var options = new CustomPolicyOptions().ByProperRecordProcessing(); var result = options.GetProperties(typeof(TestRecord).GetTypeInfo()); Assert.That(result.Select(p => p.Name), Is.EquivalentTo(new[] { nameof(TestRecord.Id), nameof(TestRecord.Name) })); }
public void WhenIgnoringStaticPropertyThenNonStaticPropertyWillBeIncluded() { var options = new CustomPolicyOptions().IgnoreStatic(); var result = options.GetProperties(typeof(Test).GetTypeInfo()); Assert.That(result.Select(p => p.Name), Is.EquivalentTo(new[] { nameof(Test.Generated), nameof(Test.Name) })); }
public void WhenIgnoringGeneratedByCompilerThenNonDecoratedByCompilerGeneratedAttributeWillBeIncluded() { var options = new CustomPolicyOptions().IgnoreGeneratedByCompiler(); var result = options.GetProperties(typeof(Test).GetTypeInfo()); Assert.That(result.Select(p => p.Name), Is.EquivalentTo(new[] { nameof(Test.Static), nameof(Test.Name) })); }
public void WhenIgnoringStaticPropertyThenItWillNotBeIncluded() { string message = string.Empty; var options = new CustomPolicyOptions().IgnoreStatic(); var result = options.GetProperties(typeof(Test).GetTypeInfo(), (rule, p) => message = $"Property {p.Name} is excluded by {rule.Name} rule"); Assert.That(result.Select(p => p.Name), Does.Not.Contain(nameof(Test.Static))); Assert.That(message, Is.EqualTo($"Property {nameof(Test.Static)} is excluded by ignore static rule")); }
public void WhenIgnoringGeneratedByCompilerThenItWillExcludeAllPropertiesDecoratedByCompilerGeneratedAttribute() { string message = string.Empty; var options = new CustomPolicyOptions().IgnoreGeneratedByCompiler(); var result = options.GetProperties(typeof(Test).GetTypeInfo(), (rule, p) => message = $"Property {p.Name} is excluded by {rule.Name} rule"); Assert.That(result.Select(p => p.Name), Does.Not.Contain(nameof(Test.Generated))); Assert.That(message, Is.EqualTo($"Property {nameof(Test.Generated)} is excluded by ignore generated by compiler rule")); }
public void WhenApplyingRecordPolicyThenItWillNotIncludeEqualityContract() { string message = string.Empty; var options = new CustomPolicyOptions().ByProperRecordProcessing(); var result = options.GetProperties(new TestRecord(1, "hello").GetType().GetTypeInfo(), (rule, p) => message = $"Property {p.Name} is excluded by {rule.Name} rule"); Assert.That(result.Select(p => p.Name), Does.Not.Contain("EqualityContract")); Assert.That(message, Is.EqualTo("Property EqualityContract is excluded by record processing rule")); }
/// <summary> /// Masking certain properties with certain mask /// </summary> /// <param name="policy"></param> /// <param name="masking">Replacement word</param> /// <param name="propertyNames">Property names to be masked</param> /// <returns></returns> public static CustomPolicyOptions Masking(this CustomPolicyOptions policy, string masking, string[] propertyNames) { if (string.IsNullOrWhiteSpace(masking)) { throw new ArgumentException(nameof(masking)); } if (propertyNames.Length == 0) { throw new ArgumentException("Please specify at least 1 property to mask", nameof(propertyNames)); } return(policy.AddPolicy("masking", (p, _) => propertyNames.Contains(p.Name), _ => masking)); }
public void WhenDestructuringNestedClassThenItWillBePopulatedAccordingly() { var options = new CustomPolicyOptions().AddPolicy("add hello", IsStringNamePropertyName, value => $"Hello {value}!"); var events = new List <LogEvent>(); var logger = new LoggerConfiguration() .Destructure.With(new CustomRuleDestructuringPolicy(options)) .WriteTo.Sink(new DelegatingSink(events.Add)) .CreateLogger(); var sut = new Nested { HasInner = true, Child = { Name = "me" } }; logger.Information("Hello {@Data}", sut); Assert.That(events.Count, Is.EqualTo(1)); var logEvent = events[0]; Assert.That(logEvent.Properties, Does.ContainKey("Data")); Assert.That(logEvent.Properties["Data"], Is.TypeOf <StructureValue>()); var logProperties = ((StructureValue)logEvent.Properties["Data"]).Properties; AssertLogProperty(logProperties, nameof(Nested.HasInner), true.ToString()); var childProperty = logProperties.FirstOrDefault(p => p.Name == nameof(Nested.Child)); Assert.That(childProperty, Is.Not.Null); Assert.That(childProperty !.Value, Is.TypeOf <StructureValue>()); var properties = ((StructureValue)childProperty.Value).Properties; AssertLogProperty(properties, nameof(Test.ReadOnly), "\"never changed\""); AssertLogProperty(properties, nameof(Test.Default), "\"hello\""); AssertLogProperty(properties, nameof(Test.Name), "\"Hello me!\""); }
/// <summary> /// Fix destructuring for record type /// </summary> /// <param name="builder"></param> /// <returns></returns> public static LoggerConfiguration ByCustomRules(this LoggerDestructuringConfiguration builder) { var rules = new CustomPolicyOptions().ByProperRecordProcessing(); return(builder.With(new CustomRuleDestructuringPolicy(rules))); }
/// <summary> /// Hide generated property for record type /// </summary> /// <param name="policy"></param> /// <returns></returns> public static CustomPolicyOptions ByProperRecordProcessing(this CustomPolicyOptions policy) => policy.AddPolicy("record processing", isExcluded: p => p.Name == "EqualityContract");
/// <summary> /// Ignore static property /// </summary> /// <param name="policy"></param> /// <returns></returns> public static CustomPolicyOptions IgnoreStatic(this CustomPolicyOptions policy) => policy.AddPolicy("ignore static", isExcluded: p => p.GetMethod.IsStatic);
/// <summary> /// Ignore compiler generated property /// </summary> /// <param name="policy"></param> /// <returns></returns> public static CustomPolicyOptions IgnoreGeneratedByCompiler(this CustomPolicyOptions policy) => policy.AddPolicy("ignore generated by compiler", isExcluded: p => p.CustomAttributes.Any(a => a.AttributeType == typeof(CompilerGeneratedAttribute)));
/// <summary> /// Masking certain properties with 5 asterisks /// </summary> /// <param name="policy"></param> /// <param name="propertyNames">Property names to be masked</param> /// <returns></returns> public static CustomPolicyOptions Masking(this CustomPolicyOptions policy, string[] propertyNames) => policy.Masking("*****", propertyNames);