Skip to content

Commit

Permalink
Log4JXmlEventLayout - Added support for configuration of Parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
snakefoot committed May 12, 2019
1 parent 3d07bd9 commit 36e7ee8
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 19 deletions.
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

0 comments on commit 36e7ee8

Please sign in to comment.