From 6fec234a318584502b2d091112c0ddf22bb97406 Mon Sep 17 00:00:00 2001 From: Nisheeth Barthwal Date: Thu, 6 Sep 2018 10:59:36 +0200 Subject: [PATCH] fix: resolve hostname Fixes issue where the hostname only resolves into an IP address when the sink is created. The very nature of hostnames is to provide a route to instances whose IP address may change, and these code changes allows for this situation. One limitation with the changes is that currently only IPv4 addresses are supported, but an upcoming PR will solve that issue. Closes #29 --- .gitignore | 3 + CHANGELOG.md | 8 +- serilog-sinks-udp.sln.DotSettings | 5 +- .../LoggerSinkConfigurationExtensions.cs | 171 +++++++++++++----- .../Serilog.Sinks.Udp.csproj | 8 +- .../Sinks/Udp/Private/IUdpClient.cs | 27 +-- .../Sinks/Udp/Private/StringExtensions.cs | 60 ------ .../Sinks/Udp/Private/UdpClientFactory.cs | 11 +- .../Sinks/Udp/Private/UdpClientWrapper.cs | 23 +-- .../Sinks/Udp/Private/UdpSink.cs | 57 ++---- .../TextFormatters/Log4netTextFormatter.cs | 2 +- .../CodeConfigurationTest.cs | 19 -- ...> OutputTemplateGivenAppSettingsShould.cs} | 23 +-- ...putTemplateGivenCodeConfigurationShould.cs | 32 ++++ .../Serilog.Sinks.Udp.Tests.csproj | 6 - test/Serilog.Sinks.Udp.Tests/SinkFixture.cs | 28 ++- .../Sinks/Udp/Private/StringExtensionsTest.cs | 52 ------ .../Sinks/Udp/Private/UdpClientMock.cs | 46 ----- ...terTest.cs => Log4jTextFormatterShould.cs} | 16 +- ...rTest.cs => Log4netTextFormatterShould.cs} | 26 +-- .../Support/Counter.cs | 3 +- .../Support/FormatProvider.cs | 12 ++ .../Support/TextFormatters/TextFormatter.cs | 12 ++ .../Support/UdpClientMock.cs | 36 ++++ ...=> TextFormatterGivenAppSettingsShould.cs} | 21 +-- ...xtFormatterGivenCodeConfigurationShould.cs | 30 +++ .../appsettings_output_template.json | 4 +- .../appsettings_text_formatter.json | 2 +- 28 files changed, 360 insertions(+), 383 deletions(-) delete mode 100644 src/Serilog.Sinks.Udp/Sinks/Udp/Private/StringExtensions.cs delete mode 100644 test/Serilog.Sinks.Udp.Tests/CodeConfigurationTest.cs rename test/Serilog.Sinks.Udp.Tests/{SettingsFileUsingOutputTemplateTest.cs => OutputTemplateGivenAppSettingsShould.cs} (53%) create mode 100644 test/Serilog.Sinks.Udp.Tests/OutputTemplateGivenCodeConfigurationShould.cs delete mode 100644 test/Serilog.Sinks.Udp.Tests/Sinks/Udp/Private/StringExtensionsTest.cs delete mode 100644 test/Serilog.Sinks.Udp.Tests/Sinks/Udp/Private/UdpClientMock.cs rename test/Serilog.Sinks.Udp.Tests/Sinks/Udp/TextFormatters/{Log4jTextFormatterTest.cs => Log4jTextFormatterShould.cs} (88%) rename test/Serilog.Sinks.Udp.Tests/Sinks/Udp/TextFormatters/{Log4netTextFormatterTest.cs => Log4netTextFormatterShould.cs} (89%) create mode 100644 test/Serilog.Sinks.Udp.Tests/Support/FormatProvider.cs create mode 100644 test/Serilog.Sinks.Udp.Tests/Support/TextFormatters/TextFormatter.cs create mode 100644 test/Serilog.Sinks.Udp.Tests/Support/UdpClientMock.cs rename test/Serilog.Sinks.Udp.Tests/{SettingsFileUsingTextFormatterTest.cs => TextFormatterGivenAppSettingsShould.cs} (53%) create mode 100644 test/Serilog.Sinks.Udp.Tests/TextFormatterGivenCodeConfigurationShould.cs diff --git a/.gitignore b/.gitignore index 94420dc..9121657 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,9 @@ bld/ # Uncomment if you have tasks that create the project's static files in wwwroot #wwwroot/ +# JetBrains config directory +.idea/ + # MSTest test Results [Tt]est[Rr]esult*/ [Bb]uild[Ll]og.* diff --git a/CHANGELOG.md b/CHANGELOG.md index 22b324a..70aea10 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ This project adheres to [Semantic Versioning](http://semver.org/) and is followi ## Unreleased +### :syringe: Fixed + +- [#29](https://github.com/FantasticFiasco/serilog-sinks-udp/issues/29) Fix remote hostname implementation bug (contribution by [Nisheeth Barthwal](https://github.com/nbaztec)) + ## [4.1.0] - 2018-06-06 ### :zap: Added @@ -32,13 +36,13 @@ This project adheres to [Semantic Versioning](http://semver.org/) and is followi ### :zap: Added -- Text formatter complient with log4net XML schema, thus compatible with [Log4View](http://www.log4view.com) (contribution by [jvanrhyn](https://github.com/jvanrhyn)) +- Text formatter compliant with log4net XML schema, thus compatible with [Log4View](http://www.log4view.com) (contribution by [jvanrhyn](https://github.com/jvanrhyn)) ## [3.2.0] - 2017-08-26 ### :zap: Added -- Text formatter complient with log4j XML schema, thus compatible with [Log2Console](https://github.com/Statyk7/log2console) +- Text formatter compliant with log4j XML schema, thus compatible with [Log2Console](https://github.com/Statyk7/log2console) ## [3.1.0] - 2017-08-20 diff --git a/serilog-sinks-udp.sln.DotSettings b/serilog-sinks-udp.sln.DotSettings index c09b201..2bf72ba 100644 --- a/serilog-sinks-udp.sln.DotSettings +++ b/serilog-sinks-udp.sln.DotSettings @@ -365,4 +365,7 @@ public void SetUp() 0 True 2.0 - InCSharpFile \ No newline at end of file + InCSharpFile + True + True + True \ No newline at end of file diff --git a/src/Serilog.Sinks.Udp/LoggerSinkConfigurationExtensions.cs b/src/Serilog.Sinks.Udp/LoggerSinkConfigurationExtensions.cs index 18bfe22..94f8e15 100644 --- a/src/Serilog.Sinks.Udp/LoggerSinkConfigurationExtensions.cs +++ b/src/Serilog.Sinks.Udp/LoggerSinkConfigurationExtensions.cs @@ -1,11 +1,11 @@ // Copyright 2015-2018 Serilog Contributors -// +// // Licensed 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. @@ -13,7 +13,6 @@ // limitations under the License. using System; -using System.ComponentModel; using System.Net; using Serilog.Configuration; using Serilog.Events; @@ -32,11 +31,45 @@ public static class LoggerSinkConfigurationExtensions { private const string DefaultOutputTemplate = "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level}] {Message}{NewLine}{Exception}"; + // NOTE: + // This overload that accepts the remote address as a string must come first in the + // class, otherwise Serilog.Settings.Configuration won't work. + /// - /// Extension method providing JSON support via - /// Serilog.Settings.Configuration. + /// Adds a sink that sends log events as UDP packages over the network. /// - [EditorBrowsable(EditorBrowsableState.Never)] + /// + /// Logger sink configuration. + /// + /// + /// The hostname of the remote host or multicast group to which the UDP client should sent + /// the logging event. + /// + /// + /// The TCP port of the remote host or multicast group to which the UDP client should sent + /// the logging event. + /// + /// + /// The TCP port from which the UDP client will communicate. The default is 0 and will + /// cause the UDP client not to bind to a local port. + /// + /// + /// The minimum level for events passed through the sink. The default is + /// . + /// + /// + /// A switch allowing the pass-through minimum level to be changed at runtime. + /// + /// + /// A message template describing the format used to write to the sink. The default is + /// "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level}] {Message}{NewLine}{Exception}". + /// + /// + /// Supplies culture-specific formatting information, or null. + /// + /// + /// Logger configuration, allowing configuration to continue. + /// public static LoggerConfiguration Udp( this LoggerSinkConfiguration sinkConfiguration, string remoteAddress, @@ -47,21 +80,27 @@ public static LoggerConfiguration Udp( string outputTemplate = DefaultOutputTemplate, IFormatProvider formatProvider = null) { + if (sinkConfiguration == null) throw new ArgumentNullException(nameof(sinkConfiguration)); + if (outputTemplate == null) throw new ArgumentNullException(nameof(outputTemplate)); + + var formatter = new MessageTemplateTextFormatter(outputTemplate, formatProvider); + return Udp( sinkConfiguration, - remoteAddress.ToIPAddress(), + remoteAddress, remotePort, + formatter, localPort, restrictedToMinimumLevel, - levelSwitch, - outputTemplate, - formatProvider); + levelSwitch); } /// /// Adds a sink that sends log events as UDP packages over the network. /// - /// Logger sink configuration. + /// + /// Logger sink configuration. + /// /// /// The of the remote host or multicast group to which the UDP /// client should sent the logging event. @@ -88,7 +127,9 @@ public static LoggerConfiguration Udp( /// /// Supplies culture-specific formatting information, or null. /// - /// Logger configuration, allowing configuration to continue. + /// + /// Logger configuration, allowing configuration to continue. + /// public static LoggerConfiguration Udp( this LoggerSinkConfiguration sinkConfiguration, IPAddress remoteAddress, @@ -99,27 +140,54 @@ public static LoggerConfiguration Udp( string outputTemplate = DefaultOutputTemplate, IFormatProvider formatProvider = null) { - if (sinkConfiguration == null) - throw new ArgumentNullException(nameof(sinkConfiguration)); - if (outputTemplate == null) - throw new ArgumentNullException(nameof(outputTemplate)); - - var formatter = new MessageTemplateTextFormatter(outputTemplate, formatProvider); return Udp( sinkConfiguration, - remoteAddress, + remoteAddress.ToString(), remotePort, - formatter, localPort, restrictedToMinimumLevel, - levelSwitch); + levelSwitch, + outputTemplate, + formatProvider + ); } + // NOTE: + // This overload that accepts the remote address as a string must come first in the + // class, otherwise Serilog.Settings.Configuration won't work. + /// - /// Extension method providing JSON support via - /// Serilog.Settings.Configuration. + /// Adds a sink that sends log events as UDP packages over the network. /// - [EditorBrowsable(EditorBrowsableState.Never)] + /// + /// Logger sink configuration. + /// + /// + /// The hostname of the remote host or multicast group to which the UDP client should sent + /// the logging event. + /// + /// + /// The TCP port of the remote host or multicast group to which the UDP client should sent + /// the logging event. + /// + /// + /// Controls the rendering of log events into text, for example to log JSON. To control + /// plain text formatting, use the overload that accepts an output template. + /// + /// + /// The TCP port from which the UDP client will communicate. The default is 0 and will + /// cause the UDP client not to bind to a local port. + /// + /// + /// The minimum level for events passed through the sink. The default is + /// . + /// + /// + /// A switch allowing the pass-through minimum level to be changed at runtime. + /// + /// + /// Logger configuration, allowing configuration to continue. + /// public static LoggerConfiguration Udp( this LoggerSinkConfiguration sinkConfiguration, string remoteAddress, @@ -129,20 +197,28 @@ public static LoggerConfiguration Udp( LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum, LoggingLevelSwitch levelSwitch = null) { - return Udp( - sinkConfiguration, - remoteAddress.ToIPAddress(), - remotePort, - formatter, - localPort, - restrictedToMinimumLevel, - levelSwitch); + if (sinkConfiguration == null) throw new ArgumentNullException(nameof(sinkConfiguration)); + + try + { + var client = UdpClientFactory.Create(localPort); + var sink = new UdpSink(client, remoteAddress, remotePort, formatter); + + return sinkConfiguration.Sink(sink, restrictedToMinimumLevel, levelSwitch); + } + catch (Exception e) + { + SelfLog.WriteLine("Unable to create UDP sink: {0}", e); + return sinkConfiguration.Sink(new NullSink(), LevelAlias.Maximum, null); + } } /// /// Adds a sink that sends log events as UDP packages over the network. /// - /// Logger sink configuration. + /// + /// Logger sink configuration. + /// /// /// The of the remote host or multicast group to which the UDP /// client should sent the logging event. @@ -166,7 +242,9 @@ public static LoggerConfiguration Udp( /// /// A switch allowing the pass-through minimum level to be changed at runtime. /// - /// Logger configuration, allowing configuration to continue. + /// + /// Logger configuration, allowing configuration to continue. + /// public static LoggerConfiguration Udp( this LoggerSinkConfiguration sinkConfiguration, IPAddress remoteAddress, @@ -176,20 +254,15 @@ public static LoggerConfiguration Udp( LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum, LoggingLevelSwitch levelSwitch = null) { - if (sinkConfiguration == null) - throw new ArgumentNullException(nameof(sinkConfiguration)); - - try - { - var client = UdpClientFactory.Create(localPort, remoteAddress); - var sink = new UdpSink(client, remoteAddress, remotePort, formatter); - return sinkConfiguration.Sink(sink, restrictedToMinimumLevel, levelSwitch); - } - catch (Exception e) - { - SelfLog.WriteLine("Unable to create UDP sink: {0}", e); - return sinkConfiguration.Sink(new NullSink(), LevelAlias.Maximum, null); - } + return Udp( + sinkConfiguration, + remoteAddress.ToString(), + remotePort, + formatter, + localPort, + restrictedToMinimumLevel, + levelSwitch + ); } } } \ No newline at end of file diff --git a/src/Serilog.Sinks.Udp/Serilog.Sinks.Udp.csproj b/src/Serilog.Sinks.Udp/Serilog.Sinks.Udp.csproj index 096c58d..c014aa8 100755 --- a/src/Serilog.Sinks.Udp/Serilog.Sinks.Udp.csproj +++ b/src/Serilog.Sinks.Udp/Serilog.Sinks.Udp.csproj @@ -1,5 +1,4 @@  - 4.1.0 Serilog.Sinks.Udp @@ -21,22 +20,17 @@ http://www.apache.org/licenses/LICENSE-2.0 For release notes, please see the change log on GitHub. - - - - $(DefineConstants);NET4 - - + \ No newline at end of file diff --git a/src/Serilog.Sinks.Udp/Sinks/Udp/Private/IUdpClient.cs b/src/Serilog.Sinks.Udp/Sinks/Udp/Private/IUdpClient.cs index d592a3a..dab9fed 100644 --- a/src/Serilog.Sinks.Udp/Sinks/Udp/Private/IUdpClient.cs +++ b/src/Serilog.Sinks.Udp/Sinks/Udp/Private/IUdpClient.cs @@ -1,18 +1,17 @@ // Copyright 2015-2018 Serilog Contributors -// +// // Licensed 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. -using System.Net; using System.Threading.Tasks; namespace Serilog.Sinks.Udp.Private @@ -25,17 +24,23 @@ public interface IUdpClient /// /// Sends a UDP datagram asynchronously to a remote host. /// - /// The datagram. + /// /// 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. + /// + /// The number of bytes in the datagram. /// - /// Returns . - Task SendAsync(byte[] datagram, int bytes, IPEndPoint endPoint); + /// + /// The name of the remote host to which you intend to send the datagram. + /// + /// + /// The remote port number with which you intend to communicate. + /// + /// + /// Returns . + /// + Task SendAsync(byte[] datagram, int bytes, string hostname, int port); #if NET4 /// diff --git a/src/Serilog.Sinks.Udp/Sinks/Udp/Private/StringExtensions.cs b/src/Serilog.Sinks.Udp/Sinks/Udp/Private/StringExtensions.cs deleted file mode 100644 index f8cbfe2..0000000 --- a/src/Serilog.Sinks.Udp/Sinks/Udp/Private/StringExtensions.cs +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2015-2018 Serilog Contributors -// -// Licensed 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. - -using System; -using System.Linq; -using System.Net; -using System.Net.Sockets; -using Serilog.Debugging; - -namespace Serilog.Sinks.Udp.Private -{ - /// - /// Class containing extensions methods to . - /// - public static class StringExtensions - { - /// - /// Converts specified address or hostname into an . - /// - /// The address to convert. - /// - /// An if address is found to be a valid IP address or DNS name; - /// otherwise null. - /// - public static IPAddress ToIPAddress(this string address) - { - if (IPAddress.TryParse(address, out var ipAddress)) - { - return ipAddress; - } - - try - { - // TODO: Use Dns.GetHostEntry when moving to .NET Standard 2.0 - var hostEntry = Dns.GetHostEntryAsync(address).Result; - - return hostEntry - .AddressList - .FirstOrDefault(a => a.AddressFamily == AddressFamily.InterNetwork); - } - catch (Exception e) - { - SelfLog.WriteLine("Unable to lookup hostname {0}: {1}", address, e); - } - - return null; - } - } -} diff --git a/src/Serilog.Sinks.Udp/Sinks/Udp/Private/UdpClientFactory.cs b/src/Serilog.Sinks.Udp/Sinks/Udp/Private/UdpClientFactory.cs index b600c1f..4dc156b 100644 --- a/src/Serilog.Sinks.Udp/Sinks/Udp/Private/UdpClientFactory.cs +++ b/src/Serilog.Sinks.Udp/Sinks/Udp/Private/UdpClientFactory.cs @@ -1,11 +1,11 @@ // Copyright 2015-2018 Serilog Contributors -// +// // Licensed 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. @@ -13,7 +13,6 @@ // limitations under the License. using System; -using System.Net; namespace Serilog.Sinks.Udp.Private { @@ -25,7 +24,7 @@ public static class UdpClientFactory /// /// Gets or sets the factory creating instances of . /// - public static Func Create { get; set; } - = (localPort, remoteAddress) => new UdpClientWrapper(localPort, remoteAddress); + public static Func Create { get; set; } + = localPort => new UdpClientWrapper(localPort); } } diff --git a/src/Serilog.Sinks.Udp/Sinks/Udp/Private/UdpClientWrapper.cs b/src/Serilog.Sinks.Udp/Sinks/Udp/Private/UdpClientWrapper.cs index 78aae3e..daa8980 100644 --- a/src/Serilog.Sinks.Udp/Sinks/Udp/Private/UdpClientWrapper.cs +++ b/src/Serilog.Sinks.Udp/Sinks/Udp/Private/UdpClientWrapper.cs @@ -1,11 +1,11 @@ // Copyright 2015-2018 Serilog Contributors -// +// // Licensed 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. @@ -23,23 +23,18 @@ internal class UdpClientWrapper : IUdpClient { private readonly UdpClient client; - public UdpClientWrapper( - int localPort, - IPAddress remoteAddress) + public UdpClientWrapper(int localPort) { - if (localPort < IPEndPoint.MinPort || localPort > IPEndPoint.MaxPort) - throw new ArgumentOutOfRangeException(nameof(localPort)); - if (remoteAddress == null) - throw new ArgumentNullException(nameof(remoteAddress)); + if (localPort < IPEndPoint.MinPort || localPort > IPEndPoint.MaxPort) throw new ArgumentOutOfRangeException(nameof(localPort)); client = localPort == 0 - ? new UdpClient(remoteAddress.AddressFamily) - : new UdpClient(localPort, remoteAddress.AddressFamily); + ? new UdpClient(AddressFamily.InterNetwork) + : new UdpClient(localPort, AddressFamily.InterNetwork); } - public Task SendAsync(byte[] datagram, int bytes, IPEndPoint endPoint) + public Task SendAsync(byte[] datagram, int bytes, string hostname, int port) { - return client.SendAsync(datagram, bytes, endPoint); + return client.SendAsync(datagram, bytes, hostname, port); } #if NET4 diff --git a/src/Serilog.Sinks.Udp/Sinks/Udp/Private/UdpSink.cs b/src/Serilog.Sinks.Udp/Sinks/Udp/Private/UdpSink.cs index 96ea21b..ff854aa 100644 --- a/src/Serilog.Sinks.Udp/Sinks/Udp/Private/UdpSink.cs +++ b/src/Serilog.Sinks.Udp/Sinks/Udp/Private/UdpSink.cs @@ -1,11 +1,11 @@ // Copyright 2015-2018 Serilog Contributors -// +// // Licensed 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. @@ -30,49 +30,29 @@ namespace Serilog.Sinks.Udp.Private /// internal class UdpSink : PeriodicBatchingSink { - private readonly IPEndPoint remoteEndPoint; + private readonly IUdpClient client; + private readonly string remoteAddress; + private readonly int remotePort; private readonly ITextFormatter formatter; - private IUdpClient client; - - /// - /// Construct a . - /// - /// - /// The UDP client responsible for sending multicast messages. - /// - /// - /// The of the remote host or multicast group to which the UDP - /// client should sent the logging event. - /// - /// - /// The TCP port of the remote host or multicast group to which the UDP client should sent - /// the logging event. - /// - /// Formatter used to convert log events to text. public UdpSink( IUdpClient client, - IPAddress remoteAddress, + string remoteAddress, int remotePort, ITextFormatter formatter) : base(1000, TimeSpan.FromSeconds(0.5)) { - if (remoteAddress == null) - throw new ArgumentNullException(nameof(remoteAddress)); - if (remotePort < IPEndPoint.MinPort || remotePort > IPEndPoint.MaxPort) - throw new ArgumentOutOfRangeException(nameof(remotePort)); + if (remotePort < IPEndPoint.MinPort || remotePort > IPEndPoint.MaxPort) throw new ArgumentOutOfRangeException(nameof(remotePort)); - remoteEndPoint = new IPEndPoint(remoteAddress, remotePort); - this.formatter = formatter ?? throw new ArgumentNullException(nameof(formatter)); this.client = client ?? throw new ArgumentNullException(nameof(client)); + this.remoteAddress = remoteAddress ?? throw new ArgumentNullException(nameof(remoteAddress)); + this.remotePort = remotePort; + this.formatter = formatter ?? throw new ArgumentNullException(nameof(formatter)); } #region PeriodicBatchingSink Members - /// - /// Emit a batch of log events, running asynchronously. - /// - /// The events to emit. + /// protected override async Task EmitBatchAsync(IEnumerable events) { foreach (LogEvent logEvent in events) @@ -90,7 +70,7 @@ protected override async Task EmitBatchAsync(IEnumerable events) .ToCharArray()); await client - .SendAsync(buffer, buffer.Length, remoteEndPoint) + .SendAsync(buffer, buffer.Length, remoteAddress, remotePort) .ConfigureAwait(false); } } @@ -101,13 +81,7 @@ await client } } - /// - /// Free resources held by the sink. - /// - /// - /// If true, called because the object is being disposed; if false, the object is being - /// disposed from the finalizer. - /// + /// protected override void Dispose(bool disposing) { base.Dispose(disposing); @@ -121,10 +95,7 @@ protected override void Dispose(bool disposing) client?.Close(); #else client?.Dispose(); - #endif - client = null; - } } diff --git a/src/Serilog.Sinks.Udp/Sinks/Udp/TextFormatters/Log4netTextFormatter.cs b/src/Serilog.Sinks.Udp/Sinks/Udp/TextFormatters/Log4netTextFormatter.cs index d509e21..4dff36a 100644 --- a/src/Serilog.Sinks.Udp/Sinks/Udp/TextFormatters/Log4netTextFormatter.cs +++ b/src/Serilog.Sinks.Udp/Sinks/Udp/TextFormatters/Log4netTextFormatter.cs @@ -19,7 +19,7 @@ namespace Serilog.Sinks.Udp.TextFormatters { /// - /// Text formatter serializing log events into log4net complient XML. + /// Text formatter serializing log events into log4net compliant XML. /// public class Log4netTextFormatter : ITextFormatter { diff --git a/test/Serilog.Sinks.Udp.Tests/CodeConfigurationTest.cs b/test/Serilog.Sinks.Udp.Tests/CodeConfigurationTest.cs deleted file mode 100644 index 2067c8b..0000000 --- a/test/Serilog.Sinks.Udp.Tests/CodeConfigurationTest.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.Net; - -namespace Serilog -{ - public class CodeConfigurationTest : SinkFixture - { - public CodeConfigurationTest() - { - RemoteAddress = IPAddress.Loopback; - RemotePort = 7071; - - Logger = new LoggerConfiguration() - .MinimumLevel.Verbose() - .WriteTo - .Udp(RemoteAddress, RemotePort) - .CreateLogger(); - } - } -} diff --git a/test/Serilog.Sinks.Udp.Tests/SettingsFileUsingOutputTemplateTest.cs b/test/Serilog.Sinks.Udp.Tests/OutputTemplateGivenAppSettingsShould.cs similarity index 53% rename from test/Serilog.Sinks.Udp.Tests/SettingsFileUsingOutputTemplateTest.cs rename to test/Serilog.Sinks.Udp.Tests/OutputTemplateGivenAppSettingsShould.cs index 494cb81..c849add 100644 --- a/test/Serilog.Sinks.Udp.Tests/SettingsFileUsingOutputTemplateTest.cs +++ b/test/Serilog.Sinks.Udp.Tests/OutputTemplateGivenAppSettingsShould.cs @@ -1,18 +1,17 @@ -using System.Globalization; -using Microsoft.Extensions.Configuration; -using Serilog.Sinks.Udp.Private; +using Microsoft.Extensions.Configuration; +using Serilog.Core; namespace Serilog { - public class SettingsFileUsingOutputTemplateTest : SinkFixture + public class OutputTemplateGivenAppSettingsShould : SinkFixture { - public SettingsFileUsingOutputTemplateTest() + public OutputTemplateGivenAppSettingsShould() { var configuration = new ConfigurationBuilder() .AddJsonFile("appsettings_output_template.json") .Build(); - RemoteAddress = configuration["Serilog:WriteTo:0:Args:remoteAddress"].ToIPAddress(); + RemoteAddress = configuration["Serilog:WriteTo:0:Args:remoteAddress"]; RemotePort = int.Parse(configuration["Serilog:WriteTo:0:Args:remotePort"]); Logger = new LoggerConfiguration() @@ -20,12 +19,10 @@ public SettingsFileUsingOutputTemplateTest() .CreateLogger(); } - public class FormatProvider : CultureInfo - { - public FormatProvider() - : base("en-US") - { - } - } + protected override string RemoteAddress { get; } + + protected override int RemotePort { get; } + + protected override Logger Logger { get; } } } diff --git a/test/Serilog.Sinks.Udp.Tests/OutputTemplateGivenCodeConfigurationShould.cs b/test/Serilog.Sinks.Udp.Tests/OutputTemplateGivenCodeConfigurationShould.cs new file mode 100644 index 0000000..f8fb026 --- /dev/null +++ b/test/Serilog.Sinks.Udp.Tests/OutputTemplateGivenCodeConfigurationShould.cs @@ -0,0 +1,32 @@ +using System.Net; +using Serilog.Core; +using Serilog.Support; + +namespace Serilog +{ + public class OutputTemplateGivenCodeConfigurationShould : SinkFixture + { + private const string OutputTemplate = "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level}] {Message} - {Exception}"; + + public OutputTemplateGivenCodeConfigurationShould() + { + var remoteAddress = IPAddress.Loopback.ToString(); + var remotePort = 7071; + + RemoteAddress = remoteAddress; + RemotePort = remotePort; + + Logger = new LoggerConfiguration() + .MinimumLevel.Verbose() + .WriteTo + .Udp(remoteAddress, remotePort, outputTemplate: OutputTemplate, formatProvider: new FormatProvider()) + .CreateLogger(); + } + + protected override string RemoteAddress { get; } + + protected override int RemotePort { get; } + + protected override Logger Logger { get; } + } +} diff --git a/test/Serilog.Sinks.Udp.Tests/Serilog.Sinks.Udp.Tests.csproj b/test/Serilog.Sinks.Udp.Tests/Serilog.Sinks.Udp.Tests.csproj index a617c85..1f50874 100755 --- a/test/Serilog.Sinks.Udp.Tests/Serilog.Sinks.Udp.Tests.csproj +++ b/test/Serilog.Sinks.Udp.Tests/Serilog.Sinks.Udp.Tests.csproj @@ -1,5 +1,4 @@  - netcoreapp2.0 Serilog @@ -7,11 +6,9 @@ true - - @@ -21,11 +18,9 @@ - - PreserveNewest @@ -34,5 +29,4 @@ PreserveNewest - diff --git a/test/Serilog.Sinks.Udp.Tests/SinkFixture.cs b/test/Serilog.Sinks.Udp.Tests/SinkFixture.cs index cac7783..969b042 100644 --- a/test/Serilog.Sinks.Udp.Tests/SinkFixture.cs +++ b/test/Serilog.Sinks.Udp.Tests/SinkFixture.cs @@ -1,5 +1,4 @@ using System; -using System.Net; using Moq; using Serilog.Core; using Serilog.Events; @@ -16,15 +15,15 @@ public abstract class SinkFixture : IDisposable protected SinkFixture() { client = new UdpClientMock(); - UdpClientFactory.Create = (_, __) => client.Object; + UdpClientFactory.Create = _ => client.Object; } - protected IPAddress RemoteAddress { get; set; } + protected abstract string RemoteAddress { get; } - protected int RemotePort { get; set; } - - protected Logger Logger { get; set; } + protected abstract int RemotePort { get; } + protected abstract Logger Logger { get; } + [Theory] [InlineData(LogEventLevel.Verbose)] [InlineData(LogEventLevel.Debug)] @@ -32,7 +31,7 @@ protected SinkFixture() [InlineData(LogEventLevel.Warning)] [InlineData(LogEventLevel.Error)] [InlineData(LogEventLevel.Fatal)] - public void Level(LogEventLevel level) + public void WriteLogEvent(LogEventLevel level) { // Arrange var counter = new Counter(1); @@ -52,12 +51,12 @@ public void Level(LogEventLevel level) } [Theory] - [InlineData(1)] // 1 batch - [InlineData(10)] // 1 batch - [InlineData(100)] // 1 batch - [InlineData(1000)] // ~1 batch - [InlineData(10000)] // ~10 batches - public void Batches(int numberOfEvents) + [InlineData(1)] // 1 batch assuming batch size is 1000 + [InlineData(10)] // 1 batch assuming batch size is 1000 + [InlineData(100)] // 1 batch assuming batch size is 1000 + [InlineData(1000)] // ~1 batch assuming batch size is 1000 + [InlineData(10000)] // ~10 batches assuming batch size is 1000 + public void WriteBatches(int numberOfEvents) { // Arrange var counter = new Counter(numberOfEvents); @@ -78,8 +77,7 @@ public void Batches(int numberOfEvents) public void Dispose() { - Logger?.Dispose(); - + Logger.Dispose(); UdpClientFactory.Create = null; } } diff --git a/test/Serilog.Sinks.Udp.Tests/Sinks/Udp/Private/StringExtensionsTest.cs b/test/Serilog.Sinks.Udp.Tests/Sinks/Udp/Private/StringExtensionsTest.cs deleted file mode 100644 index c3af34c..0000000 --- a/test/Serilog.Sinks.Udp.Tests/Sinks/Udp/Private/StringExtensionsTest.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System.Net; -using Serilog.Debugging; -using Shouldly; -using Xunit; - -namespace Serilog.Sinks.Udp.Private -{ - public class StringExtensionsTest - { - [Fact] - public void ShouldConvertIPAddress() - { - // Arrange - var expected = IPAddress.Loopback; - - // Act - var actual = "127.0.0.1".ToIPAddress(); - - // Assert - actual.ShouldBe(expected); - } - - [Fact] - public void ShouldConvertHostname() - { - // Arrange - var expected = IPAddress.Loopback; - - // Act - var actual = "localhost".ToIPAddress(); - - // Assert - actual.ShouldBe(expected); - } - - [Fact] - public void ShouldNotConvertInvalidHostname() - { - // Arrange - string actualErrorMessage = null; - - SelfLog.Enable(output => { actualErrorMessage = output; }); - - // Act - var actual = "invalid-host-name".ToIPAddress(); - - // Assert - actual.ShouldBeNull(); - actualErrorMessage.ShouldNotBeNull(); - } - } -} diff --git a/test/Serilog.Sinks.Udp.Tests/Sinks/Udp/Private/UdpClientMock.cs b/test/Serilog.Sinks.Udp.Tests/Sinks/Udp/Private/UdpClientMock.cs deleted file mode 100644 index fcb220f..0000000 --- a/test/Serilog.Sinks.Udp.Tests/Sinks/Udp/Private/UdpClientMock.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System; -using System.Linq.Expressions; -using System.Net; -using System.Threading.Tasks; -using Moq; -using Moq.Language.Flow; - -namespace Serilog.Sinks.Udp.Private -{ - internal class UdpClientMock : Mock - { - internal ISetup> SetupSendAsync( - IPAddress remoteAddress, - int remotePort) - { - return Setup( - mock => mock.SendAsync( - It.IsAny(), - It.IsAny(), - It.Is(RemoteEndPointCriteria(remoteAddress, remotePort)))); - } - - internal void VerifySendAsync( - IPAddress remoteAddress, - int remotePort, - Times times) - { - Verify( - mock => mock.SendAsync( - It.IsAny(), - It.IsAny(), - It.Is(RemoteEndPointCriteria(remoteAddress, remotePort))), - times); - } - - private static Expression> RemoteEndPointCriteria( - IPAddress remoteAddress, - int remotePort) - { - return remoteEndpoint => - remoteEndpoint.Address.Equals(remoteAddress) && - remoteEndpoint.Port == remotePort && - remoteEndpoint.AddressFamily == remoteAddress.AddressFamily; - } - } -} diff --git a/test/Serilog.Sinks.Udp.Tests/Sinks/Udp/TextFormatters/Log4jTextFormatterTest.cs b/test/Serilog.Sinks.Udp.Tests/Sinks/Udp/TextFormatters/Log4jTextFormatterShould.cs similarity index 88% rename from test/Serilog.Sinks.Udp.Tests/Sinks/Udp/TextFormatters/Log4jTextFormatterTest.cs rename to test/Serilog.Sinks.Udp.Tests/Sinks/Udp/TextFormatters/Log4jTextFormatterShould.cs index dcb1e8c..fac75f7 100644 --- a/test/Serilog.Sinks.Udp.Tests/Sinks/Udp/TextFormatters/Log4jTextFormatterTest.cs +++ b/test/Serilog.Sinks.Udp.Tests/Sinks/Udp/TextFormatters/Log4jTextFormatterShould.cs @@ -8,21 +8,21 @@ namespace Serilog.Sinks.Udp.TextFormatters { - public class Log4jTextFormatterTest + public class Log4jTextFormatterShould { private static readonly XNamespace Namespace = "http://jakarta.apache.org/log4j/"; private readonly Log4jTextFormatter formatter; private readonly TextWriter output; - public Log4jTextFormatterTest() + public Log4jTextFormatterShould() { formatter = new Log4jTextFormatter(); output = new StringWriter(); } [Fact] - public void Logger() + public void WriteLoggerAttribute() { // Arrange var logEvent = Some.LogEvent(); @@ -36,7 +36,7 @@ public void Logger() } [Fact] - public void Timestamp() + public void WriteTimestampAttribute() { // Act formatter.Format(Some.LogEvent(), output); @@ -53,7 +53,7 @@ public void Timestamp() [InlineData(LogEventLevel.Warning, "WARN")] [InlineData(LogEventLevel.Error, "ERROR")] [InlineData(LogEventLevel.Fatal, "FATAL")] - public void Level(LogEventLevel actual, string expected) + public void WriteLevelAttribute(LogEventLevel actual, string expected) { // Act formatter.Format(Some.LogEvent(level: actual), output); @@ -63,7 +63,7 @@ public void Level(LogEventLevel actual, string expected) } [Fact] - public void Thead() + public void WriteTheadAttribute() { // Arrange var logEvent = Some.LogEvent(); @@ -77,7 +77,7 @@ public void Thead() } [Fact] - public void Message() + public void WriteMessageElement() { // Arrange var logEvent = Some.LogEvent(message: "Some message"); @@ -90,7 +90,7 @@ public void Message() } [Fact] - public void Exception() + public void WriteExceptionElement() { // Arrange var logEvent = Some.LogEvent(exception: new DivideByZeroException()); diff --git a/test/Serilog.Sinks.Udp.Tests/Sinks/Udp/TextFormatters/Log4netTextFormatterTest.cs b/test/Serilog.Sinks.Udp.Tests/Sinks/Udp/TextFormatters/Log4netTextFormatterShould.cs similarity index 89% rename from test/Serilog.Sinks.Udp.Tests/Sinks/Udp/TextFormatters/Log4netTextFormatterTest.cs rename to test/Serilog.Sinks.Udp.Tests/Sinks/Udp/TextFormatters/Log4netTextFormatterShould.cs index 39d36fd..9c52093 100644 --- a/test/Serilog.Sinks.Udp.Tests/Sinks/Udp/TextFormatters/Log4netTextFormatterTest.cs +++ b/test/Serilog.Sinks.Udp.Tests/Sinks/Udp/TextFormatters/Log4netTextFormatterShould.cs @@ -8,21 +8,21 @@ namespace Serilog.Sinks.Udp.TextFormatters { - public class Log4netTextFormatterTest + public class Log4netTextFormatterShould { private static readonly XNamespace Namespace = "http://logging.apache.org/log4net/schemas/log4net-events-1.2/"; private readonly Log4netTextFormatter formatter; private readonly TextWriter output; - public Log4netTextFormatterTest() + public Log4netTextFormatterShould() { formatter = new Log4netTextFormatter(); output = new StringWriter(); } [Fact] - public void Logger() + public void WriteLoggerAttribute() { // Arrange var logEvent = Some.LogEvent(); @@ -36,7 +36,7 @@ public void Logger() } [Fact] - public void Timestamp() + public void WriteTimestampAttribute() { // Act formatter.Format(Some.LogEvent(), output); @@ -53,7 +53,7 @@ public void Timestamp() [InlineData(LogEventLevel.Warning, "WARN")] [InlineData(LogEventLevel.Error, "ERROR")] [InlineData(LogEventLevel.Fatal, "FATAL")] - public void Level(LogEventLevel actual, string expected) + public void WriteLevelAttribute(LogEventLevel actual, string expected) { // Act formatter.Format(Some.LogEvent(level: actual), output); @@ -63,7 +63,7 @@ public void Level(LogEventLevel actual, string expected) } [Fact] - public void Thead() + public void WriteTheadAttribute() { // Arrange var logEvent = Some.LogEvent(); @@ -77,7 +77,7 @@ public void Thead() } [Fact] - public void Username() + public void WriteUsernameAttribute() { // Arrange var logEvent = Some.LogEvent(); @@ -91,7 +91,7 @@ public void Username() } [Fact] - public void Domain() + public void WriteDomainAttribute() { // Arrange var logEvent = Some.LogEvent(); @@ -105,7 +105,7 @@ public void Domain() } [Fact] - public void Class() + public void WriteClassAttribute() { // Arrange var logEvent = Some.LogEvent(); @@ -119,7 +119,7 @@ public void Class() } [Fact] - public void Method() + public void WriteMethodAttribute() { // Arrange var logEvent = Some.LogEvent(); @@ -133,7 +133,7 @@ public void Method() } [Fact] - public void MachineName() + public void WriteMachineNameAttribute() { // Arrange var logEvent = Some.LogEvent(); @@ -147,7 +147,7 @@ public void MachineName() } [Fact] - public void Message() + public void WriteMessageElement() { // Arrange var logEvent = Some.LogEvent(message: "Some message"); @@ -160,7 +160,7 @@ public void Message() } [Fact] - public void Exception() + public void WriteExceptionElement() { // Arrange var logEvent = Some.LogEvent(exception: new DivideByZeroException()); diff --git a/test/Serilog.Sinks.Udp.Tests/Support/Counter.cs b/test/Serilog.Sinks.Udp.Tests/Support/Counter.cs index 303b19c..d2f215c 100644 --- a/test/Serilog.Sinks.Udp.Tests/Support/Counter.cs +++ b/test/Serilog.Sinks.Udp.Tests/Support/Counter.cs @@ -13,8 +13,7 @@ internal class Counter public Counter(int expected) { - if (expected <= 0) - throw new ArgumentException("expected must be at least 1"); + if (expected <= 0) throw new ArgumentException("expected must be at least 1"); this.expected = expected; resetEvent = new ManualResetEventSlim(); diff --git a/test/Serilog.Sinks.Udp.Tests/Support/FormatProvider.cs b/test/Serilog.Sinks.Udp.Tests/Support/FormatProvider.cs new file mode 100644 index 0000000..fa0c234 --- /dev/null +++ b/test/Serilog.Sinks.Udp.Tests/Support/FormatProvider.cs @@ -0,0 +1,12 @@ +using System.Globalization; + +namespace Serilog.Support +{ + public class FormatProvider : CultureInfo + { + public FormatProvider() + : base("en-US") + { + } + } +} diff --git a/test/Serilog.Sinks.Udp.Tests/Support/TextFormatters/TextFormatter.cs b/test/Serilog.Sinks.Udp.Tests/Support/TextFormatters/TextFormatter.cs new file mode 100644 index 0000000..9876acc --- /dev/null +++ b/test/Serilog.Sinks.Udp.Tests/Support/TextFormatters/TextFormatter.cs @@ -0,0 +1,12 @@ +using Serilog.Formatting.Display; + +namespace Serilog.Support.TextFormatters +{ + public class TextFormatter : MessageTemplateTextFormatter + { + public TextFormatter() + : base("{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level}] {Message} - {Exception}", null) + { + } + } +} diff --git a/test/Serilog.Sinks.Udp.Tests/Support/UdpClientMock.cs b/test/Serilog.Sinks.Udp.Tests/Support/UdpClientMock.cs new file mode 100644 index 0000000..752a1a2 --- /dev/null +++ b/test/Serilog.Sinks.Udp.Tests/Support/UdpClientMock.cs @@ -0,0 +1,36 @@ +using System.Threading.Tasks; +using Moq; +using Moq.Language.Flow; +using Serilog.Sinks.Udp.Private; + +namespace Serilog.Support +{ + internal class UdpClientMock : Mock + { + internal ISetup> SetupSendAsync( + string remoteHost, + int remotePort) + { + return Setup( + mock => mock.SendAsync( + It.IsAny(), + It.IsAny(), + It.Is(x => x == remoteHost), + It.Is(x => x == remotePort))); + } + + internal void VerifySendAsync( + string remoteHost, + int remotePort, + Times times) + { + Verify( + mock => mock.SendAsync( + It.IsAny(), + It.IsAny(), + It.Is(x => x == remoteHost), + It.Is(x => x == remotePort)), + times); + } + } +} diff --git a/test/Serilog.Sinks.Udp.Tests/SettingsFileUsingTextFormatterTest.cs b/test/Serilog.Sinks.Udp.Tests/TextFormatterGivenAppSettingsShould.cs similarity index 53% rename from test/Serilog.Sinks.Udp.Tests/SettingsFileUsingTextFormatterTest.cs rename to test/Serilog.Sinks.Udp.Tests/TextFormatterGivenAppSettingsShould.cs index 7997ca5..77c07ce 100644 --- a/test/Serilog.Sinks.Udp.Tests/SettingsFileUsingTextFormatterTest.cs +++ b/test/Serilog.Sinks.Udp.Tests/TextFormatterGivenAppSettingsShould.cs @@ -1,18 +1,17 @@ using Microsoft.Extensions.Configuration; -using Serilog.Formatting.Display; -using Serilog.Sinks.Udp.Private; +using Serilog.Core; namespace Serilog { - public class SettingsFileUsingTextFormatterTest : SinkFixture + public class TextFormatterGivenAppSettingsShould : SinkFixture { - public SettingsFileUsingTextFormatterTest() + public TextFormatterGivenAppSettingsShould() { var configuration = new ConfigurationBuilder() .AddJsonFile("appsettings_text_formatter.json") .Build(); - RemoteAddress = configuration["Serilog:WriteTo:0:Args:remoteAddress"].ToIPAddress(); + RemoteAddress = configuration["Serilog:WriteTo:0:Args:remoteAddress"]; RemotePort = int.Parse(configuration["Serilog:WriteTo:0:Args:remotePort"]); Logger = new LoggerConfiguration() @@ -20,12 +19,10 @@ public SettingsFileUsingTextFormatterTest() .CreateLogger(); } - public class TextFormatter : MessageTemplateTextFormatter - { - public TextFormatter() - : base("{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level}] {Message}{NewLine}{Exception}", null) - { - } - } + protected override string RemoteAddress{ get; } + + protected override int RemotePort { get; } + + protected override Logger Logger { get; } } } diff --git a/test/Serilog.Sinks.Udp.Tests/TextFormatterGivenCodeConfigurationShould.cs b/test/Serilog.Sinks.Udp.Tests/TextFormatterGivenCodeConfigurationShould.cs new file mode 100644 index 0000000..0b3f883 --- /dev/null +++ b/test/Serilog.Sinks.Udp.Tests/TextFormatterGivenCodeConfigurationShould.cs @@ -0,0 +1,30 @@ +using System.Net; +using Serilog.Core; +using Serilog.Support.TextFormatters; + +namespace Serilog +{ + public class TextFormatterGivenCodeConfigurationShould : SinkFixture + { + public TextFormatterGivenCodeConfigurationShould() + { + var remoteAddress = IPAddress.Loopback.ToString(); + var remotePort = 7071; + + RemoteAddress = remoteAddress; + RemotePort = remotePort; + + Logger = new LoggerConfiguration() + .MinimumLevel.Verbose() + .WriteTo + .Udp(remoteAddress, remotePort, new TextFormatter()) + .CreateLogger(); + } + + protected override string RemoteAddress { get; } + + protected override int RemotePort { get; } + + protected override Logger Logger { get; } + } +} diff --git a/test/Serilog.Sinks.Udp.Tests/appsettings_output_template.json b/test/Serilog.Sinks.Udp.Tests/appsettings_output_template.json index 7d9ab4e..34a47f3 100644 --- a/test/Serilog.Sinks.Udp.Tests/appsettings_output_template.json +++ b/test/Serilog.Sinks.Udp.Tests/appsettings_output_template.json @@ -10,8 +10,8 @@ "localPort": 0, "restrictedToMinimumLevel": "Verbose", "levelSwitch": "Verbose", - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level}] {Message}{NewLine}{Exception}", - "formatProvider": "Serilog.SettingsFileUsingOutputTemplateTest+FormatProvider, Serilog.Sinks.Udp.Tests" + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level}] {Message} - {Exception}", + "formatProvider": "Serilog.Support.FormatProvider, Serilog.Sinks.Udp.Tests" } } ] diff --git a/test/Serilog.Sinks.Udp.Tests/appsettings_text_formatter.json b/test/Serilog.Sinks.Udp.Tests/appsettings_text_formatter.json index 21c1b78..0a86616 100644 --- a/test/Serilog.Sinks.Udp.Tests/appsettings_text_formatter.json +++ b/test/Serilog.Sinks.Udp.Tests/appsettings_text_formatter.json @@ -7,7 +7,7 @@ "Args": { "remoteAddress": "localhost", "remotePort": 7071, - "formatter": "Serilog.SettingsFileUsingTextFormatterTest+TextFormatter, Serilog.Sinks.Udp.Tests", + "formatter": "Serilog.Support.TextFormatters.TextFormatter, Serilog.Sinks.Udp.Tests", "localPort": 0, "restrictedToMinimumLevel": "Verbose", "levelSwitch": "Verbose"