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

${when}, support for RawValue on Inner and Else (backport) #3394

Merged
merged 1 commit into from May 13, 2019
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
36 changes: 32 additions & 4 deletions src/NLog/LayoutRenderers/Wrappers/WhenLayoutRendererWrapper.cs
Expand Up @@ -38,6 +38,7 @@ namespace NLog.LayoutRenderers.Wrappers
using NLog.Conditions;
using NLog.Config;
using NLog.Layouts;
using NLog.Internal;

/// <summary>
/// Only outputs the inner layout when the specified condition has been met.
Expand All @@ -46,7 +47,7 @@ namespace NLog.LayoutRenderers.Wrappers
[AmbientProperty("When")]
[ThreadAgnostic]
[ThreadSafe]
public sealed class WhenLayoutRendererWrapper : WrapperLayoutRendererBuilderBase
public sealed class WhenLayoutRendererWrapper : WrapperLayoutRendererBuilderBase, IRawValue
{
/// <summary>
/// Gets or sets the condition that must be met for the <see cref="WrapperLayoutRendererBase.Inner"/> layout to be printed.
Expand All @@ -67,13 +68,13 @@ protected override void Append(StringBuilder builder, LogEventInfo logEvent)
int orgLength = builder.Length;
try
{
if (When == null || true.Equals(When.Evaluate(logEvent)))
if (ShouldRenderInner(logEvent))
{
Inner?.RenderAppendBuilder(logEvent, builder);
}
else if (Else != null)
else
{
Else.RenderAppendBuilder(logEvent, builder);
Else?.RenderAppendBuilder(logEvent, builder);
}
}
catch
Expand All @@ -83,10 +84,37 @@ protected override void Append(StringBuilder builder, LogEventInfo logEvent)
}
}

private bool ShouldRenderInner(LogEventInfo logEvent)
{
return When == null || true.Equals(When.Evaluate(logEvent));
}

/// <inheritdoc/>
[Obsolete("Inherit from WrapperLayoutRendererBase and override RenderInnerAndTransform() instead. Marked obsolete in NLog 4.6")]
protected override void TransformFormattedMesssage(StringBuilder target)
{
}

/// <inheritdoc />
public bool TryGetRawValue(LogEventInfo logEvent, out object value)
{
if (ShouldRenderInner(logEvent))
{
return TryGetRawValueFromLayout(logEvent, Inner, out value);
}

return TryGetRawValueFromLayout(logEvent, Else, out value);
}

private static bool TryGetRawValueFromLayout(LogEventInfo logEvent, Layout layout, out object value)
{
if (layout == null)
{
value = null;
return false;
}

return layout.TryGetRawValue(logEvent, out value);
}
}
}
45 changes: 45 additions & 0 deletions tests/NLog.UnitTests/LayoutRenderers/Wrappers/WhenTests.cs
Expand Up @@ -31,6 +31,7 @@
// THE POSSIBILITY OF SUCH DAMAGE.
//

using System;
using NLog.Config;

namespace NLog.UnitTests.LayoutRenderers.Wrappers
Expand Down Expand Up @@ -203,5 +204,49 @@ private static void WhenNumericAndPropertyConditionTest_inner(SimpleLayout l, ob
le.Properties["Elapsed"] = time;
Assert.Equal(fast ? "Fast" : "Slow", l.Render(le));
}

[Theory]
[InlineData("logger", "DBNullValue", true)]
[InlineData("logger1", null, false)]
public void WhenDbNullRawValueShouldWork(string loggername, object expectedValue, bool expectedSuccess)
{
expectedValue = OptionalConvert(expectedValue);

//else cannot be invoked ambiently. First param is inner
SimpleLayout l = @"${when:${db-null}:when=logger=='logger':else=better}";

var le = LogEventInfo.Create(LogLevel.Info, loggername, "message");
var success = l.TryGetRawValue(le, out var result);

Assert.Equal(expectedValue, result);
Assert.Equal(expectedSuccess, success);
}
[Theory]
[InlineData("logger1", "DBNullValue", true)]
[InlineData("logger", null, false)]
public void WhenDbNullRawValueShouldWorkElse(string loggername, object expectedValue, bool expectedSuccess)
{

expectedValue = OptionalConvert(expectedValue);

//else cannot be invoked ambiently. First param is inner
SimpleLayout l = @"${when:something:when=logger=='logger':else=${db-null}}";

var le = LogEventInfo.Create(LogLevel.Info, loggername, "message");
var success = l.TryGetRawValue(le, out var result);

Assert.Equal(expectedValue, result);
Assert.Equal(expectedSuccess, success);
}

private static object OptionalConvert(object expectedValue)
{
if (expectedValue is string s && s == "DBNullValue")
{
expectedValue = DBNull.Value;
}

return expectedValue;
}
}
}