Skip to content

Commit

Permalink
Added several layout renders for NLog.Web (#784)
Browse files Browse the repository at this point in the history
* AspNetRequestClientCertificateLayoutRenderer - aspnet-request-client-certificate
* AspNetRequestIsWebSocketLayoutRenderer - aspnet-request-is-web-socket
* AspNetRequestLocalIpLayoutRenderer - aspnet-request-local-ip
* AspNetRequestLocalPortLayoutRenderer - aspnet-request-local-port
* AspNetRequestRemotePortLayoutRenderer - aspnet-request-remote-port
* AspNetRequestWebSocketRequestedProtocolsLayoutRenderer - aspnet-request-web-socket-requested-protocols
* AspNetResponseContentTypeLayoutRenderer - aspnet-response-contenttype
* AspNetResponseHeadersLayoutRenderer - aspnet-response-headers

Co-authored-by: Burak Akgerman <[email protected]>
  • Loading branch information
bakgerman and Burak Akgerman authored Jun 4, 2022
1 parent 1fec381 commit 0a06ef8
Show file tree
Hide file tree
Showing 17 changed files with 1,333 additions and 0 deletions.
63 changes: 63 additions & 0 deletions src/Shared/LayoutRenderers/AspNetLayoutMultiValueRendererBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,69 @@ private void SerializePairsFlat(IEnumerable<KeyValuePair<string, string>> pairs,
}
}

/// <summary>
/// Serialize multiple values
/// </summary>
/// <param name="values">The values.</param>
/// <param name="builder">Add to this builder.</param>
/// <param name="logEvent">Log event for rendering separators.</param>
protected void SerializeValues(IEnumerable<string> values, StringBuilder builder, LogEventInfo logEvent)
{
switch (OutputFormat)
{
case AspNetRequestLayoutOutputFormat.Flat:
SerializeValuesFlat(values, builder, logEvent);
break;
case AspNetRequestLayoutOutputFormat.JsonArray:
case AspNetRequestLayoutOutputFormat.JsonDictionary:
SerializeValuesJson(values, builder);
break;
}
}

private static void SerializeValuesJson(IEnumerable<string> values, StringBuilder builder)
{
var firstItem = true;
foreach (var item in values)
{
if (firstItem)
{
builder.Append('[');
}
else
{
builder.Append(',');
}
SerializeValueJson(builder, item);
firstItem = false;
}
if (!firstItem)
{
builder.Append(']');
}
}

private static void SerializeValueJson(StringBuilder builder, string value)
{
// Quoted value
AppendQuoted(builder, value);
}

private void SerializeValuesFlat(IEnumerable<string> values, StringBuilder builder, LogEventInfo logEvent)
{
var itemSeparator = GetRenderedItemSeparator(logEvent);
var firstItem = true;
foreach (var value in values)
{
if (!firstItem)
{
builder.Append(itemSeparator);
}
firstItem = false;
builder.Append(value);
}
}

/// <summary>
/// Get the rendered <see cref="ItemSeparator" />
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using System.Text;
using NLog.LayoutRenderers;
#if ASP_NET_CORE
using Microsoft.AspNetCore.Http;
#else
using System.Security.Cryptography.X509Certificates;
using System.Web;
#endif

namespace NLog.Web.LayoutRenderers
{
/// <summary>
/// ASP.NET Client Certificate of the Connection
/// </summary>
/// <remarks>
/// ${aspnet-request-client certificate}
/// </remarks>
[LayoutRenderer("aspnet-request-client-certificate")]
public class AspNetRequestClientCertificateLayoutRenderer : AspNetLayoutRendererBase
{
/// <summary>
/// Render Remote Port
/// </summary>
protected override void DoAppend(StringBuilder builder, LogEventInfo logEvent)
{
var httpContext = HttpContextAccessor.HttpContext;
#if ASP_NET_CORE
var connection = httpContext.Connection;
if (connection == null)
{
return;
}
builder.Append(connection.ClientCertificate);
#else
var certificate = httpContext.Request.ClientCertificate;
if (certificate == null)
{
return;
}
// Convert to an X509Certificate2, which does have the proper overridden ToString() method.
// HttpClientCertificate class only use object.ToString() which is useless.
builder.Append(new X509Certificate2(certificate.Certificate));
#endif
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using System.Text;
using NLog.LayoutRenderers;

namespace NLog.Web.LayoutRenderers
{
/// <summary>
/// ASP.NET Is Request Web Socket
/// </summary>
/// <remarks>
/// ${aspnet-request-is-web-socket}
/// </remarks>
[LayoutRenderer("aspnet-request-is-web-socket")]
public class AspNetRequestIsWebSocketLayoutRenderer : AspNetLayoutRendererBase
{
/// <summary>
/// Renders the specified ASP.NET Core HttpContext.WebSocketManager.IsWebSocketRequest variable and appends it to the specified <see cref="StringBuilder" />.
/// </summary>
/// <param name="builder">The <see cref="StringBuilder" /> to append the rendered data to.</param>
/// <param name="logEvent">Logging event.</param>
protected override void DoAppend(StringBuilder builder, LogEventInfo logEvent)
{
// Not available on .NET 3.5
#if ASP_NET_CORE
var websockets = HttpContextAccessor.HttpContext?.WebSockets;
if (websockets == null)
{
return;
}

builder.Append(websockets.IsWebSocketRequest);
#elif NET46_OR_GREATER
var httpContext = HttpContextAccessor.HttpContext;
if (httpContext == null)
{
return;
}
builder.Append(httpContext.IsWebSocketRequest);
#endif
}
}
}
46 changes: 46 additions & 0 deletions src/Shared/LayoutRenderers/AspNetRequestLocalIpLayoutRenderer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using System.Text;
using NLog.LayoutRenderers;
using NLog.Web.Internal;
#if ASP_NET_CORE
using Microsoft.AspNetCore.Http;
#else
using System.Web;
#endif

namespace NLog.Web.LayoutRenderers
{
/// <summary>
/// ASP.NET Local IP of the Connection
/// </summary>
/// <remarks>
/// ${aspnet-request-local-ip}
/// </remarks>
[LayoutRenderer("aspnet-request-local-ip")]
public class AspNetRequestLocalIpLayoutRenderer : AspNetLayoutRendererBase
{
/// <summary>
/// Render Remote Port
/// </summary>
protected override void DoAppend(StringBuilder builder, LogEventInfo logEvent)
{
var httpContext = HttpContextAccessor.HttpContext;

#if ASP_NET_CORE
var connection = httpContext.Connection;
if (connection == null)
{
return;
}

builder.Append(connection.LocalIpAddress?.ToString());
#else
var request = httpContext.TryGetRequest();
if (request == null)
{
return;
}
builder.Append(request.ServerVariables?["LOCAL_ADDR"]);
#endif
}
}
}
45 changes: 45 additions & 0 deletions src/Shared/LayoutRenderers/AspNetRequestLocalPortLayoutRenderer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using System.Text;
using NLog.LayoutRenderers;
using NLog.Web.Internal;
#if ASP_NET_CORE
using Microsoft.AspNetCore.Http;
#else
using System.Web;
#endif

namespace NLog.Web.LayoutRenderers
{
/// <summary>
/// ASP.NET Local Port of the Connection
/// </summary>
/// <remarks>
/// ${aspnet-request-local-port}
/// </remarks>
[LayoutRenderer("aspnet-request-local-port")]
public class AspNetRequestLocalPortLayoutRenderer : AspNetLayoutRendererBase
{
/// <summary>
/// Render Remote Port
/// </summary>
protected override void DoAppend(StringBuilder builder, LogEventInfo logEvent)
{
var httpContext = HttpContextAccessor.HttpContext;
#if ASP_NET_CORE
var connection = httpContext.Connection;
if (connection == null)
{
return;
}

builder.Append(connection.LocalPort);
#else
var request = httpContext.TryGetRequest();
if (request == null)
{
return;
}
builder.Append(request.ServerVariables?["LOCAL_PORT"]);
#endif
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using System.Text;
using NLog.LayoutRenderers;
using NLog.Web.Internal;
#if ASP_NET_CORE
using Microsoft.AspNetCore.Http;
#else
using System.Web;
#endif

namespace NLog.Web.LayoutRenderers
{
/// <summary>
/// ASP.NET Remote Port of the Connection
/// </summary>
/// <remarks>
/// ${aspnet-request-remote-port}
/// </remarks>
[LayoutRenderer("aspnet-request-remote-port")]
public class AspNetRequestRemotePortLayoutRenderer : AspNetLayoutRendererBase
{
/// <summary>
/// Render Remote Port
/// </summary>
protected override void DoAppend(StringBuilder builder, LogEventInfo logEvent)
{
var httpContext = HttpContextAccessor.HttpContext;

#if ASP_NET_CORE
var connection = httpContext.Connection;
if (connection == null)
{
return;
}

builder.Append(connection.RemotePort);
#else
var request = httpContext.TryGetRequest();
if (request == null)
{
return;
}
builder.Append(request.ServerVariables?["REMOTE_PORT"]);
#endif
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
using System.Text;
using NLog.LayoutRenderers;

namespace NLog.Web.LayoutRenderers
{
/// <summary>
/// ASP.NET Web Socket Requested Protocols
/// </summary>
/// <remarks>
/// ${aspnet-request-web-socket-requested-protocols}
/// </remarks>
/// <example>
/// <para>Example usage of ${aspnet-request-web-socket-requested-protocols}</para>
/// <code lang="NLog Layout Renderer">
/// ${aspnet-request-web-socket-requested-protocols:OutputFormat=Flat}
/// ${aspnet-request-web-socket-requested-protocols:OutputFormat=JsonArray}
/// </code>
/// </example>
[LayoutRenderer("aspnet-request-web-socket-requested-protocols")]
public class AspNetRequestWebSocketRequestedProtocolsLayoutRenderer : AspNetLayoutMultiValueRendererBase
{
/// <summary>
/// Renders the specified ASP.NET Core HttpContext.WebSocketManager.WebSocketRequestedProtocols variable and appends it to the specified <see cref="StringBuilder" />.
/// </summary>
/// <param name="builder">The <see cref="StringBuilder" /> to append the rendered data to.</param>
/// <param name="logEvent">Logging event.</param>
protected override void DoAppend(StringBuilder builder, LogEventInfo logEvent)
{
// Not available on .NET 3.5
#if ASP_NET_CORE
var websockets = HttpContextAccessor.HttpContext?.WebSockets;
if (websockets == null)
{
return;
}

if (websockets.WebSocketRequestedProtocols == null)
{
return;

}

if (websockets.WebSocketRequestedProtocols.Count == 0)
{
return;
}

SerializeValues(websockets.WebSocketRequestedProtocols, builder, logEvent);

#elif NET46_OR_GREATER
var httpContext = HttpContextAccessor.HttpContext;
if (httpContext == null)
{
return;
}

if (httpContext.WebSocketRequestedProtocols == null)
{
return;

}

if (httpContext.WebSocketRequestedProtocols.Count == 0)
{
return;
}

SerializeValues(httpContext.WebSocketRequestedProtocols, builder, logEvent);
#endif
}
}
}
Loading

0 comments on commit 0a06ef8

Please sign in to comment.