docs: document default values for Filters properties in XML docs

Continues the work started for #5917 (already covered Targets, Layouts,
LayoutRenderers and Target Wrappers), extending the same pattern to the
NLog.Filters namespace so default values show up in IntelliSense and the
generated API docs.

Adds a regression test that scans all settable NLog.Filters properties
against the generated XML documentation file and fails if any of them is
missing a documented default value.
This commit is contained in:
dualfroz committed 2026-08-28 13:24:33 +02:00
1 parent 2154098b97
commit 44df43fabd
9 files changed
+114

No files matched your search

+1
View File
@@ -50,6 +50,7 @@ namespace NLog.Filters
/// <summary>
/// Gets or sets the condition expression.
/// </summary>
/// <remarks><b>[Required]</b> Default: <see langword="null"/></remarks>
/// <docgen category='Filtering Options' order='10' />
public ConditionExpression Condition { get; set; } = ConditionLiteralExpression.Null;
+1
View File
@@ -53,6 +53,7 @@ namespace NLog.Filters
/// <summary>
/// Gets or sets the action to be taken when filter matches.
/// </summary>
/// <remarks>Default: <see cref="FilterResult.Neutral"/></remarks>
/// <docgen category='Filtering Options' order='10' />
public FilterResult Action { get; set; }
+1
View File
@@ -51,6 +51,7 @@ namespace NLog.Filters
/// Gets or sets the layout to be used to filter log messages.
/// </summary>
/// <value>The layout.</value>
/// <remarks><b>[Required]</b> Default: <see cref="Layout.Empty"/></remarks>
/// <docgen category='Filtering Options' order='10' />
public Layout Layout { get; set; } = Layout.Empty;
}
+2
View File
@@ -45,12 +45,14 @@ namespace NLog.Filters
/// <summary>
/// Gets or sets a value indicating whether to ignore case when comparing strings.
/// </summary>
/// <remarks>Default: <see langword="false"/></remarks>
/// <docgen category='Filtering Options' order='10' />
public bool IgnoreCase { get; set; }
/// <summary>
/// Gets or sets the substring to be matched.
/// </summary>
/// <remarks><b>[Required]</b> Default: <see cref="string.Empty"/></remarks>
/// <docgen category='Filtering Options' order='10' />
public string Substring { get; set; } = string.Empty;
+2
View File
@@ -45,12 +45,14 @@ namespace NLog.Filters
/// <summary>
/// Gets or sets a value indicating whether to ignore case when comparing strings.
/// </summary>
/// <remarks>Default: <see langword="false"/></remarks>
/// <docgen category='Filtering Options' order='10' />
public bool IgnoreCase { get; set; }
/// <summary>
/// Gets or sets a string to compare the layout to.
/// </summary>
/// <remarks>Default: <see cref="string.Empty"/></remarks>
/// <docgen category='Filtering Options' order='10' />
public string CompareTo { get; set; } = string.Empty;
@@ -45,12 +45,14 @@ namespace NLog.Filters
/// <summary>
/// Gets or sets the substring to be matched.
/// </summary>
/// <remarks><b>[Required]</b> Default: <see cref="string.Empty"/></remarks>
/// <docgen category='Filtering Options' order='10' />
public string Substring { get; set; } = string.Empty;
/// <summary>
/// Gets or sets a value indicating whether to ignore case when comparing strings.
/// </summary>
/// <remarks>Default: <see langword="false"/></remarks>
/// <docgen category='Filtering Options' order='10' />
public bool IgnoreCase { get; set; }
+2
View File
@@ -52,12 +52,14 @@ namespace NLog.Filters
/// <summary>
/// Gets or sets a string to compare the layout to.
/// </summary>
/// <remarks>Default: <see cref="string.Empty"/></remarks>
/// <docgen category='Filtering Options' order='10' />
public string CompareTo { get; set; } = string.Empty;
/// <summary>
/// Gets or sets a value indicating whether to ignore case when comparing strings.
/// </summary>
/// <remarks>Default: <see langword="false"/></remarks>
/// <docgen category='Filtering Options' order='10' />
public bool IgnoreCase { get; set; }
+8
View File
@@ -54,12 +54,14 @@ namespace NLog.Filters
/// <summary>
/// How long before a filter expires, and logging is accepted again
/// </summary>
/// <remarks>Default: <c>10</c></remarks>
/// <docgen category='Filtering Options' order='10' />
public int TimeoutSeconds { get; set; } = 10;
/// <summary>
/// Max length of filter values, will truncate if above limit
/// </summary>
/// <remarks>Default: <c>1000</c></remarks>
/// <docgen category='Filtering Options' order='10' />
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.
/// </summary>
/// <remarks>Default: <see langword="false"/></remarks>
/// <docgen category='Filtering Options' order='10' />
public bool IncludeFirst { get; set; }
/// <summary>
/// Max number of unique filter values to expect simultaneously
/// </summary>
/// <remarks>Default: <c>50000</c></remarks>
/// <docgen category='Filtering Options' order='100' />
public int MaxFilterCacheSize { get; set; } = 50000;
/// <summary>
/// Default number of unique filter values to expect, will automatically increase if needed
/// </summary>
/// <remarks>Default: <c>1000</c></remarks>
/// <docgen category='Filtering Options' order='100' />
public int DefaultFilterCacheSize { get; set; } = 1000;
/// <summary>
/// Insert FilterCount value into <see cref="LogEventInfo.Properties"/> when an event is no longer filtered
/// </summary>
/// <remarks>Default: <see cref="string.Empty"/></remarks>
/// <docgen category='Filtering Options' order='10' />
public string FilterCountPropertyName { get; set; } = string.Empty;
/// <summary>
/// Append FilterCount to the <see cref="LogEventInfo.Message"/> when an event is no longer filtered
/// </summary>
/// <remarks>Default: <see cref="string.Empty"/></remarks>
/// <docgen category='Filtering Options' order='10' />
public string FilterCountMessageAppendFormat { get; set; } = string.Empty;
@@ -106,6 +113,7 @@ namespace NLog.Filters
/// <summary>
/// Default buffer size for the internal buffers
/// </summary>
/// <remarks>Default: <c>1000</c></remarks>
/// <docgen category='Filtering Options' order='100' />
public int OptimizeBufferDefaultLength { get; set; } = 1000;
@@ -0,0 +1,95 @@
//
// Copyright (c) 2004-2024 Jaroslaw Kowalski <jaak@jkowalski.net>, 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;
/// <summary>
/// Verifies that every settable property under the <see cref="NLog.Filters"/> 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
/// </summary>
public class FilterDefaultValueDocsTests : NLogTestBase
{
// Properties that intentionally do not document a default value.
private static readonly HashSet<string> ExcludedMembers = new HashSet<string>
{
// 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<string>();
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<ObsoleteAttribute>() != 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);
}
}
}