diff --git a/src/Serilog.Sinks.Udp/Sinks/Udp/Private/IUdpClient.cs b/src/Serilog.Sinks.Udp/Sinks/Udp/Private/IUdpClient.cs index dab9fed..2f2a509 100644 --- a/src/Serilog.Sinks.Udp/Sinks/Udp/Private/IUdpClient.cs +++ b/src/Serilog.Sinks.Udp/Sinks/Udp/Private/IUdpClient.cs @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +using System.Net; using System.Threading.Tasks; namespace Serilog.Sinks.Udp.Private @@ -21,6 +22,22 @@ namespace Serilog.Sinks.Udp.Private /// public interface IUdpClient { + /// + /// Sends a UDP datagram asynchronously to a remote host. + /// + /// + /// An array of type that specifies the UDP datagram that you intend to + /// send represented as an array of bytes. + /// + /// + /// The number of bytes in the datagram. + /// + /// + /// An that represents the host and port to which to send the datagram. + /// + /// + Task SendAsync(byte[] datagram, int bytes, IPEndPoint endPoint); + /// /// Sends a UDP datagram asynchronously to a remote host. /// diff --git a/src/Serilog.Sinks.Udp/Sinks/Udp/Private/RemoteEndPoint.cs b/src/Serilog.Sinks.Udp/Sinks/Udp/Private/RemoteEndPoint.cs new file mode 100644 index 0000000..2d20b73 --- /dev/null +++ b/src/Serilog.Sinks.Udp/Sinks/Udp/Private/RemoteEndPoint.cs @@ -0,0 +1,27 @@ +using System; +using System.Net; + +namespace Serilog.Sinks.Udp.Private +{ + internal class RemoteEndPoint + { + public RemoteEndPoint(string address, int port) + { + if (port < IPEndPoint.MinPort || port > IPEndPoint.MaxPort) throw new ArgumentOutOfRangeException(nameof(port)); + + Address = address ?? throw new ArgumentNullException(nameof(address)); + Port = port; + + if (IPAddress.TryParse(address, out var ipAddress)) + { + IPEndPoint = new IPEndPoint(ipAddress, port); + } + } + + public string Address { get; } + + public int Port { get; } + + public IPEndPoint IPEndPoint { get; } + } +} diff --git a/src/Serilog.Sinks.Udp/Sinks/Udp/Private/UdpClientWrapper.cs b/src/Serilog.Sinks.Udp/Sinks/Udp/Private/UdpClientWrapper.cs index daa8980..6f0fe84 100644 --- a/src/Serilog.Sinks.Udp/Sinks/Udp/Private/UdpClientWrapper.cs +++ b/src/Serilog.Sinks.Udp/Sinks/Udp/Private/UdpClientWrapper.cs @@ -32,6 +32,11 @@ public UdpClientWrapper(int localPort) : new UdpClient(localPort, AddressFamily.InterNetwork); } + public Task SendAsync(byte[] datagram, int bytes, IPEndPoint endPoint) + { + return client.SendAsync(datagram, bytes, endPoint); + } + public Task SendAsync(byte[] datagram, int bytes, string hostname, int port) { return client.SendAsync(datagram, bytes, hostname, port); diff --git a/src/Serilog.Sinks.Udp/Sinks/Udp/Private/UdpSink.cs b/src/Serilog.Sinks.Udp/Sinks/Udp/Private/UdpSink.cs index ff854aa..85d8cd8 100644 --- a/src/Serilog.Sinks.Udp/Sinks/Udp/Private/UdpSink.cs +++ b/src/Serilog.Sinks.Udp/Sinks/Udp/Private/UdpSink.cs @@ -15,7 +15,6 @@ using System; using System.Collections.Generic; using System.IO; -using System.Net; using System.Text; using System.Threading.Tasks; using Serilog.Debugging; @@ -31,8 +30,7 @@ namespace Serilog.Sinks.Udp.Private internal class UdpSink : PeriodicBatchingSink { private readonly IUdpClient client; - private readonly string remoteAddress; - private readonly int remotePort; + private readonly RemoteEndPoint remoteEndPoint; private readonly ITextFormatter formatter; public UdpSink( @@ -42,11 +40,8 @@ public UdpSink( ITextFormatter formatter) : base(1000, TimeSpan.FromSeconds(0.5)) { - if (remotePort < IPEndPoint.MinPort || remotePort > IPEndPoint.MaxPort) throw new ArgumentOutOfRangeException(nameof(remotePort)); - this.client = client ?? throw new ArgumentNullException(nameof(client)); - this.remoteAddress = remoteAddress ?? throw new ArgumentNullException(nameof(remoteAddress)); - this.remotePort = remotePort; + remoteEndPoint = new RemoteEndPoint(remoteAddress, remotePort); this.formatter = formatter ?? throw new ArgumentNullException(nameof(formatter)); } @@ -69,9 +64,18 @@ protected override async Task EmitBatchAsync(IEnumerable events) .Trim() .ToCharArray()); - await client - .SendAsync(buffer, buffer.Length, remoteAddress, remotePort) - .ConfigureAwait(false); + if (remoteEndPoint.IPEndPoint != null) + { + await client + .SendAsync(buffer, buffer.Length, remoteEndPoint.IPEndPoint) + .ConfigureAwait(false); + } + else + { + await client + .SendAsync(buffer, buffer.Length, remoteEndPoint.Address, remoteEndPoint.Port) + .ConfigureAwait(false); + } } } catch (Exception e) diff --git a/test/Serilog.Sinks.Udp.Tests/OutputTemplateGivenCodeConfigurationShould.cs b/test/Serilog.Sinks.Udp.Tests/OutputTemplateGivenCodeConfigurationShould.cs index f8fb026..aacdcdf 100644 --- a/test/Serilog.Sinks.Udp.Tests/OutputTemplateGivenCodeConfigurationShould.cs +++ b/test/Serilog.Sinks.Udp.Tests/OutputTemplateGivenCodeConfigurationShould.cs @@ -1,5 +1,4 @@ -using System.Net; -using Serilog.Core; +using Serilog.Core; using Serilog.Support; namespace Serilog @@ -10,7 +9,7 @@ public class OutputTemplateGivenCodeConfigurationShould : SinkFixture public OutputTemplateGivenCodeConfigurationShould() { - var remoteAddress = IPAddress.Loopback.ToString(); + var remoteAddress = "localhost"; var remotePort = 7071; RemoteAddress = remoteAddress; diff --git a/test/Serilog.Sinks.Udp.Tests/TextFormatterGivenCodeConfigurationShould.cs b/test/Serilog.Sinks.Udp.Tests/TextFormatterGivenCodeConfigurationShould.cs index 0b3f883..38100a7 100644 --- a/test/Serilog.Sinks.Udp.Tests/TextFormatterGivenCodeConfigurationShould.cs +++ b/test/Serilog.Sinks.Udp.Tests/TextFormatterGivenCodeConfigurationShould.cs @@ -1,5 +1,4 @@ -using System.Net; -using Serilog.Core; +using Serilog.Core; using Serilog.Support.TextFormatters; namespace Serilog @@ -8,7 +7,7 @@ public class TextFormatterGivenCodeConfigurationShould : SinkFixture { public TextFormatterGivenCodeConfigurationShould() { - var remoteAddress = IPAddress.Loopback.ToString(); + var remoteAddress = "localhost"; var remotePort = 7071; RemoteAddress = remoteAddress;