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 a7abf189a982e8d172aabbc63976f6e5178894b5
Author: Jan Friedrich <freeand...@apache.org>
AuthorDate: Thu Jun 19 15:10:06 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