This is an automated email from the ASF dual-hosted git repository. freeandnil pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/logging-log4net.git
commit 33d668d2ffdde6f2ce3fddb2decbddfd0b65cbee Author: Jan Friedrich <[email protected]> AuthorDate: Wed Jun 18 16:06:12 2025 +0200 #255 added unit test for RemoteSyslogAppender --- src/log4net.Tests/Appender/Internal/UdpMock.cs | 60 ++++++++++++ .../Appender/RemoteSyslogAppenderTest.cs | 75 +++++++++++++++ src/log4net.Tests/Appender/TelnetAppenderTest.cs | 4 +- src/log4net/Appender/AppenderSkeleton.cs | 4 +- src/log4net/Appender/Internal/IUdpConnection.cs | 51 +++++++++++ src/log4net/Appender/Internal/UdpConnection.cs | 58 ++++++++++++ src/log4net/Appender/RemoteSyslogAppender.cs | 102 ++++++++++----------- src/log4net/Appender/UdpAppender.cs | 43 +++------ src/log4net/Core/ErrorCode.cs | 2 +- src/log4net/Core/LoggerManager.cs | 2 +- src/log4net/Core/LoggingEvent.cs | 15 ++- src/log4net/log4net.csproj | 4 +- 12 files changed, 321 insertions(+), 99 deletions(-) diff --git a/src/log4net.Tests/Appender/Internal/UdpMock.cs b/src/log4net.Tests/Appender/Internal/UdpMock.cs new file mode 100644 index 00000000..152c625e --- /dev/null +++ b/src/log4net.Tests/Appender/Internal/UdpMock.cs @@ -0,0 +1,60 @@ +#region Apache License +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to you under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#endregion + +using System.Collections.Generic; +using System.Net; +using System.Threading.Tasks; +using log4net.Appender.Internal; + +namespace log4net.Tests.Appender.Internal; + +/// <summary> +/// Mock implementation of <see cref="IUdpConnection"/> for testing purposes. +/// </summary> +internal sealed class UdpMock : IUdpConnection +{ + /// <summary> + /// Passed to <see cref="SendAsync(byte[], int)"/> + /// </summary> + public List<(byte[] Datagram, int Bytes)> Sent { get; } = []; + + /// <summary> + /// Was <see cref="Dispose"/> called + /// </summary> + internal bool WasDisposed { get; private set; } + + /// <summary> + /// Parameters passed to <see cref="Connect(int, IPAddress, int)"/> + /// </summary> + internal (int LocalPort, IPAddress Host, int RemotePort)? ConnectedTo { get; private set; } + + /// <inheritdoc/> + public void Connect(int localPort, IPAddress host, int remotePort) + => ConnectedTo = (localPort, host, remotePort); + + /// <inheritdoc/> + public void Dispose() => WasDisposed = true; + + /// <inheritdoc/> + public Task<int> SendAsync(byte[] datagram, int bytes) + { + Sent.Add((datagram, bytes)); + return Task.FromResult(bytes); + } +} \ No newline at end of file diff --git a/src/log4net.Tests/Appender/RemoteSyslogAppenderTest.cs b/src/log4net.Tests/Appender/RemoteSyslogAppenderTest.cs new file mode 100644 index 00000000..bc5ea526 --- /dev/null +++ b/src/log4net.Tests/Appender/RemoteSyslogAppenderTest.cs @@ -0,0 +1,75 @@ +#region Apache License +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to you under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#endregion + +using System.Text; +using log4net.Appender; +using log4net.Appender.Internal; +using log4net.Core; +using log4net.Layout; +using log4net.Tests.Appender.Internal; +using NUnit.Framework; + +namespace log4net.Tests.Appender; + +/// <summary> +/// Tests for <see cref="RemoteSyslogAppender"/> +/// </summary> +[TestFixture] +public sealed class RemoteSyslogAppenderTest +{ + private sealed class RemoteAppender : RemoteSyslogAppender + { + /// <summary> + /// Mock + /// </summary> + internal UdpMock Mock { get; } = new(); + + /// <inheritdoc/> + protected override IUdpConnection CreateUdpConnection() => Mock; + } + + /// <summary> + /// Simple Test for the <see cref="RemoteSyslogAppenderTest"/> + /// </summary> + /// <remarks> + /// https://github.com/apache/logging-log4net/issues/255 + /// </remarks> + [Test] + public void RemoteSyslogTest() + { + System.Net.IPAddress ipAddress = new([127, 0, 0, 1]); + RemoteAppender appender = new() { RemoteAddress = ipAddress, Layout = new PatternLayout("%-5level - %message%newline") }; + appender.ActivateOptions(); + LoggingEvent loggingEvent = new(new() + { + Level = Level.Info, + Message = "Test message", + LoggerName = "TestLogger", + Domain = "TestDomain", + }); + appender.DoAppend(loggingEvent); + appender.Close(); + Assert.That(appender.Mock.ConnectedTo, Is.EqualTo((0, ipAddress, 514))); + Assert.That(appender.Mock.Sent, Has.Count.EqualTo(1)); + Assert.That(appender.Mock.WasDisposed, Is.True); + Assert.That(appender.Mock.Sent, Has.Count.EqualTo(1)); + const string expectedData = @"<14>TestDomain: INFO - Test message"; + Assert.That(Encoding.ASCII.GetString(appender.Mock.Sent[0].Datagram), Is.EqualTo(expectedData)); + } +} \ No newline at end of file diff --git a/src/log4net.Tests/Appender/TelnetAppenderTest.cs b/src/log4net.Tests/Appender/TelnetAppenderTest.cs index 0e8d5f84..ea153e76 100644 --- a/src/log4net.Tests/Appender/TelnetAppenderTest.cs +++ b/src/log4net.Tests/Appender/TelnetAppenderTest.cs @@ -1,4 +1,4 @@ -#region Apache License +#region Apache License // // Licensed to the Apache Software Foundation (ASF) under one or more // contributor license agreements. See the NOTICE file distributed with @@ -37,7 +37,7 @@ namespace log4net.Tests.Appender; public sealed class TelnetAppenderTest { /// <summary> - /// Simple Test für the <see cref="TelnetAppender"/> + /// Simple Test for the <see cref="TelnetAppender"/> /// </summary> /// <remarks> /// https://github.com/apache/logging-log4net/issues/194 diff --git a/src/log4net/Appender/AppenderSkeleton.cs b/src/log4net/Appender/AppenderSkeleton.cs index 216e4ec0..474bac42 100644 --- a/src/log4net/Appender/AppenderSkeleton.cs +++ b/src/log4net/Appender/AppenderSkeleton.cs @@ -353,7 +353,7 @@ public void DoAppend(LoggingEvent[] loggingEvents) { _recursiveGuard = true; - var filteredEvents = new List<LoggingEvent>(loggingEvents.Length); + List<LoggingEvent> filteredEvents = new(loggingEvents.Length); foreach (LoggingEvent loggingEvent in loggingEvents) { @@ -628,7 +628,7 @@ protected string RenderLoggingEvent(LoggingEvent loggingEvent) lock (LockObj) { // Create the render writer on first use - _renderWriter ??= new ReusableStringWriter(System.Globalization.CultureInfo.InvariantCulture); + _renderWriter ??= new(System.Globalization.CultureInfo.InvariantCulture); // Reset the writer so we can reuse it _renderWriter.Reset(RenderBufferMaxCapacity, RenderBufferSize); diff --git a/src/log4net/Appender/Internal/IUdpConnection.cs b/src/log4net/Appender/Internal/IUdpConnection.cs new file mode 100644 index 00000000..cf0dd2c3 --- /dev/null +++ b/src/log4net/Appender/Internal/IUdpConnection.cs @@ -0,0 +1,51 @@ +#region Apache License +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to you under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#endregion + +using System; +using System.ComponentModel; +using System.Net; +using System.Threading.Tasks; + +namespace log4net.Appender.Internal; + +/// <summary> +/// Interface for UDP connection management. +/// Only public for unit testing purposes. +/// Do not use outside of log4net. +/// Signatures may change without notice. +/// </summary> +[EditorBrowsable(EditorBrowsableState.Never)] +public interface IUdpConnection : IDisposable +{ + /// <summary> + /// Establishes a default remote host using the specified host name and port number. + /// </summary> + /// <param name="localPort">The local port number</param> + /// <param name="host">The remote host to which you intend send data.</param> + /// <param name="remotePort">The port number on the remote host to which you intend to send data.</param> + void Connect(int localPort, IPAddress host, int remotePort); + + /// <summary> + /// Sends a UDP datagram asynchronously to a remote host. + /// </summary> + /// <param name="datagram">An array of type System.Byte that specifies the UDP datagram that you intend to send represented as an array of bytes.</param> + /// <param name="bytes">The number of bytes in the datagram.</param> + /// <returns>Task for Completion</returns> + Task<int> SendAsync(byte[] datagram, int bytes); +} \ No newline at end of file diff --git a/src/log4net/Appender/Internal/UdpConnection.cs b/src/log4net/Appender/Internal/UdpConnection.cs new file mode 100644 index 00000000..d39cd536 --- /dev/null +++ b/src/log4net/Appender/Internal/UdpConnection.cs @@ -0,0 +1,58 @@ +#region Apache License +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to you under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#endregion + +using System.Net; +using System.Net.Sockets; +using System.Threading.Tasks; +using log4net.Util; + +namespace log4net.Appender.Internal; + +/// <summary> +/// Wrapper for <see cref="UdpClient"/> to manage UDP connections. +/// </summary> +internal sealed class UdpConnection : IUdpConnection +{ + private UdpClient? _client; + + private UdpClient Client + => _client.EnsureNotNull(errorMessage: "Client is not initialized. Call Connect first."); + + /// <inheritdoc/> + public void Connect(int localPort, IPAddress remoteAddress, int remotePort) + { + _client = CreateClient(localPort, remoteAddress); + Client.Connect(remoteAddress, remotePort); + } + + /// <inheritdoc/> + public Task<int> SendAsync(byte[] datagram, int bytes) => Client.SendAsync(datagram, bytes); + + /// <inheritdoc/> + public void Dispose() => _client?.Dispose(); + + /// <summary> + /// Creates a new <see cref="UdpClient"/> instance configured with the specified local port and remote address. + /// </summary> + /// <returns>A <see cref="UdpClient"/> instance configured with the specified parameters.</returns> + internal static UdpClient CreateClient(int localPort, System.Net.IPAddress remoteAddress) + => localPort == 0 + ? new (remoteAddress.AddressFamily) + : new (localPort, remoteAddress.AddressFamily); +} \ No newline at end of file diff --git a/src/log4net/Appender/RemoteSyslogAppender.cs b/src/log4net/Appender/RemoteSyslogAppender.cs index 95a79a56..f9f46f76 100644 --- a/src/log4net/Appender/RemoteSyslogAppender.cs +++ b/src/log4net/Appender/RemoteSyslogAppender.cs @@ -18,15 +18,14 @@ #endregion using System; - -using log4net.Core; -using log4net.Util; -using log4net.Layout; +using System.Collections.Concurrent; using System.Text; -using System.Net.Sockets; -using System.Threading.Tasks; using System.Threading; -using System.Collections.Concurrent; +using System.Threading.Tasks; +using log4net.Appender.Internal; +using log4net.Core; +using log4net.Layout; +using log4net.Util; namespace log4net.Appender; @@ -260,9 +259,9 @@ public enum SyslogFacility } private readonly BlockingCollection<byte[]> _sendQueue = new(); - private CancellationTokenSource? _cts; + private CancellationTokenSource? _cancellationTokenSource; private Task? _pumpTask; - + /// <summary> /// Initializes a new instance of the <see cref="RemoteSyslogAppender" /> class. /// </summary> @@ -301,6 +300,11 @@ public RemoteSyslogAppender() /// </remarks> public SyslogFacility Facility { get; set; } = SyslogFacility.User; + /// <summary> + /// Gets or sets the delegate used to create instances of <see cref="IUdpConnection"/>. + /// </summary> + protected virtual IUdpConnection CreateUdpConnection() => new UdpConnection(); + /// <summary> /// Add a mapping of level to severity /// </summary> @@ -326,15 +330,6 @@ public RemoteSyslogAppender() /// </remarks> protected override void Append(LoggingEvent loggingEvent) { - if (Client is null) - { - ErrorHandler.Error( - $"Unable to send logging event to remote syslog {RemoteAddress} on port {RemotePort}, no client created", - e: null, - ErrorCode.WriteFailure); - return; - } - loggingEvent.EnsureNotNull(); try { @@ -342,22 +337,14 @@ protected override void Append(LoggingEvent loggingEvent) int priority = GeneratePriority(Facility, GetSeverity(loggingEvent.Level)); // Identity - string? identity; - if (Identity is not null) - { - identity = Identity.Format(loggingEvent); - } - else - { - identity = loggingEvent.Domain; - } + string? identity = Identity?.Format(loggingEvent) ?? loggingEvent.Domain; // Message. The message goes after the tag/identity string message = RenderLoggingEvent(loggingEvent); int i = 0; - var builder = new StringBuilder(); + StringBuilder builder = new(); while (i < message.Length) { @@ -375,14 +362,13 @@ protected override void Append(LoggingEvent loggingEvent) // Grab as a byte array byte[] buffer = Encoding.GetBytes(builder.ToString()); - //Client.SendAsync(buffer, buffer.Length, RemoteEndPoint).Wait(); _sendQueue.Add(buffer); } } catch (Exception e) when (!e.IsFatal()) { ErrorHandler.Error( - $"Unable to send logging event to remote syslog {RemoteAddress} on port {RemotePort}.", + $"Unable to enqueue logging event to remote syslog {RemoteAddress} on port {RemotePort}.", e, ErrorCode.WriteFailure); } } @@ -434,10 +420,11 @@ public override void ActivateOptions() base.ActivateOptions(); _levelMapping.ActivateOptions(); // Start the background pump - _cts = new CancellationTokenSource(); - _pumpTask = Task.Run(() => ProcessQueueAsync(_cts.Token), CancellationToken.None); + _cancellationTokenSource = new(); + _pumpTask = Task.Factory.StartNew(() => ProcessQueueAsync(_cancellationTokenSource.Token), CancellationToken.None, + TaskCreationOptions.LongRunning, TaskScheduler.Default); } - + /// <summary> /// Translates a log4net level to a syslog severity. /// </summary> @@ -544,44 +531,49 @@ public class LevelSeverity : LevelMappingEntry public SyslogSeverity Severity { get; set; } } + /// <inheritdoc/> protected override void OnClose() { // Signal shutdown and wait for the pump to drain - _cts?.Cancel(); - _pumpTask?.Wait(TimeSpan.FromSeconds(5)); // or your own timeout + _cancellationTokenSource?.Cancel(); + _pumpTask?.Wait(TimeSpan.FromSeconds(5)); base.OnClose(); } private async Task ProcessQueueAsync(CancellationToken token) { // We create our own UdpClient here, so that client lifetime is tied to this task - using (var udp = new UdpClient()) - { - udp.Connect(RemoteAddress?.ToString(), RemotePort); + using IUdpConnection udpClient = CreateUdpConnection(); + udpClient.Connect(LocalPort, RemoteAddress.EnsureNotNull(), RemotePort); - try + try + { + while (!token.IsCancellationRequested) { - while (!token.IsCancellationRequested) + // Take next message or throw when cancelled + byte[] datagram = _sendQueue.Take(token); + try + { + await udpClient.SendAsync(datagram, datagram.Length).ConfigureAwait(false); + } + catch (Exception ex) when (!ex.IsFatal()) { - // Take next message or throw when cancelled - byte[] datagram = _sendQueue.Take(token); - try - { - await udp.SendAsync(datagram, datagram.Length); - } - catch (Exception ex) when (!ex.IsFatal()) - { - ErrorHandler.Error("RemoteSyslogAppender: send failed", ex, ErrorCode.WriteFailure); - } + ErrorHandler.Error("RemoteSyslogAppender: send failed", ex, ErrorCode.WriteFailure); } } - catch (OperationCanceledException) + } + catch (OperationCanceledException) + { + // Clean shutdown: drain remaining items if desired + while (_sendQueue.TryTake(out byte[]? leftover)) { - // Clean shutdown: drain remaining items if desired - while (_sendQueue.TryTake(out var leftover)) + try + { + await udpClient.SendAsync(leftover, leftover.Length).ConfigureAwait(false); + } + catch (Exception ex) when (!ex.IsFatal()) { - try { await udp.SendAsync(leftover, leftover.Length); } - catch { /* ignore */ } + ErrorHandler.Error("RemoteSyslogAppender: send failed during shutdown", ex, ErrorCode.FlushFailure); } } } diff --git a/src/log4net/Appender/UdpAppender.cs b/src/log4net/Appender/UdpAppender.cs index cf4f03f9..2e0dc957 100644 --- a/src/log4net/Appender/UdpAppender.cs +++ b/src/log4net/Appender/UdpAppender.cs @@ -21,7 +21,7 @@ using System.Net; using System.Net.Sockets; using System.Text; - +using log4net.Appender.Internal; using log4net.Core; using log4net.Util; @@ -206,13 +206,10 @@ public int RemotePort { if (value is < IPEndPoint.MinPort or > IPEndPoint.MaxPort) { - throw Util.SystemInfo.CreateArgumentOutOfRangeException(nameof(value), value, + throw SystemInfo.CreateArgumentOutOfRangeException(nameof(value), value, $"The value specified is less than {IPEndPoint.MinPort} or greater than {IPEndPoint.MaxPort}."); } - else - { - _remotePort = value; - } + _remotePort = value; } } @@ -240,13 +237,10 @@ public int LocalPort { if (value is not 0 and (< IPEndPoint.MinPort or > IPEndPoint.MaxPort)) { - throw Util.SystemInfo.CreateArgumentOutOfRangeException(nameof(value), value, + throw SystemInfo.CreateArgumentOutOfRangeException(nameof(value), value, $"The value specified is less than {IPEndPoint.MinPort} or greater than {IPEndPoint.MaxPort}."); } - else - { - _localPort = value; - } + _localPort = value; } } @@ -270,7 +264,7 @@ public int LocalPort /// The underlying <see cref="UdpClient" />. /// </value> /// <remarks> - /// <see cref="UdpAppender" /> creates a <see cref="UdpClient" /> to send logging events + /// <see cref="UdpAppender" /> creates a <see cref="UdpClient" /> to send logging events /// over a network. Classes deriving from <see cref="UdpAppender" /> can use this /// property to get or set this <see cref="UdpClient" />. Use the underlying <see cref="UdpClient" /> /// returned from <see cref="Client" /> if you require access beyond that which @@ -282,7 +276,7 @@ public int LocalPort /// Gets or sets the cached remote endpoint to which the logging events should be sent. /// </summary> /// <remarks> - /// The <see cref="ActivateOptions" /> method will initialize the remote endpoint + /// The <see cref="ActivateOptions" /> method will initialize the remote endpoint /// with the values of the <see cref="RemoteAddress" /> and <see cref="RemotePort"/> /// properties. /// </remarks> @@ -294,13 +288,13 @@ public int LocalPort /// <remarks> /// <para> /// This is part of the <see cref="IOptionHandler"/> delayed object - /// activation scheme. The <see cref="ActivateOptions"/> method must + /// activation scheme. The <see cref="ActivateOptions"/> method must /// be called on this object after the configuration properties have /// been set. Until <see cref="ActivateOptions"/> is called this - /// object is in an undefined state and must not be used. + /// object is in an undefined state and must not be used. /// </para> /// <para> - /// If any of the configuration properties are modified then + /// If any of the configuration properties are modified then /// <see cref="ActivateOptions"/> must be called again. /// </para> /// <para> @@ -371,7 +365,7 @@ protected override void Append(LoggingEvent loggingEvent) protected override bool RequiresLayout => true; /// <summary> - /// Closes the UDP connection and releases all resources associated with + /// Closes the UDP connection and releases all resources associated with /// this <see cref="UdpAppender" /> instance. /// </summary> /// <remarks> @@ -392,7 +386,7 @@ protected override void OnClose() /// </summary> /// <remarks> /// <para> - /// The underlying <see cref="UdpClient"/> is initialized and binds to the + /// The underlying <see cref="UdpClient"/> is initialized and binds to the /// port number from which you intend to communicate. /// </para> /// <para> @@ -403,14 +397,7 @@ protected virtual void InitializeClientConnection() { try { - if (LocalPort == 0) - { - Client = new(RemoteAddress!.AddressFamily); - } - else - { - Client = new(LocalPort, RemoteAddress!.AddressFamily); - } + Client = UdpConnection.CreateClient(LocalPort, RemoteAddress.EnsureNotNull()); } catch (Exception e) when (!e.IsFatal()) { @@ -423,7 +410,7 @@ protected virtual void InitializeClientConnection() } /// <summary> - /// The TCP port number of the remote host or multicast group to + /// The TCP port number of the remote host or multicast group to /// which the logging event will be sent. /// </summary> private int _remotePort; @@ -432,4 +419,4 @@ protected virtual void InitializeClientConnection() /// The TCP port number from which the <see cref="UdpClient" /> will communicate. /// </summary> private int _localPort; -} +} \ No newline at end of file diff --git a/src/log4net/Core/ErrorCode.cs b/src/log4net/Core/ErrorCode.cs index c936b64e..5faf0921 100644 --- a/src/log4net/Core/ErrorCode.cs +++ b/src/log4net/Core/ErrorCode.cs @@ -66,4 +66,4 @@ public enum ErrorCode : int /// Failed to parse address /// </summary> AddressParseFailure -} +} \ No newline at end of file diff --git a/src/log4net/Core/LoggerManager.cs b/src/log4net/Core/LoggerManager.cs index 212e66f8..ab6fb89b 100644 --- a/src/log4net/Core/LoggerManager.cs +++ b/src/log4net/Core/LoggerManager.cs @@ -527,7 +527,7 @@ public static ILoggerRepository CreateRepository(Assembly repositoryAssembly, Ty /// <returns>A string of version info.</returns> private static string GetVersionInfo() { - var sb = new StringBuilder(); + StringBuilder sb = new(); Assembly myAssembly = Assembly.GetExecutingAssembly(); sb.Append("log4net assembly [").Append(myAssembly.FullName).Append("]. "); diff --git a/src/log4net/Core/LoggingEvent.cs b/src/log4net/Core/LoggingEvent.cs index 20e7892c..cdc13465 100644 --- a/src/log4net/Core/LoggingEvent.cs +++ b/src/log4net/Core/LoggingEvent.cs @@ -803,7 +803,7 @@ private static string ReviseThreadName(string? threadName) return null; } #endif - using var identity = WindowsIdentity.GetCurrent(); + using WindowsIdentity identity = WindowsIdentity.GetCurrent(); return identity?.Name ?? string.Empty; } @@ -1140,14 +1140,13 @@ protected virtual void FixVolatileData(FixFlags flags) private void CreateCompositeProperties() { - var compositeProperties = new CompositeProperties(); + CompositeProperties compositeProperties = new(); if (_eventProperties is not null) { compositeProperties.Add(_eventProperties); } - var logicalThreadProperties = LogicalThreadContext.Properties.GetProperties(false); - if (logicalThreadProperties is not null) + if (LogicalThreadContext.Properties.GetProperties(false) is PropertiesDictionary logicalThreadProperties) { compositeProperties.Add(logicalThreadProperties); } @@ -1163,7 +1162,7 @@ private void CreateCompositeProperties() bool shouldFixIdentity = (_fixFlags & FixFlags.Identity) != 0; if (shouldFixIdentity || shouldFixUserName) { - var eventProperties = new PropertiesDictionary(); + PropertiesDictionary eventProperties = new(); if (shouldFixUserName) { eventProperties[UserNameProperty] = UserName; @@ -1178,7 +1177,7 @@ private void CreateCompositeProperties() } compositeProperties.Add(GlobalContext.Properties.GetReadOnlyProperties()); - this._compositeProperties = compositeProperties; + _compositeProperties = compositeProperties; } private void CacheProperties() @@ -1190,9 +1189,9 @@ private void CacheProperties() CreateCompositeProperties(); } - var flattenedProperties = _compositeProperties!.Flatten(); + PropertiesDictionary flattenedProperties = _compositeProperties!.Flatten(); - var fixedProperties = new PropertiesDictionary(); + PropertiesDictionary fixedProperties = new(); // Validate properties foreach (KeyValuePair<string, object?> entry in flattenedProperties) diff --git a/src/log4net/log4net.csproj b/src/log4net/log4net.csproj index e6d6d105..6a16ea0b 100644 --- a/src/log4net/log4net.csproj +++ b/src/log4net/log4net.csproj @@ -107,8 +107,8 @@ log4net is designed with two distinct goals in mind: speed and flexibility <!-- "Workaround" for missing '.pdb'-Files from NuGet Packages --> <!-- https://github.com/dotnet/sdk/issues/1458#issuecomment-420456386 --> <ItemGroup> - <ReferenceCopyLocalPaths Include="@(ReferenceCopyLocalPaths->'%(RootDir)%(Directory)%(Filename).pdb')" Condition="'%(ReferenceCopyLocalPaths.NuGetPackageId)' != '' and Exists('%(RootDir)%(Directory)%(Filename).pdb')" /> - <ReferenceCopyLocalPaths Include="@(ReferenceCopyLocalPaths->'%(RootDir)%(Directory)%(Filename).xml')" Condition="'%(ReferenceCopyLocalPaths.NuGetPackageId)' != '' and Exists('%(RootDir)%(Directory)%(Filename).xml')" /> + <ReferenceCopyLocalPaths Include="@(ReferenceCopyLocalPaths->'%(RootDir)%(Directory)%(Filename).pdb')" Condition="'%(ReferenceCopyLocalPaths.NuGetPackageId)' != '' and Exists('%(RootDir)%(Directory)%(Filename).pdb')" /> + <ReferenceCopyLocalPaths Include="@(ReferenceCopyLocalPaths->'%(RootDir)%(Directory)%(Filename).xml')" Condition="'%(ReferenceCopyLocalPaths.NuGetPackageId)' != '' and Exists('%(RootDir)%(Directory)%(Filename).xml')" /> </ItemGroup> </Target> </Project> \ No newline at end of file
