Skip to content
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

Log4JXmlEventLayout - Added support for configuration of Parameters #3389

Merged
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
21 changes: 13 additions & 8 deletions src/NLog/LayoutRenderers/Log4JXmlEventLayoutRenderer.cs
Expand Up @@ -370,15 +370,20 @@ private static void AppendException(LogEventInfo logEvent, XmlWriter xtw)

private void AppendParameters(LogEventInfo logEvent, XmlWriter xtw)
{
if (Parameters.Count > 0)
for (int i = 0; i < Parameters?.Count; ++i)
{
foreach (NLogViewerParameterInfo parameter in Parameters)
{
xtw.WriteStartElement("log4j", "data", dummyNamespace);
xtw.WriteAttributeSafeString("name", parameter.Name);
xtw.WriteAttributeSafeString("value", parameter.Layout.Render(logEvent));
xtw.WriteEndElement();
}
var parameter = Parameters[i];
if (string.IsNullOrEmpty(parameter?.Name))
continue;

var parameterValue = parameter.Layout?.Render(logEvent) ?? string.Empty;
if (!parameter.IncludeEmptyValue && string.IsNullOrEmpty(parameterValue))
continue;

xtw.WriteStartElement("log4j", "data", dummyNamespace);
xtw.WriteAttributeSafeString("name", parameter.Name);
xtw.WriteAttributeSafeString("value", parameterValue);
xtw.WriteEndElement();
}
}

Expand Down
1 change: 1 addition & 0 deletions src/NLog/Layouts/JsonAttribute.cs
Expand Up @@ -41,6 +41,7 @@ namespace NLog.Layouts
[NLogConfigurationItem]
[ThreadAgnostic]
[ThreadSafe]
[AppDomainFixedOutput]
public class JsonAttribute
{
/// <summary>
Expand Down
14 changes: 13 additions & 1 deletion src/NLog/Layouts/Log4JXmlEventLayout.cs
Expand Up @@ -33,9 +33,11 @@

namespace NLog.Layouts
{
using System.Collections.Generic;
using System.Text;
using NLog.Config;
using NLog.LayoutRenderers;
using NLog.Targets;

/// <summary>
/// A specialized layout that renders Log4j-compatible XML events.
Expand All @@ -55,12 +57,22 @@ public class Log4JXmlEventLayout : Layout, IIncludeContext
public Log4JXmlEventLayout()
{
Renderer = new Log4JXmlEventLayoutRenderer();
Parameters = new List<NLogViewerParameterInfo>();
Renderer.Parameters = Parameters;
}

/// <summary>
/// Gets the <see cref="Log4JXmlEventLayoutRenderer"/> instance that renders log events.
/// </summary>
public Log4JXmlEventLayoutRenderer Renderer { get; private set; }
public Log4JXmlEventLayoutRenderer Renderer { get; }

/// <summary>
/// Gets the collection of parameters. Each parameter contains a mapping
/// between NLog layout and a named parameter.
/// </summary>
/// <docgen category='Payload Options' order='10' />
[ArrayParameter(typeof(NLogViewerParameterInfo), "parameter")]
public IList<NLogViewerParameterInfo> Parameters { get => Renderer.Parameters; set => Renderer.Parameters = value; }

/// <summary>
/// Gets or sets a value indicating whether to include contents of the <see cref="MappedDiagnosticsContext"/> dictionary.
Expand Down
9 changes: 9 additions & 0 deletions src/NLog/Targets/NLogViewerParameterInfo.cs
Expand Up @@ -40,6 +40,9 @@ namespace NLog.Targets
/// Represents a parameter to a NLogViewer target.
/// </summary>
[NLogConfigurationItem]
[ThreadAgnostic]
[ThreadSafe]
[AppDomainFixedOutput]
public class NLogViewerParameterInfo
{
/// <summary>
Expand All @@ -62,5 +65,11 @@ public NLogViewerParameterInfo()
/// <docgen category='Parameter Options' order='10' />
[RequiredParameter]
public Layout Layout { get; set; }

/// <summary>
/// Gets or sets whether an attribute with empty value should be included in the output
/// </summary>
/// <docgen category='Parameter Options' order='100' />
public bool IncludeEmptyValue { get; set; } = true;
}
}
50 changes: 40 additions & 10 deletions tests/NLog.UnitTests/LayoutRenderers/Log4JXmlTests.cs
Expand Up @@ -31,19 +31,20 @@
// THE POSSIBILITY OF SUCH DAMAGE.
//

using System.Collections.Generic;
using NLog.Config;

namespace NLog.UnitTests.LayoutRenderers
{
using System.Threading;
using System.Diagnostics;
using System;
using System.Xml;
using System.Reflection;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using Xunit;
using System.Reflection;
using System.Threading;
using System.Xml;
using NLog.Config;
using NLog.Internal;
using NLog.Layouts;
using NLog.Targets;
using Xunit;

public class Log4JXmlTests : NLogTestBase
{
Expand All @@ -53,8 +54,8 @@ public void Log4JXmlTest()
LogManager.Configuration = XmlLoggingConfiguration.CreateFromXmlString(@"
<nlog throwExceptions='true'>
<targets>
<target name='debug' type='Debug' layout='${log4jxmlevent:includeCallSite=true:includeSourceInfo=true:includeNdlc=true:includeMdc=true:IncludeNdc=true:includeMdlc=true:IncludeAllProperties=true:ndcItemSeparator=\:\::includenlogdata=true:loggerName=${logger}}' />
</targets>
<target name='debug' type='Debug' layout='${log4jxmlevent:includeCallSite=true:includeSourceInfo=true:includeNdlc=true:includeMdc=true:IncludeNdc=true:includeMdlc=true:IncludeAllProperties=true:ndcItemSeparator=\:\::includenlogdata=true:loggerName=${logger}}' />
</targets>
<rules>
<logger name='*' minlevel='Debug' writeTo='debug' />
</rules>
Expand Down Expand Up @@ -235,6 +236,35 @@ public void Log4JXmlTest()
}
}

[Fact]
void Log4JXmlEventLayoutParameterTest()
{
var log4jLayout = new Log4JXmlEventLayout()
{
Parameters =
{
new NLogViewerParameterInfo
{
Name = "mt",
Layout = "${message:raw=true}",
}
},
};
log4jLayout.Renderer.AppInfo = "MyApp";
var logEventInfo = new LogEventInfo
{
LoggerName = "MyLOgger",
TimeStamp = new DateTime(2010, 01, 01, 12, 34, 56, DateTimeKind.Utc),
Level = LogLevel.Info,
Message = "hello, {0}",
Parameters = new[] { "world" },
};

var threadid = Environment.CurrentManagedThreadId;
var machinename = Environment.MachineName;
Assert.Equal($"<log4j:event logger=\"MyLOgger\" level=\"INFO\" timestamp=\"1262349296000\" thread=\"{threadid}\"><log4j:message>hello, world</log4j:message><log4j:properties><log4j:data name=\"mt\" value=\"hello, {{0}}\" /><log4j:data name=\"log4japp\" value=\"MyApp\" /><log4j:data name=\"log4jmachinename\" value=\"{machinename}\" /></log4j:properties></log4j:event>", log4jLayout.Render(logEventInfo));
}

[Fact]
void BadXmlValueTest()
{
Expand Down