diff --git a/src/Elastic.Ingest.Elasticsearch.CommonSchema/Elastic.Ingest.Elasticsearch.CommonSchema.csproj b/src/Elastic.Ingest.Elasticsearch.CommonSchema/Elastic.Ingest.Elasticsearch.CommonSchema.csproj index 77b65e53..1787e90a 100644 --- a/src/Elastic.Ingest.Elasticsearch.CommonSchema/Elastic.Ingest.Elasticsearch.CommonSchema.csproj +++ b/src/Elastic.Ingest.Elasticsearch.CommonSchema/Elastic.Ingest.Elasticsearch.CommonSchema.csproj @@ -10,7 +10,7 @@ - + diff --git a/src/Elastic.Serilog.Sinks/ElasticsearchSink.cs b/src/Elastic.Serilog.Sinks/ElasticsearchSink.cs index a6592405..9d83f7eb 100644 --- a/src/Elastic.Serilog.Sinks/ElasticsearchSink.cs +++ b/src/Elastic.Serilog.Sinks/ElasticsearchSink.cs @@ -31,14 +31,14 @@ public interface IElasticsearchSinkOptions IEcsTextFormatterConfiguration EcsTextFormatterConfiguration { get; } /// - public DataStreamName DataStream { get; } + DataStreamName DataStream { get; } /// /// The ILM Policy to apply, see the following for more details: /// https://www.elastic.co/guide/en/elasticsearch/reference/current/index-lifecycle-management.html /// Defaults to `logs` which is shipped by default with Elasticsearch /// - public string? IlmPolicy { get; } + string? IlmPolicy { get; } } @@ -137,7 +137,6 @@ public ElasticsearchSink(ElasticsearchSinkOptions options) { DataStream = options.DataStream, ExportMaxRetriesCallback = EmitExportFailures - }; options.ConfigureChannel?.Invoke(channelOptions); _channel = new EcsDataStreamChannel(channelOptions, new [] { new SelfLogCallbackListener(options)}); @@ -153,7 +152,7 @@ private void EmitExportFailures(IReadOnlyCollection documents) .ToArray(); _failureListener.OnLoggingFailed( this, - LoggingFailureKind.Temporary, + LoggingFailureKind.Permanent, "Failure to export events over to Elasticsearch.", logs, exception: null @@ -169,7 +168,7 @@ public void Emit(LogEvent logEvent) { _failureListener.OnLoggingFailed( this, - LoggingFailureKind.Temporary, + LoggingFailureKind.Permanent, "Failure to push event over the channel.", [logEvent], exception: null diff --git a/tests-integration/Elasticsearch.IntegrationDefaults/Elasticsearch.IntegrationDefaults.csproj b/tests-integration/Elasticsearch.IntegrationDefaults/Elasticsearch.IntegrationDefaults.csproj index 80c23f6b..7b48b1a4 100644 --- a/tests-integration/Elasticsearch.IntegrationDefaults/Elasticsearch.IntegrationDefaults.csproj +++ b/tests-integration/Elasticsearch.IntegrationDefaults/Elasticsearch.IntegrationDefaults.csproj @@ -11,7 +11,7 @@ - + diff --git a/tests/Elastic.Serilog.Sinks.Tests/Elastic.Serilog.Sinks.Tests.csproj b/tests/Elastic.Serilog.Sinks.Tests/Elastic.Serilog.Sinks.Tests.csproj index 7ccd2cd7..158fe856 100644 --- a/tests/Elastic.Serilog.Sinks.Tests/Elastic.Serilog.Sinks.Tests.csproj +++ b/tests/Elastic.Serilog.Sinks.Tests/Elastic.Serilog.Sinks.Tests.csproj @@ -12,6 +12,8 @@ + + diff --git a/tests/Elastic.Serilog.Sinks.Tests/SerilogFailureOutputTests.cs b/tests/Elastic.Serilog.Sinks.Tests/SerilogFailureOutputTests.cs new file mode 100644 index 00000000..a239ab35 --- /dev/null +++ b/tests/Elastic.Serilog.Sinks.Tests/SerilogFailureOutputTests.cs @@ -0,0 +1,54 @@ +using Elastic.Channels; +using Elastic.Channels.Diagnostics; +using Elastic.Transport; +using FluentAssertions; +using Serilog; +using Serilog.Sinks.TestCorrelator; +using Xunit; +using DataStreamName = Elastic.Ingest.Elasticsearch.DataStreams.DataStreamName; + +namespace Elastic.Serilog.Sinks.Tests +{ + public class SerilogFailureOutputTests + { + private readonly CountdownEvent _waitHandle; + private IChannelDiagnosticsListener? _listener; + private ElasticsearchSinkOptions SinkOptions { get; } + + public SerilogFailureOutputTests() + { + _waitHandle = new CountdownEvent(1); + SinkOptions = new ElasticsearchSinkOptions(new DistributedTransport(new TransportConfiguration())) + { + DataStream = new DataStreamName("logs", "serilog", "tests"), + ConfigureChannel = c => + { + c.BufferOptions = new BufferOptions + { + ExportMaxRetries = 0, + WaitHandle = _waitHandle, + OutboundBufferMaxSize = 1 + }; + }, + ChannelDiagnosticsCallback = (l) => _listener = l + }; + } + + [Fact] public void AssertLogs() + { + var loggerConfig = new LoggerConfiguration() + .MinimumLevel.Information() + .WriteTo.FallbackChain( + fc => fc.Elasticsearch(SinkOptions), + fc => fc.Console() + ); + + using var logger = loggerConfig.CreateLogger(); + logger.Information("Hello world"); + + if (!_waitHandle.WaitHandle.WaitOne(TimeSpan.FromSeconds(10))) + throw new Exception($"No flush occurred in 10 seconds: {_listener}", _listener?.ObservedException); + + } + } +}