This is an automated email from the ASF dual-hosted git repository.
freeandnil pushed a commit to branch Feature/ImprovementRemoteSyslogApp
in repository https://gitbox.apache.org/repos/asf/logging-log4net.git
The following commit(s) were added to
refs/heads/Feature/ImprovementRemoteSyslogApp by this push:
new ed3ed52d Asynchronous Sending for RemoteSyslogAppender in log4net
(#253)
ed3ed52d is described below
commit ed3ed52d82f05d4593a3999936c2f1dce6c44b5f
Author: yogitasingh001 <[email protected]>
AuthorDate: Thu Jun 12 02:02:00 2025 +0530
Asynchronous Sending for RemoteSyslogAppender in log4net (#253)
Co-authored-by: yogita singh <[email protected]>
---
...nousSendingforRemoteSyslogAppenderinlog4net.pdf | Bin 0 -> 322016 bytes
src/log4net/Appender/RemoteSyslogAppender.cs | 70 +++++++++++++++++++--
2 files changed, 64 insertions(+), 6 deletions(-)
diff --git a/docs/AsynchronousSendingforRemoteSyslogAppenderinlog4net.pdf
b/docs/AsynchronousSendingforRemoteSyslogAppenderinlog4net.pdf
new file mode 100644
index 00000000..b69445fa
Binary files /dev/null and
b/docs/AsynchronousSendingforRemoteSyslogAppenderinlog4net.pdf differ
diff --git a/src/log4net/Appender/RemoteSyslogAppender.cs
b/src/log4net/Appender/RemoteSyslogAppender.cs
index a111200e..6444155d 100644
--- a/src/log4net/Appender/RemoteSyslogAppender.cs
+++ b/src/log4net/Appender/RemoteSyslogAppender.cs
@@ -23,6 +23,10 @@
using log4net.Util;
using log4net.Layout;
using System.Text;
+using System.Net.Sockets;
+using System.Threading.Tasks;
+using System.Threading;
+using System.Collections.Concurrent;
namespace log4net.Appender;
@@ -367,7 +371,8 @@ protected override void Append(LoggingEvent loggingEvent)
// Grab as a byte array
byte[] buffer = Encoding.GetBytes(builder.ToString());
- Client.SendAsync(buffer, buffer.Length, RemoteEndPoint).Wait();
+ //Client.SendAsync(buffer, buffer.Length, RemoteEndPoint).Wait();
+ _sendQueue.Add(buffer);
}
}
catch (Exception e) when (!e.IsFatal())
@@ -420,11 +425,11 @@ protected virtual void AppendMessage(string message, ref
int characterIndex, Str
/// Initialize the level to syslog severity mappings set on this appender.
/// </para>
/// </remarks>
- public override void ActivateOptions()
- {
- base.ActivateOptions();
- _levelMapping.ActivateOptions();
- }
+ //public override void ActivateOptions()
+ //{
+ // base.ActivateOptions();
+ // _levelMapping.ActivateOptions();
+ //}
/// <summary>
/// Translates a log4net level to a syslog severity.
@@ -531,4 +536,57 @@ public class LevelSeverity : LevelMappingEntry
/// </remarks>
public SyslogSeverity Severity { get; set; }
}
+ private readonly BlockingCollection<byte[]> _sendQueue = new();
+ private CancellationTokenSource? _cts;
+ private Task? _pumpTask;
+ public override void ActivateOptions()
+ {
+ base.ActivateOptions();
+ // Start the background pump
+ _cts = new CancellationTokenSource();
+ _pumpTask = Task.Run(() => ProcessQueueAsync(_cts.Token),
CancellationToken.None);
+ }
+
+ protected override void OnClose()
+ {
+ // Signal shutdown and wait for the pump to drain
+ _cts?.Cancel();
+ _pumpTask?.Wait(TimeSpan.FromSeconds(5)); // or your own timeout
+ 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);
+
+ try
+ {
+ while (!token.IsCancellationRequested)
+ {
+ // 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);
+ }
+ }
+ }
+ catch (OperationCanceledException)
+ {
+ // Clean shutdown: drain remaining items if desired
+ while (_sendQueue.TryTake(out var leftover))
+ {
+ try { await udp.SendAsync(leftover, leftover.Length); }
+ catch { /* ignore */ }
+ }
+ }
+ }
+ }
}
\ No newline at end of file