From 7bc5e33d399171f929e2e3787ac1fcafcea3043a Mon Sep 17 00:00:00 2001 From: Rolf Kristensen Date: Tue, 5 Oct 2021 20:29:46 +0200 Subject: [PATCH] Updated to NLog 5.0 preview 2 (#701) --- appveyor.yml | 1 + .../ASP.NET 4.6.1 - VS2017.csproj | 4 +- .../ASP.NET 4.6.1 - VS2017/packages.config | 2 +- .../AspNetEnvironmentLayoutRenderer.cs | 1 - .../AspNetUserClaimLayoutRenderer.cs | 1 - .../NLog.Web.AspNetCore.csproj | 19 ++- src/NLog.Web/Internal/LogEventInfoBuffer.cs | 155 ++++++++++++++++++ .../AspNetApplicationValueLayoutRenderer.cs | 1 - src/NLog.Web/NLog.Web.csproj | 6 +- .../Wrappers/AspNetBufferingTargetWrapper.cs | 11 +- src/Shared/Internal/PropertyReader.cs | 4 +- .../AspNetAppBasePathLayoutRenderer.cs | 1 - .../AspNetItemValueLayoutRenderer.cs | 3 +- .../AspNetMvcActionRenderer.cs | 1 - .../AspNetMvcControllerRenderer.cs | 1 - .../AspNetRequestContentTypeLayoutRenderer.cs | 1 - .../AspNetRequestCookieLayoutRenderer.cs | 1 - .../AspNetRequestFormLayoutRenderer.cs | 1 - .../AspNetRequestHeadersLayoutRenderer.cs | 1 - .../AspNetRequestHostLayoutRenderer.cs | 1 - .../AspNetRequestHttpMethodRenderer.cs | 1 - .../AspNetRequestIpLayoutRenderer.cs | 1 - .../AspNetRequestPostedBody.cs | 1 - .../AspNetRequestQueryStringLayoutRenderer.cs | 1 - .../AspNetRequestReferrerRenderer.cs | 1 - .../AspNetRequestUrlRenderer.cs | 1 - .../LayoutRenderers/AspNetRequestUserAgent.cs | 1 - .../AspNetRequestValueLayoutRenderer.cs | 15 +- .../AspNetResponseStatusCodeRenderer.cs | 1 - .../AspNetSessionIdLayoutRenderer.cs | 1 - .../AspNetSessionValueLayoutRenderer.cs | 1 - .../AspNetTraceIdentifierLayoutRenderer.cs | 1 - .../AspNetUserAuthTypeLayoutRenderer.cs | 1 - .../AspNetUserIdentityLayoutRenderer.cs | 1 - ...AspNetUserIsAuthenticatedLayoutRenderer.cs | 1 - .../AspNetWebRootPathLayoutRenderer.cs | 1 - .../AssemblyVersionLayoutRenderer.cs | 1 - .../IISInstanceNameLayoutRenderer.cs | 1 - .../AspNetUserClaimLayoutRendererTests.cs | 20 +++ .../NLog.Web.AspNetCore.Tests.csproj | 4 +- ...pNetApplicationValueLayoutRendererTests.cs | 9 +- tests/NLog.Web.Tests/NLog.Web.Tests.csproj | 2 +- .../AspNetSessionValueLayoutRendererTests.cs | 1 + .../LayoutRenderersTestBase.cs | 2 +- 44 files changed, 226 insertions(+), 60 deletions(-) create mode 100644 src/NLog.Web/Internal/LogEventInfoBuffer.cs diff --git a/appveyor.yml b/appveyor.yml index d7963c62..0109bbba 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -27,6 +27,7 @@ deploy: test_script: - nuget.exe install OpenCover -ExcludeVersion -DependencyVersion Ignore - OpenCover\tools\OpenCover.Console.exe -register:user -returntargetcode -target:"%xunit20%\xunit.console.x86.exe" -targetargs:"\"c:\projects\nlogweb\tests\NLog.Web.Tests\bin\Release\net452\NLog.Web.Tests.dll\" -appveyor -noshadow" -returntargetcode -filter:"+[NLog.Web]*" -excludebyattribute:*.ExcludeFromCodeCoverage* -hideskipped:All -oldstyle -output:coverage.xml + - OpenCover\tools\OpenCover.Console.exe -register:user -returntargetcode -target:"%xunit20%\xunit.console.x86.exe" -targetargs:"\"c:\projects\nlogweb\tests\NLog.Web.Tests\bin\Release\net461\NLog.Web.Tests.dll\" -appveyor -noshadow" -returntargetcode -filter:"+[NLog.Web]*" -excludebyattribute:*.ExcludeFromCodeCoverage* -hideskipped:All -oldstyle -mergeoutput -output:coverage.xml - OpenCover\tools\OpenCover.Console.exe -register:user -returntargetcode -target:"%xunit20%\xunit.console.x86.exe" -targetargs:"\"c:\projects\nlogweb\tests\NLog.Web.AspNetCore.Tests\bin\Release\net461\NLog.Web.AspNetCore.Tests.dll\" -appveyor -noshadow" -filter:"+[NLog.Web]*" -excludebyattribute:*.ExcludeFromCodeCoverage* -hideskipped:All -oldstyle -mergeoutput -output:coverage.xml - pip install codecov - codecov -f "coverage.xml" diff --git a/examples/ASP.NET 4.6.1/Visual Studio 2017/ASP.NET 4.6.1 - VS2017/ASP.NET 4.6.1 - VS2017.csproj b/examples/ASP.NET 4.6.1/Visual Studio 2017/ASP.NET 4.6.1 - VS2017/ASP.NET 4.6.1 - VS2017.csproj index 72d0bf75..c5f3792b 100644 --- a/examples/ASP.NET 4.6.1/Visual Studio 2017/ASP.NET 4.6.1 - VS2017/ASP.NET 4.6.1 - VS2017.csproj +++ b/examples/ASP.NET 4.6.1/Visual Studio 2017/ASP.NET 4.6.1 - VS2017/ASP.NET 4.6.1 - VS2017.csproj @@ -45,9 +45,7 @@ - - ..\..\..\..\packages\NLog.4.5.8\lib\net45\NLog.dll - + diff --git a/examples/ASP.NET 4.6.1/Visual Studio 2017/ASP.NET 4.6.1 - VS2017/packages.config b/examples/ASP.NET 4.6.1/Visual Studio 2017/ASP.NET 4.6.1 - VS2017/packages.config index a20670ca..5b2328f3 100644 --- a/examples/ASP.NET 4.6.1/Visual Studio 2017/ASP.NET 4.6.1 - VS2017/packages.config +++ b/examples/ASP.NET 4.6.1/Visual Studio 2017/ASP.NET 4.6.1 - VS2017/packages.config @@ -13,7 +13,7 @@ - + \ No newline at end of file diff --git a/src/NLog.Web.AspNetCore/LayoutRenderers/AspNetEnvironmentLayoutRenderer.cs b/src/NLog.Web.AspNetCore/LayoutRenderers/AspNetEnvironmentLayoutRenderer.cs index 387a5b10..60704966 100644 --- a/src/NLog.Web.AspNetCore/LayoutRenderers/AspNetEnvironmentLayoutRenderer.cs +++ b/src/NLog.Web.AspNetCore/LayoutRenderers/AspNetEnvironmentLayoutRenderer.cs @@ -19,7 +19,6 @@ namespace NLog.Web.LayoutRenderers /// [LayoutRenderer("aspnet-environment")] [ThreadAgnostic] - [ThreadSafe] public class AspNetEnvironmentLayoutRenderer : LayoutRenderer { private static IHostEnvironment _hostEnvironment; diff --git a/src/NLog.Web.AspNetCore/LayoutRenderers/AspNetUserClaimLayoutRenderer.cs b/src/NLog.Web.AspNetCore/LayoutRenderers/AspNetUserClaimLayoutRenderer.cs index 60b0abd0..3c0aa382 100644 --- a/src/NLog.Web.AspNetCore/LayoutRenderers/AspNetUserClaimLayoutRenderer.cs +++ b/src/NLog.Web.AspNetCore/LayoutRenderers/AspNetUserClaimLayoutRenderer.cs @@ -12,7 +12,6 @@ namespace NLog.Web.LayoutRenderers /// ASP.NET User ClaimType Value Lookup. /// [LayoutRenderer("aspnet-user-claim")] - [ThreadSafe] public class AspNetUserClaimLayoutRenderer : AspNetLayoutRendererBase { /// diff --git a/src/NLog.Web.AspNetCore/NLog.Web.AspNetCore.csproj b/src/NLog.Web.AspNetCore/NLog.Web.AspNetCore.csproj index 842fd6aa..daa83bf6 100644 --- a/src/NLog.Web.AspNetCore/NLog.Web.AspNetCore.csproj +++ b/src/NLog.Web.AspNetCore/NLog.Web.AspNetCore.csproj @@ -1,7 +1,7 @@  PackageReference - net461;netstandard2.0;netcoreapp3.0 + net461;netstandard2.0;netcoreapp3.1;net5.0 NLog.Web.AspNetCore v$(VersionPrefix) NLog LoggerProvider for Microsoft.Extensions.Logging and ASP.NET Core platform. Adds helpers and layout renderers for websites and web applications. @@ -30,7 +30,7 @@ See also https://github.com/NLog/NLog.Web/releases git git://github.com/NLog/NLog.Web true - 4.0.0.0 + 5.0.0.0 NLog.snk true NLog.Web @@ -56,12 +56,16 @@ See also https://github.com/NLog/NLog.Web/releases ASP.NET Core 2 integration for NLog - .NET Standard 2 $(DefineConstants);ASP_NET_CORE;ASP_NET_CORE2 - - ASP.NET Core 3 integration for NLog - .NET Core 3 + + ASP.NET Core 3 integration for NLog - .NET Core 3.1 + $(DefineConstants);ASP_NET_CORE;ASP_NET_CORE3 + + + ASP.NET Core 5 integration for NLog - .NET 5.0 $(DefineConstants);ASP_NET_CORE;ASP_NET_CORE3 - + @@ -72,7 +76,10 @@ See also https://github.com/NLog/NLog.Web/releases - + + + + diff --git a/src/NLog.Web/Internal/LogEventInfoBuffer.cs b/src/NLog.Web/Internal/LogEventInfoBuffer.cs new file mode 100644 index 00000000..dd846daf --- /dev/null +++ b/src/NLog.Web/Internal/LogEventInfoBuffer.cs @@ -0,0 +1,155 @@ +// +// Copyright (c) 2004-2021 Jaroslaw Kowalski , Kim Christensen, Julian Verdurmen +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * Neither the name of Jaroslaw Kowalski nor the names of its +// contributors may be used to endorse or promote products derived from this +// software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +// THE POSSIBILITY OF SUCH DAMAGE. +// + +namespace NLog.Web.Internal +{ + using NLog.Common; + using System; + + /// + /// A cyclic buffer of object. + /// + internal class LogEventInfoBuffer + { + private readonly object _lockObject = new object(); + private readonly bool _growAsNeeded; + private readonly int _growLimit; + + private AsyncLogEventInfo[] _buffer; + private int _getPointer; + private int _putPointer; + private int _count; + + /// + /// Initializes a new instance of the class. + /// + /// Buffer size. + /// Whether buffer should grow as it becomes full. + /// The maximum number of items that the buffer can grow to. + public LogEventInfoBuffer(int size, bool growAsNeeded, int growLimit) + { + _growAsNeeded = growAsNeeded; + _buffer = new AsyncLogEventInfo[size]; + _growLimit = growLimit; + _getPointer = 0; + _putPointer = 0; + } + + /// + /// Gets the capacity of the buffer + /// + public int Size => _buffer.Length; + + /// + /// Gets the number of items in the buffer + /// + internal int Count { get { lock (_lockObject) return _count; } } + + /// + /// Adds the specified log event to the buffer. + /// + /// Log event. + /// The number of items in the buffer. + public int Append(AsyncLogEventInfo eventInfo) + { + lock (_lockObject) + { + // make room for additional item + if (_count >= _buffer.Length) + { + if (_growAsNeeded && _buffer.Length < _growLimit) + { + // create a new buffer, copy data from current + int newLength = _buffer.Length * 2; + if (newLength >= _growLimit) + { + newLength = _growLimit; + } + + InternalLogger.Trace("Enlarging LogEventInfoBuffer from {0} to {1}", _buffer.Length, newLength); + var newBuffer = new AsyncLogEventInfo[newLength]; + Array.Copy(_buffer, 0, newBuffer, 0, _buffer.Length); + _buffer = newBuffer; + } + else + { + // lose the oldest item + _getPointer = _getPointer + 1; + } + } + + // put the item + _putPointer = _putPointer % _buffer.Length; + _buffer[_putPointer] = eventInfo; + _putPointer = _putPointer + 1; + _count++; + if (_count >= _buffer.Length) + { + _count = _buffer.Length; + } + + return _count; + } + } + + /// + /// Gets the array of events accumulated in the buffer and clears the buffer as one atomic operation. + /// + /// Events in the buffer. + public AsyncLogEventInfo[] GetEventsAndClear() + { + lock (_lockObject) + { + int cnt = _count; + if (cnt == 0) + return new AsyncLogEventInfo[0]; + + var returnValue = new AsyncLogEventInfo[cnt]; + + for (int i = 0; i < cnt; ++i) + { + int p = (_getPointer + i) % _buffer.Length; + var e = _buffer[p]; + _buffer[p] = default(AsyncLogEventInfo); // we don't want memory leaks + returnValue[i] = e; + } + + _count = 0; + _getPointer = 0; + _putPointer = 0; + + return returnValue; + } + } + } +} diff --git a/src/NLog.Web/LayoutRenderers/AspNetApplicationValueLayoutRenderer.cs b/src/NLog.Web/LayoutRenderers/AspNetApplicationValueLayoutRenderer.cs index 6880c677..41258136 100644 --- a/src/NLog.Web/LayoutRenderers/AspNetApplicationValueLayoutRenderer.cs +++ b/src/NLog.Web/LayoutRenderers/AspNetApplicationValueLayoutRenderer.cs @@ -33,7 +33,6 @@ namespace NLog.Web.LayoutRenderers /// /// [LayoutRenderer("aspnet-application")] - [ThreadSafe] public class AspNetApplicationValueLayoutRenderer : AspNetLayoutRendererBase { /// diff --git a/src/NLog.Web/NLog.Web.csproj b/src/NLog.Web/NLog.Web.csproj index c9825c07..cb99fbf0 100644 --- a/src/NLog.Web/NLog.Web.csproj +++ b/src/NLog.Web/NLog.Web.csproj @@ -1,7 +1,7 @@  PackageReference - net35 + net35;net46 NLog.Web v$(VersionPrefix) NLog logging for ASP.NET and ASP.NET MVC. Includes targets and layout renderers for websites and web applications. @@ -33,7 +33,7 @@ See https://github.com/NLog/NLog.Web/releases https://github.com/NLog/NLog.Web.git true - 4.0.0.0 + 5.0.0.0 NLog.snk true @@ -49,7 +49,7 @@ See https://github.com/NLog/NLog.Web/releases - + diff --git a/src/NLog.Web/Targets/Wrappers/AspNetBufferingTargetWrapper.cs b/src/NLog.Web/Targets/Wrappers/AspNetBufferingTargetWrapper.cs index d65dcd39..a9eda3f6 100644 --- a/src/NLog.Web/Targets/Wrappers/AspNetBufferingTargetWrapper.cs +++ b/src/NLog.Web/Targets/Wrappers/AspNetBufferingTargetWrapper.cs @@ -4,6 +4,7 @@ using NLog.Common; using NLog.Targets; using NLog.Targets.Wrappers; +using NLog.Web.Internal; namespace NLog.Web.Targets.Wrappers { @@ -163,7 +164,7 @@ protected override void CloseTarget() /// The log event. protected override void Write(AsyncLogEventInfo logEvent) { - LogEventInfoBuffer buffer = GetRequestBuffer(); + var buffer = GetRequestBuffer(); if (buffer != null) { WrappedTarget.PrecalculateVolatileLayouts(logEvent.LogEvent); @@ -178,7 +179,7 @@ protected override void Write(AsyncLogEventInfo logEvent) } } - private LogEventInfoBuffer GetRequestBuffer() + private NLog.Web.Internal.LogEventInfoBuffer GetRequestBuffer() { HttpContext context = HttpContext.Current; if (context == null) @@ -186,19 +187,19 @@ private LogEventInfoBuffer GetRequestBuffer() return null; } - return context.Items[dataSlot] as LogEventInfoBuffer; + return context.Items[dataSlot] as NLog.Web.Internal.LogEventInfoBuffer; } private void OnBeginRequest(object sender, EventArgs args) { InternalLogger.Trace("Setting up ASP.NET request buffer."); HttpContext context = HttpContext.Current; - context.Items[dataSlot] = new LogEventInfoBuffer(BufferSize, GrowBufferAsNeeded, BufferGrowLimit); + context.Items[dataSlot] = new NLog.Web.Internal.LogEventInfoBuffer(BufferSize, GrowBufferAsNeeded, BufferGrowLimit); } private void OnEndRequest(object sender, EventArgs args) { - LogEventInfoBuffer buffer = GetRequestBuffer(); + var buffer = GetRequestBuffer(); if (buffer != null) { InternalLogger.Trace("Sending buffered events to wrapped target: {0}.", WrappedTarget); diff --git a/src/Shared/Internal/PropertyReader.cs b/src/Shared/Internal/PropertyReader.cs index 2c8b21f5..8a526ff8 100644 --- a/src/Shared/Internal/PropertyReader.cs +++ b/src/Shared/Internal/PropertyReader.cs @@ -32,9 +32,9 @@ private static object GetValueAsNestedProperties(string key, T container, Fun var value = getVal(container, path?.First() ?? key); if (value != null && path?.Length > 1) { - foreach (var property in path.Skip(1)) + for (int i = 1; i < path.Length; ++i) { - var propertyInfo = GetPropertyInfo(value, property); + var propertyInfo = GetPropertyInfo(value, path[i]); value = propertyInfo?.GetValue(value, null); if (value == null) { diff --git a/src/Shared/LayoutRenderers/AspNetAppBasePathLayoutRenderer.cs b/src/Shared/LayoutRenderers/AspNetAppBasePathLayoutRenderer.cs index e49755f8..b59282b7 100644 --- a/src/Shared/LayoutRenderers/AspNetAppBasePathLayoutRenderer.cs +++ b/src/Shared/LayoutRenderers/AspNetAppBasePathLayoutRenderer.cs @@ -30,7 +30,6 @@ namespace NLog.Web.LayoutRenderers #endif [LayoutRenderer("aspnet-appbasepath")] [ThreadAgnostic] - [ThreadSafe] public class AspNetAppBasePathLayoutRenderer : LayoutRenderer { #if ASP_NET_CORE diff --git a/src/Shared/LayoutRenderers/AspNetItemValueLayoutRenderer.cs b/src/Shared/LayoutRenderers/AspNetItemValueLayoutRenderer.cs index 0aaaaccf..4fd7023d 100644 --- a/src/Shared/LayoutRenderers/AspNetItemValueLayoutRenderer.cs +++ b/src/Shared/LayoutRenderers/AspNetItemValueLayoutRenderer.cs @@ -41,7 +41,6 @@ namespace NLog.Web.LayoutRenderers /// /// [LayoutRenderer("aspnet-item")] - [ThreadSafe] public class AspNetItemValueLayoutRenderer : AspNetLayoutRendererBase { /// @@ -84,7 +83,7 @@ protected override void DoAppend(StringBuilder builder, LogEventInfo logEvent) } var context = HttpContextAccessor.HttpContext; - var value = PropertyReader.GetValue(Variable, context?.Items, LookupItemValue, EvaluateAsNestedProperties); + var value = PropertyReader.GetValue(Variable, context?.Items, (items, key) => LookupItemValue(items, key), EvaluateAsNestedProperties); var formatProvider = GetFormatProvider(logEvent, Culture); builder.Append(Convert.ToString(value, formatProvider)); } diff --git a/src/Shared/LayoutRenderers/AspNetMvcActionRenderer.cs b/src/Shared/LayoutRenderers/AspNetMvcActionRenderer.cs index cc1360ac..9b6bdb7b 100644 --- a/src/Shared/LayoutRenderers/AspNetMvcActionRenderer.cs +++ b/src/Shared/LayoutRenderers/AspNetMvcActionRenderer.cs @@ -24,7 +24,6 @@ namespace NLog.Web.LayoutRenderers /// /// [LayoutRenderer("aspnet-mvc-action")] - [ThreadSafe] public class AspNetMvcActionRenderer : AspNetMvcLayoutRendererBase { /// diff --git a/src/Shared/LayoutRenderers/AspNetMvcControllerRenderer.cs b/src/Shared/LayoutRenderers/AspNetMvcControllerRenderer.cs index e8db696d..d5f4010f 100644 --- a/src/Shared/LayoutRenderers/AspNetMvcControllerRenderer.cs +++ b/src/Shared/LayoutRenderers/AspNetMvcControllerRenderer.cs @@ -24,7 +24,6 @@ namespace NLog.Web.LayoutRenderers /// /// [LayoutRenderer("aspnet-mvc-controller")] - [ThreadSafe] public class AspNetMvcControllerRenderer : AspNetMvcLayoutRendererBase { /// diff --git a/src/Shared/LayoutRenderers/AspNetRequestContentTypeLayoutRenderer.cs b/src/Shared/LayoutRenderers/AspNetRequestContentTypeLayoutRenderer.cs index 8bffa565..474caf78 100644 --- a/src/Shared/LayoutRenderers/AspNetRequestContentTypeLayoutRenderer.cs +++ b/src/Shared/LayoutRenderers/AspNetRequestContentTypeLayoutRenderer.cs @@ -14,7 +14,6 @@ namespace NLog.Web.LayoutRenderers /// /// [LayoutRenderer("aspnet-request-contenttype")] - [ThreadSafe] public class AspNetRequestContentTypeLayoutRenderer : AspNetLayoutRendererBase { /// diff --git a/src/Shared/LayoutRenderers/AspNetRequestCookieLayoutRenderer.cs b/src/Shared/LayoutRenderers/AspNetRequestCookieLayoutRenderer.cs index 75511b22..7ad50ed7 100644 --- a/src/Shared/LayoutRenderers/AspNetRequestCookieLayoutRenderer.cs +++ b/src/Shared/LayoutRenderers/AspNetRequestCookieLayoutRenderer.cs @@ -30,7 +30,6 @@ namespace NLog.Web.LayoutRenderers /// /// [LayoutRenderer("aspnet-request-cookie")] - [ThreadSafe] public class AspNetRequestCookieLayoutRenderer : AspNetLayoutMultiValueRendererBase { /// diff --git a/src/Shared/LayoutRenderers/AspNetRequestFormLayoutRenderer.cs b/src/Shared/LayoutRenderers/AspNetRequestFormLayoutRenderer.cs index dc6f63cf..06815b67 100644 --- a/src/Shared/LayoutRenderers/AspNetRequestFormLayoutRenderer.cs +++ b/src/Shared/LayoutRenderers/AspNetRequestFormLayoutRenderer.cs @@ -24,7 +24,6 @@ namespace NLog.Web.LayoutRenderers /// /// [LayoutRenderer("aspnet-request-form")] - [ThreadSafe] public class AspNetRequestFormLayoutRenderer : AspNetLayoutMultiValueRendererBase { /// diff --git a/src/Shared/LayoutRenderers/AspNetRequestHeadersLayoutRenderer.cs b/src/Shared/LayoutRenderers/AspNetRequestHeadersLayoutRenderer.cs index b452adc2..8a5a28cb 100644 --- a/src/Shared/LayoutRenderers/AspNetRequestHeadersLayoutRenderer.cs +++ b/src/Shared/LayoutRenderers/AspNetRequestHeadersLayoutRenderer.cs @@ -26,7 +26,6 @@ namespace NLog.Web.LayoutRenderers /// /// [LayoutRenderer("aspnet-request-headers")] - [ThreadSafe] public class AspNetRequestHeadersLayoutRenderer : AspNetLayoutMultiValueRendererBase { /// diff --git a/src/Shared/LayoutRenderers/AspNetRequestHostLayoutRenderer.cs b/src/Shared/LayoutRenderers/AspNetRequestHostLayoutRenderer.cs index b8d6d461..dd964be5 100644 --- a/src/Shared/LayoutRenderers/AspNetRequestHostLayoutRenderer.cs +++ b/src/Shared/LayoutRenderers/AspNetRequestHostLayoutRenderer.cs @@ -17,7 +17,6 @@ namespace NLog.Web.LayoutRenderers /// /// [LayoutRenderer("aspnet-request-host")] - [ThreadSafe] public class AspNetRequestHostLayoutRenderer : AspNetLayoutRendererBase { /// diff --git a/src/Shared/LayoutRenderers/AspNetRequestHttpMethodRenderer.cs b/src/Shared/LayoutRenderers/AspNetRequestHttpMethodRenderer.cs index 76cc0816..a908211b 100644 --- a/src/Shared/LayoutRenderers/AspNetRequestHttpMethodRenderer.cs +++ b/src/Shared/LayoutRenderers/AspNetRequestHttpMethodRenderer.cs @@ -20,7 +20,6 @@ namespace NLog.Web.LayoutRenderers /// /// [LayoutRenderer("aspnet-request-method")] - [ThreadSafe] public class AspNetRequestHttpMethodRenderer : AspNetLayoutRendererBase { /// diff --git a/src/Shared/LayoutRenderers/AspNetRequestIpLayoutRenderer.cs b/src/Shared/LayoutRenderers/AspNetRequestIpLayoutRenderer.cs index f582a3f7..bec3e0a7 100644 --- a/src/Shared/LayoutRenderers/AspNetRequestIpLayoutRenderer.cs +++ b/src/Shared/LayoutRenderers/AspNetRequestIpLayoutRenderer.cs @@ -23,7 +23,6 @@ namespace NLog.Web.LayoutRenderers /// /// [LayoutRenderer("aspnet-request-ip")] - [ThreadSafe] public class AspNetRequestIpLayoutRenderer : AspNetLayoutRendererBase { /// diff --git a/src/Shared/LayoutRenderers/AspNetRequestPostedBody.cs b/src/Shared/LayoutRenderers/AspNetRequestPostedBody.cs index 12706b60..fb98e295 100644 --- a/src/Shared/LayoutRenderers/AspNetRequestPostedBody.cs +++ b/src/Shared/LayoutRenderers/AspNetRequestPostedBody.cs @@ -27,7 +27,6 @@ namespace NLog.Web.LayoutRenderers /// /// [LayoutRenderer("aspnet-request-posted-body")] - [ThreadSafe] public class AspNetRequestPostedBody : AspNetLayoutRendererBase { private const int Size64KiloBytes = 64 * 1024; diff --git a/src/Shared/LayoutRenderers/AspNetRequestQueryStringLayoutRenderer.cs b/src/Shared/LayoutRenderers/AspNetRequestQueryStringLayoutRenderer.cs index f3aa0d39..e90f6baa 100644 --- a/src/Shared/LayoutRenderers/AspNetRequestQueryStringLayoutRenderer.cs +++ b/src/Shared/LayoutRenderers/AspNetRequestQueryStringLayoutRenderer.cs @@ -26,7 +26,6 @@ namespace NLog.Web.LayoutRenderers /// /// [LayoutRenderer("aspnet-request-querystring")] - [ThreadSafe] public class AspNetQueryStringLayoutRenderer : AspNetLayoutMultiValueRendererBase { /// diff --git a/src/Shared/LayoutRenderers/AspNetRequestReferrerRenderer.cs b/src/Shared/LayoutRenderers/AspNetRequestReferrerRenderer.cs index 06de4f81..fb05fb5a 100644 --- a/src/Shared/LayoutRenderers/AspNetRequestReferrerRenderer.cs +++ b/src/Shared/LayoutRenderers/AspNetRequestReferrerRenderer.cs @@ -21,7 +21,6 @@ namespace NLog.Web.LayoutRenderers /// /// [LayoutRenderer("aspnet-request-referrer")] - [ThreadSafe] public class AspNetRequestReferrerRenderer : AspNetLayoutRendererBase { /// diff --git a/src/Shared/LayoutRenderers/AspNetRequestUrlRenderer.cs b/src/Shared/LayoutRenderers/AspNetRequestUrlRenderer.cs index ea4cdcb6..f4e27713 100644 --- a/src/Shared/LayoutRenderers/AspNetRequestUrlRenderer.cs +++ b/src/Shared/LayoutRenderers/AspNetRequestUrlRenderer.cs @@ -29,7 +29,6 @@ namespace NLog.Web.LayoutRenderers /// /// [LayoutRenderer("aspnet-request-url")] - [ThreadSafe] public class AspNetRequestUrlRenderer : AspNetLayoutRendererBase { /// diff --git a/src/Shared/LayoutRenderers/AspNetRequestUserAgent.cs b/src/Shared/LayoutRenderers/AspNetRequestUserAgent.cs index 197bcdd6..a2cc09c9 100644 --- a/src/Shared/LayoutRenderers/AspNetRequestUserAgent.cs +++ b/src/Shared/LayoutRenderers/AspNetRequestUserAgent.cs @@ -21,7 +21,6 @@ namespace NLog.Web.LayoutRenderers /// /// [LayoutRenderer("aspnet-request-useragent")] - [ThreadSafe] public class AspNetRequestUserAgent : AspNetLayoutRendererBase { /// diff --git a/src/Shared/LayoutRenderers/AspNetRequestValueLayoutRenderer.cs b/src/Shared/LayoutRenderers/AspNetRequestValueLayoutRenderer.cs index 638f195c..e974b078 100644 --- a/src/Shared/LayoutRenderers/AspNetRequestValueLayoutRenderer.cs +++ b/src/Shared/LayoutRenderers/AspNetRequestValueLayoutRenderer.cs @@ -31,7 +31,6 @@ namespace NLog.Web.LayoutRenderers /// /// [LayoutRenderer("aspnet-request")] - [ThreadSafe] public class AspNetRequestValueLayoutRenderer : AspNetLayoutRendererBase { /// @@ -151,7 +150,8 @@ private static string LookupItemValue(string key, HttpRequestBase httpRequest) #else private static string LookupQueryString(string key, HttpRequest httpRequest) { - if (httpRequest.Query?.TryGetValue(key, out var queryValue) ?? false) + var query = httpRequest.Query; + if (query != null && query.TryGetValue(key, out var queryValue)) { return queryValue.ToString(); } @@ -161,9 +161,13 @@ private static string LookupQueryString(string key, HttpRequest httpRequest) private static string LookupFormValue(string key, HttpRequest httpRequest) { - if (httpRequest.HasFormContentType && (httpRequest.Form?.TryGetValue(key, out var queryValue) ?? false)) + if (httpRequest.HasFormContentType) { - return queryValue.ToString(); + var form = httpRequest.Form; + if (form != null && form.TryGetValue(key, out var queryValue)) + { + return queryValue.ToString(); + } } return null; @@ -182,7 +186,8 @@ private static string LookupCookieValue(string key, HttpRequest httpRequest) private static string LookupHeaderValue(string key, HttpRequest httpRequest) { - if (httpRequest.Headers?.TryGetValue(key, out var headerValue) ?? false) + var headers = httpRequest.Headers; + if (headers != null && headers.TryGetValue(key, out var headerValue)) { return headerValue.ToString(); } diff --git a/src/Shared/LayoutRenderers/AspNetResponseStatusCodeRenderer.cs b/src/Shared/LayoutRenderers/AspNetResponseStatusCodeRenderer.cs index 8a12f25a..04c64161 100644 --- a/src/Shared/LayoutRenderers/AspNetResponseStatusCodeRenderer.cs +++ b/src/Shared/LayoutRenderers/AspNetResponseStatusCodeRenderer.cs @@ -15,7 +15,6 @@ namespace NLog.Web.LayoutRenderers /// /// [LayoutRenderer("aspnet-response-statuscode")] - [ThreadSafe] public class AspNetResponseStatusCodeRenderer : AspNetLayoutRendererBase { /// diff --git a/src/Shared/LayoutRenderers/AspNetSessionIdLayoutRenderer.cs b/src/Shared/LayoutRenderers/AspNetSessionIdLayoutRenderer.cs index 69f386ab..717a1321 100644 --- a/src/Shared/LayoutRenderers/AspNetSessionIdLayoutRenderer.cs +++ b/src/Shared/LayoutRenderers/AspNetSessionIdLayoutRenderer.cs @@ -13,7 +13,6 @@ namespace NLog.Web.LayoutRenderers /// ASP.NET Session ID. /// [LayoutRenderer("aspnet-sessionid")] - [ThreadSafe] public class AspNetSessionIdLayoutRenderer : AspNetLayoutRendererBase { /// diff --git a/src/Shared/LayoutRenderers/AspNetSessionValueLayoutRenderer.cs b/src/Shared/LayoutRenderers/AspNetSessionValueLayoutRenderer.cs index b6185c9b..c7cd0549 100644 --- a/src/Shared/LayoutRenderers/AspNetSessionValueLayoutRenderer.cs +++ b/src/Shared/LayoutRenderers/AspNetSessionValueLayoutRenderer.cs @@ -39,7 +39,6 @@ namespace NLog.Web.LayoutRenderers /// /// [LayoutRenderer("aspnet-session")] - [ThreadSafe] public class AspNetSessionValueLayoutRenderer : AspNetLayoutRendererBase { #if ASP_NET_CORE diff --git a/src/Shared/LayoutRenderers/AspNetTraceIdentifierLayoutRenderer.cs b/src/Shared/LayoutRenderers/AspNetTraceIdentifierLayoutRenderer.cs index 0671545c..c3710afc 100644 --- a/src/Shared/LayoutRenderers/AspNetTraceIdentifierLayoutRenderer.cs +++ b/src/Shared/LayoutRenderers/AspNetTraceIdentifierLayoutRenderer.cs @@ -12,7 +12,6 @@ namespace NLog.Web.LayoutRenderers /// ASP.NET Request TraceIdentifier. /// [LayoutRenderer("aspnet-traceidentifier")] - [ThreadSafe] public class AspNetTraceIdentifierLayoutRenderer : AspNetLayoutRendererBase { /// diff --git a/src/Shared/LayoutRenderers/AspNetUserAuthTypeLayoutRenderer.cs b/src/Shared/LayoutRenderers/AspNetUserAuthTypeLayoutRenderer.cs index 4c1b1f30..2df03978 100644 --- a/src/Shared/LayoutRenderers/AspNetUserAuthTypeLayoutRenderer.cs +++ b/src/Shared/LayoutRenderers/AspNetUserAuthTypeLayoutRenderer.cs @@ -14,7 +14,6 @@ namespace NLog.Web.LayoutRenderers /// ASP.NET User variable. /// [LayoutRenderer("aspnet-user-authtype")] - [ThreadSafe] public class AspNetUserAuthTypeLayoutRenderer : AspNetLayoutRendererBase { /// diff --git a/src/Shared/LayoutRenderers/AspNetUserIdentityLayoutRenderer.cs b/src/Shared/LayoutRenderers/AspNetUserIdentityLayoutRenderer.cs index 6fe3a9ea..9d3798ff 100644 --- a/src/Shared/LayoutRenderers/AspNetUserIdentityLayoutRenderer.cs +++ b/src/Shared/LayoutRenderers/AspNetUserIdentityLayoutRenderer.cs @@ -14,7 +14,6 @@ namespace NLog.Web.LayoutRenderers /// ASP.NET User variable. /// [LayoutRenderer("aspnet-user-identity")] - [ThreadSafe] public class AspNetUserIdentityLayoutRenderer : AspNetLayoutRendererBase { /// diff --git a/src/Shared/LayoutRenderers/AspNetUserIsAuthenticatedLayoutRenderer.cs b/src/Shared/LayoutRenderers/AspNetUserIsAuthenticatedLayoutRenderer.cs index 1dd73e13..b6c62c9e 100644 --- a/src/Shared/LayoutRenderers/AspNetUserIsAuthenticatedLayoutRenderer.cs +++ b/src/Shared/LayoutRenderers/AspNetUserIsAuthenticatedLayoutRenderer.cs @@ -13,7 +13,6 @@ namespace NLog.Web.AspNetCore.LayoutRenderers /// ${aspnet-user-isAuthenticated} /// [LayoutRenderer("aspnet-user-isAuthenticated")] - [ThreadSafe] public class AspNetUserIsAuthenticatedLayoutRenderer : AspNetLayoutRendererBase { /// diff --git a/src/Shared/LayoutRenderers/AspNetWebRootPathLayoutRenderer.cs b/src/Shared/LayoutRenderers/AspNetWebRootPathLayoutRenderer.cs index 87c6304a..0b5b4a62 100644 --- a/src/Shared/LayoutRenderers/AspNetWebRootPathLayoutRenderer.cs +++ b/src/Shared/LayoutRenderers/AspNetWebRootPathLayoutRenderer.cs @@ -26,7 +26,6 @@ namespace NLog.Web.LayoutRenderers #endif [LayoutRenderer("aspnet-webrootpath")] [ThreadAgnostic] - [ThreadSafe] public class AspNetWebRootPathLayoutRenderer : LayoutRenderer { #if ASP_NET_CORE diff --git a/src/Shared/LayoutRenderers/AssemblyVersionLayoutRenderer.cs b/src/Shared/LayoutRenderers/AssemblyVersionLayoutRenderer.cs index e13b3cde..e429653f 100644 --- a/src/Shared/LayoutRenderers/AssemblyVersionLayoutRenderer.cs +++ b/src/Shared/LayoutRenderers/AssemblyVersionLayoutRenderer.cs @@ -11,7 +11,6 @@ namespace NLog.Web.LayoutRenderers /// [LayoutRenderer("assembly-version")] [ThreadAgnostic] - [ThreadSafe] public class AssemblyVersionLayoutRenderer : NLog.LayoutRenderers.AssemblyVersionLayoutRenderer { #if !ASP_NET_CORE diff --git a/src/Shared/LayoutRenderers/IISInstanceNameLayoutRenderer.cs b/src/Shared/LayoutRenderers/IISInstanceNameLayoutRenderer.cs index 8e8e4c73..fce582d9 100644 --- a/src/Shared/LayoutRenderers/IISInstanceNameLayoutRenderer.cs +++ b/src/Shared/LayoutRenderers/IISInstanceNameLayoutRenderer.cs @@ -30,7 +30,6 @@ namespace NLog.Web.LayoutRenderers [LayoutRenderer("iis-site-name")] // ReSharper disable once InconsistentNaming [ThreadAgnostic] - [ThreadSafe] public class IISInstanceNameLayoutRenderer : LayoutRenderer { #if ASP_NET_CORE diff --git a/tests/NLog.Web.AspNetCore.Tests/AspNetUserClaimLayoutRendererTests.cs b/tests/NLog.Web.AspNetCore.Tests/AspNetUserClaimLayoutRendererTests.cs index 71eefe68..4d45f117 100644 --- a/tests/NLog.Web.AspNetCore.Tests/AspNetUserClaimLayoutRendererTests.cs +++ b/tests/NLog.Web.AspNetCore.Tests/AspNetUserClaimLayoutRendererTests.cs @@ -9,6 +9,26 @@ namespace NLog.Web.Tests.LayoutRenderers { public class AspNetUserClaimLayoutRendererTests : LayoutRenderersTestBase { + [Fact] + public override void NullRendersEmptyString() + { + // Arrange + var (renderer, httpContext) = CreateWithHttpContext(); + renderer.ClaimType = string.Empty; + httpContext.User.Identity.Returns(null as IIdentity); + + // Act + string result = renderer.Render(new LogEventInfo()); + + // Assert + Assert.Empty(result); + + // Bonus assert + renderer.ClaimType = null; + result = renderer.Render(new LogEventInfo()); + Assert.Empty(result); + } + [Fact] public void NullUserIdentityRendersEmptyString() { diff --git a/tests/NLog.Web.AspNetCore.Tests/NLog.Web.AspNetCore.Tests.csproj b/tests/NLog.Web.AspNetCore.Tests/NLog.Web.AspNetCore.Tests.csproj index 378c7dd4..d8f97538 100644 --- a/tests/NLog.Web.AspNetCore.Tests/NLog.Web.AspNetCore.Tests.csproj +++ b/tests/NLog.Web.AspNetCore.Tests/NLog.Web.AspNetCore.Tests.csproj @@ -1,6 +1,6 @@  - netcoreapp2.1;net461;netcoreapp3.0 + netcoreapp2.1;net461;netcoreapp3.1;net5.0 NLog.Web.AspNetCore.Tests 1.2.3.0 1.2.3.1 @@ -15,7 +15,7 @@ 2.0.0 $(DefineConstants);ASP_NET_CORE;ASP_NET_CORE2 - + $(DefineConstants);ASP_NET_CORE;ASP_NET_CORE3 diff --git a/tests/NLog.Web.Tests/LayoutRenderers/AspNetApplicationValueLayoutRendererTests.cs b/tests/NLog.Web.Tests/LayoutRenderers/AspNetApplicationValueLayoutRendererTests.cs index 71474cff..38d3ef7a 100644 --- a/tests/NLog.Web.Tests/LayoutRenderers/AspNetApplicationValueLayoutRendererTests.cs +++ b/tests/NLog.Web.Tests/LayoutRenderers/AspNetApplicationValueLayoutRendererTests.cs @@ -16,9 +16,13 @@ public class AspNetApplicationValueLayoutRendererTests : TestBase public void NullHttpContextRendersEmptyString() { var renderer = new AspNetApplicationValueLayoutRenderer(); + renderer.Variable = string.Empty; string result = renderer.Render(new LogEventInfo()); + Assert.Empty(result); + renderer.Variable = null; + result = renderer.Render(new LogEventInfo()); Assert.Empty(result); } @@ -28,11 +32,14 @@ public void NullVariableRendersEmptyString() var httpContext = Substitute.For(); var renderer = new AspNetApplicationValueLayoutRenderer(); - renderer.Variable = null; + renderer.Variable = string.Empty; renderer.HttpContextAccessor = new FakeHttpContextAccessor(httpContext); string result = renderer.Render(new LogEventInfo()); + Assert.Empty(result); + renderer.Variable = null; + result = renderer.Render(new LogEventInfo()); Assert.Empty(result); } diff --git a/tests/NLog.Web.Tests/NLog.Web.Tests.csproj b/tests/NLog.Web.Tests/NLog.Web.Tests.csproj index fab12799..f5c1db4d 100644 --- a/tests/NLog.Web.Tests/NLog.Web.Tests.csproj +++ b/tests/NLog.Web.Tests/NLog.Web.Tests.csproj @@ -1,6 +1,6 @@  - net452 + net452;net461 False UnitTest NLog.Web.Tests diff --git a/tests/Shared/LayoutRenderers/AspNetSessionValueLayoutRendererTests.cs b/tests/Shared/LayoutRenderers/AspNetSessionValueLayoutRendererTests.cs index 4e196dd0..209db909 100644 --- a/tests/Shared/LayoutRenderers/AspNetSessionValueLayoutRendererTests.cs +++ b/tests/Shared/LayoutRenderers/AspNetSessionValueLayoutRendererTests.cs @@ -147,6 +147,7 @@ public void NullVarname() [Fact] public void SessionWithCulture() { + LayoutRenderer.Register("aspnet-session"); Layout layout = "${aspnet-session:a.b:culture=en-GB:evaluateAsNestedProperties=true}"; var o = new { b = new DateTime(2015, 11, 24, 2, 30, 23) }; diff --git a/tests/Shared/LayoutRenderers/LayoutRenderersTestBase.cs b/tests/Shared/LayoutRenderers/LayoutRenderersTestBase.cs index b529cdd7..1fde85ac 100644 --- a/tests/Shared/LayoutRenderers/LayoutRenderersTestBase.cs +++ b/tests/Shared/LayoutRenderers/LayoutRenderersTestBase.cs @@ -16,7 +16,7 @@ public abstract class LayoutRenderersTestBase : TestBase where TLayoutRenderer : AspNetLayoutRendererBase, new() { [Fact] - public void NullRendersEmptyString() + public virtual void NullRendersEmptyString() { // Arrange var (renderer, _) = CreateWithHttpContext();