diff --git a/src/NLog/Filters/ConditionBasedFilter.cs b/src/NLog/Filters/ConditionBasedFilter.cs index 1a04215..35eb3b9 100644 --- a/src/NLog/Filters/ConditionBasedFilter.cs +++ b/src/NLog/Filters/ConditionBasedFilter.cs @@ -50,6 +50,7 @@ namespace NLog.Filters /// /// Gets or sets the condition expression. /// + /// [Required] Default: /// public ConditionExpression Condition { get; set; } = ConditionLiteralExpression.Null; diff --git a/src/NLog/Filters/Filter.cs b/src/NLog/Filters/Filter.cs index 779f4b7..1a996f2 100644 --- a/src/NLog/Filters/Filter.cs +++ b/src/NLog/Filters/Filter.cs @@ -53,6 +53,7 @@ namespace NLog.Filters /// /// Gets or sets the action to be taken when filter matches. /// + /// Default: /// public FilterResult Action { get; set; } diff --git a/src/NLog/Filters/LayoutBasedFilter.cs b/src/NLog/Filters/LayoutBasedFilter.cs index bc047f5..a807788 100644 --- a/src/NLog/Filters/LayoutBasedFilter.cs +++ b/src/NLog/Filters/LayoutBasedFilter.cs @@ -51,6 +51,7 @@ namespace NLog.Filters /// Gets or sets the layout to be used to filter log messages. /// /// The layout. + /// [Required] Default: /// public Layout Layout { get; set; } = Layout.Empty; } diff --git a/src/NLog/Filters/WhenContainsFilter.cs b/src/NLog/Filters/WhenContainsFilter.cs index e5135c6..c014156 100644 --- a/src/NLog/Filters/WhenContainsFilter.cs +++ b/src/NLog/Filters/WhenContainsFilter.cs @@ -45,12 +45,14 @@ namespace NLog.Filters /// /// Gets or sets a value indicating whether to ignore case when comparing strings. /// + /// Default: /// public bool IgnoreCase { get; set; } /// /// Gets or sets the substring to be matched. /// + /// [Required] Default: /// public string Substring { get; set; } = string.Empty; diff --git a/src/NLog/Filters/WhenEqualFilter.cs b/src/NLog/Filters/WhenEqualFilter.cs index e8a66cb..45513a2 100644 --- a/src/NLog/Filters/WhenEqualFilter.cs +++ b/src/NLog/Filters/WhenEqualFilter.cs @@ -45,12 +45,14 @@ namespace NLog.Filters /// /// Gets or sets a value indicating whether to ignore case when comparing strings. /// + /// Default: /// public bool IgnoreCase { get; set; } /// /// Gets or sets a string to compare the layout to. /// + /// Default: /// public string CompareTo { get; set; } = string.Empty; diff --git a/src/NLog/Filters/WhenNotContainsFilter.cs b/src/NLog/Filters/WhenNotContainsFilter.cs index 53a4d54..52709f2 100644 --- a/src/NLog/Filters/WhenNotContainsFilter.cs +++ b/src/NLog/Filters/WhenNotContainsFilter.cs @@ -45,12 +45,14 @@ namespace NLog.Filters /// /// Gets or sets the substring to be matched. /// + /// [Required] Default: /// public string Substring { get; set; } = string.Empty; /// /// Gets or sets a value indicating whether to ignore case when comparing strings. /// + /// Default: /// public bool IgnoreCase { get; set; } diff --git a/src/NLog/Filters/WhenNotEqualFilter.cs b/src/NLog/Filters/WhenNotEqualFilter.cs index 3abd781..accd268 100644 --- a/src/NLog/Filters/WhenNotEqualFilter.cs +++ b/src/NLog/Filters/WhenNotEqualFilter.cs @@ -52,12 +52,14 @@ namespace NLog.Filters /// /// Gets or sets a string to compare the layout to. /// + /// Default: /// public string CompareTo { get; set; } = string.Empty; /// /// Gets or sets a value indicating whether to ignore case when comparing strings. /// + /// Default: /// public bool IgnoreCase { get; set; } diff --git a/src/NLog/Filters/WhenRepeatedFilter.cs b/src/NLog/Filters/WhenRepeatedFilter.cs index 3914c23..c27922f 100644 --- a/src/NLog/Filters/WhenRepeatedFilter.cs +++ b/src/NLog/Filters/WhenRepeatedFilter.cs @@ -54,12 +54,14 @@ namespace NLog.Filters /// /// How long before a filter expires, and logging is accepted again /// + /// Default: 10 /// public int TimeoutSeconds { get; set; } = 10; /// /// Max length of filter values, will truncate if above limit /// + /// Default: 1000 /// public int MaxLength { get; set; } = 1000; @@ -67,30 +69,35 @@ namespace NLog.Filters /// Applies the configured action to the initial logevent that starts the timeout period. /// Used to configure that it should ignore all events until timeout. /// + /// Default: /// public bool IncludeFirst { get; set; } /// /// Max number of unique filter values to expect simultaneously /// + /// Default: 50000 /// public int MaxFilterCacheSize { get; set; } = 50000; /// /// Default number of unique filter values to expect, will automatically increase if needed /// + /// Default: 1000 /// public int DefaultFilterCacheSize { get; set; } = 1000; /// /// Insert FilterCount value into when an event is no longer filtered /// + /// Default: /// public string FilterCountPropertyName { get; set; } = string.Empty; /// /// Append FilterCount to the when an event is no longer filtered /// + /// Default: /// public string FilterCountMessageAppendFormat { get; set; } = string.Empty; @@ -106,6 +113,7 @@ namespace NLog.Filters /// /// Default buffer size for the internal buffers /// + /// Default: 1000 /// public int OptimizeBufferDefaultLength { get; set; } = 1000; diff --git a/tests/NLog.UnitTests/Filters/FilterDefaultValueDocsTests.cs b/tests/NLog.UnitTests/Filters/FilterDefaultValueDocsTests.cs new file mode 100644 index 0000000..0e39774 --- /dev/null +++ b/tests/NLog.UnitTests/Filters/FilterDefaultValueDocsTests.cs @@ -0,0 +1,95 @@ +// +// Copyright (c) 2004-2024 Jaroslaw Kowalski , Kim Christensen, Julian Verdurmen +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * Neither the name of Jaroslaw Kowalski nor the names of its +// contributors may be used to endorse or promote products derived from this +// software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +// THE POSSIBILITY OF SUCH DAMAGE. +// + +namespace NLog.UnitTests.Filters +{ + using System; + using System.Collections.Generic; + using System.IO; + using System.Linq; + using System.Reflection; + using System.Xml.Linq; + using Xunit; + + /// + /// Verifies that every settable property under the namespace + /// documents its default value in the generated XML docs, so it shows up in IntelliSense + /// and the Sandcastle API docs. See https://github.com/NLog/NLog/issues/5917 + /// + public class FilterDefaultValueDocsTests : NLogTestBase + { + // Properties that intentionally do not document a default value. + private static readonly HashSet ExcludedMembers = new HashSet + { + // Obsolete since NLog 5.0, always returns true, no meaningful default to document. + "P:NLog.Filters.WhenRepeatedFilter.OptimizeBufferReuse", + }; + + [Fact] + public void SettablePropertiesDocumentDefaultValue() + { + var nlogAssembly = typeof(LogManager).Assembly; + var xmlDocPath = Path.ChangeExtension(nlogAssembly.Location, ".xml"); + Assert.True(File.Exists(xmlDocPath), $"Generated XML doc file not found at '{xmlDocPath}'. Build NLog.csproj with GenerateDocumentationFile enabled."); + + var documentedMembers = XDocument.Load(xmlDocPath) + .Descendants("member") + .ToDictionary(member => (string)member.Attribute("name"), member => member.ToString()); + + var propertiesMissingDefaultValueDocs = new List(); + + foreach (var type in nlogAssembly.GetTypes()) + { + if (type.Namespace != "NLog.Filters" || !type.IsPublic) + continue; + + foreach (var property in type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)) + { + if (!property.CanWrite || property.GetCustomAttribute() != null) + continue; + + var memberName = $"P:{type.FullName}.{property.Name}"; + if (ExcludedMembers.Contains(memberName)) + continue; + + if (!documentedMembers.TryGetValue(memberName, out var memberDocs) || !memberDocs.Contains("Default:")) + { + propertiesMissingDefaultValueDocs.Add(memberName); + } + } + } + + Assert.Empty(propertiesMissingDefaultValueDocs); + } + } +}