Skip to content

Commit

Permalink
LogManager.Setup() - Added support for RegisterNLogWeb + RegisterAspN…
Browse files Browse the repository at this point in the history
…etLayoutRenderer
  • Loading branch information
snakefoot committed Nov 30, 2021
1 parent d3f0657 commit 083ca69
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
layout="${longdate}|${event-properties:item=EventId_Id:whenEmpty=0}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}|url: ${aspnet-request-url}|action: ${aspnet-mvc-action}" />

<!--Console Target for hosting lifetime messages to improve Docker / Visual Studio startup detection -->
<target xsi:type="Console" name="lifetimeConsole" layout="${level:truncate=4:lowercase=true}\: ${logger}[0]${newline} ${message}${exception:format=tostring}" />
<target xsi:type="Console" name="lifetimeConsole" layout="${MicrosoftConsoleLayout}" />
</targets>

<!-- rules to map from logger name to target -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
layout="${longdate}|${event-properties:item=EventId_Id:whenEmpty=0}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}|url: ${aspnet-request-url}|action: ${aspnet-mvc-action}|${callsite}| body: ${aspnet-request-posted-body}" />

<!--Console Target for hosting lifetime messages to improve Docker / Visual Studio startup detection -->
<target xsi:type="Console" name="lifetimeConsole" layout="${level:truncate=4:lowercase=true}\: ${logger}[0]${newline} ${message}${exception:format=tostring}" />
<target xsi:type="Console" name="lifetimeConsole" layout="${MicrosoftConsoleLayout}" />
</targets>

<!-- rules to map from logger name to target -->
Expand Down
15 changes: 15 additions & 0 deletions src/NLog.Web.AspNetCore/Config/SetupExtensionsBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
using System.Reflection;
using NLog.Config;
using NLog.Web.DependencyInjection;
using NLog.Web.LayoutRenderers;
using HttpContextBase = Microsoft.AspNetCore.Http.HttpContext;

namespace NLog.Web
{
Expand All @@ -25,5 +27,18 @@ public static ISetupExtensionsBuilder RegisterNLogWeb(this ISetupExtensionsBuild

return setupBuilder.RegisterAssembly(typeof(NLogAspNetCoreOptions).GetTypeInfo().Assembly);
}


/// <summary>
/// Register a custom layout renderer using custom delegate-method <paramref name="layoutMethod" />
/// </summary>
/// <param name="setupBuilder">Fluent style</param>
/// <param name="name">Name of the layout renderer - without ${}.</param>
/// <param name="layoutMethod">Delegate method that returns layout renderer output.</param>
public static ISetupExtensionsBuilder RegisterAspNetLayoutRenderer(this ISetupExtensionsBuilder setupBuilder, string name, Func<LogEventInfo, HttpContextBase, LoggingConfiguration, object> layoutMethod)
{
AspNetLayoutRendererBase.Register(name, layoutMethod);
return setupBuilder;
}
}
}
23 changes: 23 additions & 0 deletions src/NLog.Web/Config/SetupBuilderExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NLog.Config;

namespace NLog.Web
{
/// <summary>
/// Extension methods to setup LogFactory options
/// </summary>
public static class SetupBuilderExtensions
{
/// <summary>
/// Register the NLog.Web LayoutRenderers before loading NLog config
/// </summary>
public static ISetupBuilder RegisterNLogWeb(this ISetupBuilder setupBuilder)
{
setupBuilder.SetupExtensions(e => e.RegisterNLogWeb());
return setupBuilder;
}
}
}
33 changes: 33 additions & 0 deletions src/NLog.Web/Config/SetupExtensionsBuilderExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System;
using System.Web;
using NLog.Config;
using NLog.Web.LayoutRenderers;

namespace NLog.Web
{
/// <summary>
/// Extension methods to setup NLog extensions, so they are known when loading NLog LoggingConfiguration
/// </summary>
public static class SetupExtensionsBuilderExtensions
{
/// <summary>
/// Register the NLog.Web LayoutRenderers
/// </summary>
public static ISetupExtensionsBuilder RegisterNLogWeb(this ISetupExtensionsBuilder setupBuilder)
{
return setupBuilder.RegisterAssembly(typeof(SetupExtensionsBuilderExtensions).Assembly);
}

/// <summary>
/// Register a custom layout renderer using custom delegate-method <paramref name="layoutMethod" />
/// </summary>
/// <param name="setupBuilder">Fluent style</param>
/// <param name="name">Name of the layout renderer - without ${}.</param>
/// <param name="layoutMethod">Delegate method that returns layout renderer output.</param>
public static ISetupExtensionsBuilder RegisterAspNetLayoutRenderer(this ISetupExtensionsBuilder setupBuilder, string name, Func<LogEventInfo, HttpContextBase, LoggingConfiguration, object> layoutMethod)
{
AspNetLayoutRendererBase.Register(name, layoutMethod);
return setupBuilder;
}
}
}
29 changes: 29 additions & 0 deletions tests/NLog.Web.Tests/AspNetTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System;
using NLog.Web.Targets.Wrappers;
using Xunit;

namespace NLog.Web.Tests
{
public sealed class AspNetTests
{
[Fact]
public void RegisterNLogWebTest()
{
// Act
var logFactory = new NLog.LogFactory().Setup().RegisterNLogWeb().LoadConfigurationFromXml(
@"<nlog throwConfigExceptions='true'>
<targets>
<target type='AspNetBufferingWrapper' name='hello'>
<target type='Memory' name='hello_wrapped' />
</target>
</targets>
<rules>
<logger name='*' writeTo='hello' />
</rules>
</nlog>").LogFactory;

// Assert
Assert.NotNull(logFactory?.Configuration?.FindTargetByName<AspNetBufferingTargetWrapper>("hello"));
}
}
}
23 changes: 16 additions & 7 deletions tests/Shared/RegisterCustomLayoutRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,28 @@ public void RegisterLayoutRendererTest()
#endif

// Act
AspNetLayoutRendererBase.Register("test-web",
var logFactory = new LogFactory().Setup().RegisterNLogWeb().SetupExtensions(ext =>
ext.RegisterAspNetLayoutRenderer("test-web",
(logEventInfo, httpContext, loggingConfiguration) =>
#if ASP_NET_CORE
httpContext.Connection.LocalPort);
httpContext.Connection.LocalPort)
#else
httpContext.Request.RawUrl);
httpContext.Request.RawUrl)
#endif
SimpleLayout l = "${test-web}";
(l.Renderers.FirstOrDefault() as NLogWebFuncLayoutRenderer).HttpContextAccessor = httpContextMock;
var result = l.Render(LogEventInfo.CreateNullEvent());
).LoadConfiguration(builder =>
{
builder.ForLogger().WriteTo(new NLog.Targets.MemoryTarget("hello") { Layout = "${test-web}" });
}).LogFactory;

var target = logFactory.Configuration.FindTargetByName<NLog.Targets.MemoryTarget>("hello");
var layoutRenderer = (target.Layout as NLog.Layouts.SimpleLayout).Renderers.FirstOrDefault() as NLogWebFuncLayoutRenderer;
layoutRenderer.HttpContextAccessor = httpContextMock;

logFactory.GetCurrentClassLogger().Info("Hello World");

// Assert
Assert.Equal("123", result);
Assert.Single(target.Logs);
Assert.Equal("123", target.Logs[0]);
}
}
}

0 comments on commit 083ca69

Please sign in to comment.