tests-integration/Elastic.Extensions.Logging.IntegrationTests/LoggingToDataStreamTests.cs (98 lines of code) (raw):

using System; using System.Linq; using System.Threading; using System.Threading.Tasks; using Elastic.Channels.Diagnostics; using Elastic.Clients.Elasticsearch; using Elastic.CommonSchema; using Elastic.Extensions.Logging.Options; using FluentAssertions; using Microsoft.Extensions.Logging; using Xunit; using Xunit.Abstractions; namespace Elastic.Extensions.Logging.IntegrationTests { public class LoggingToDataStreamTests : TestBase { public LoggingToDataStreamTests(LoggingCluster cluster, ITestOutputHelper output) : base(cluster, output) { } private IDisposable CreateLogger( out ILogger logger, out ElasticsearchLoggerProvider provider, out string @namespace, out WaitHandle waitHandle, out IChannelDiagnosticsListener listener ) => base.CreateLogger(out logger, out provider, out @namespace, out waitHandle, out listener, (o, s) => { o.DataStream = new DataStreamNameOptions { Type = "x", Namespace = s, DataSet = "dotnet" }; var nodes = Client.ElasticsearchClientSettings.NodePool.Nodes.Select(n => n.Uri).ToArray(); o.ShipTo = new ShipToOptions { NodeUris = nodes, NodePoolType = NodePoolType.Static }; }); // ReSharper disable once UnusedMember.Local private enum MyEnum { Success, Failure } [Fact] public async Task LogsEndUpInCluster() { using var _ = CreateLogger(out var logger, out var provider, out var @namespace, out var waitHandle, out var listener); var dataStream = $"x-dotnet-{@namespace}"; logger.LogError("an error occurred {Status}", MyEnum.Failure); if (!waitHandle.WaitOne(TimeSpan.FromSeconds(10))) throw new Exception($"No flush occurred in 10 seconds: {listener}", listener.ObservedException); listener.PublishSuccess.Should().BeTrue("{0}", listener); listener.ObservedException.Should().BeNull(); await Client.Indices.RefreshAsync(dataStream); var response = await Client.SearchAsync<EcsDocument>(new SearchRequest(dataStream)); response.IsValidResponse.Should().BeTrue("{0}", response.DebugInformation); response.Total.Should().BeGreaterThan(0); var loggedError = response.Documents.First(); loggedError.Message.Should().Be("an error occurred Failure"); loggedError.Log.Should().NotBeNull(); loggedError.Log.Level.Should().Be("Error"); loggedError.Ecs.Version.Should().Be(EcsDocument.Version); loggedError.Ecs.Version.Should().NotStartWith("v"); loggedError.Labels.Should().ContainKey("Status"); loggedError.Labels["Status"].Should().Be("Failure"); } [Fact] public async Task SerializesAndDeserializesMessageTemplateAndScope() { using var _ = CreateLogger(out var logger, out var provider, out var @namespace, out var waitHandle, out var listener); using var scope = logger.BeginScope("custom scope"); var dataStream = $"x-dotnet-{@namespace}"; var userId = 1; logger.LogError("an error occurred for userId {UserId}", userId); if (!waitHandle.WaitOne(TimeSpan.FromSeconds(10))) throw new Exception($"No flush occurred in 10 seconds: {listener}", listener.ObservedException); listener.PublishSuccess.Should().BeTrue("{0}", listener); listener.ObservedException.Should().BeNull(); await Client.Indices.RefreshAsync(dataStream); var response = await Client.SearchAsync<LogEvent>(new SearchRequest(dataStream)); response.IsValidResponse.Should().BeTrue("{0}", response.DebugInformation); response.Total.Should().BeGreaterThan(0); var loggedError = response.Documents.First(); loggedError.Message.Should().Be("an error occurred for userId 1"); loggedError.MessageTemplate.Should().Be("an error occurred for userId {UserId}"); loggedError.Scopes.Should().ContainSingle(s => s == "custom scope"); } [Fact] public async Task MessageTemplateOnLogIsNotTemplatedScope() { using var _ = CreateLogger(out var logger, out var provider, out var @namespace, out var waitHandle, out var listener); using var scope = logger.BeginScope("My Scope {Value}", "value"); var dataStream = $"x-dotnet-{@namespace}"; var userId = 1; logger.LogError("an error occurred for userId {UserId}", userId); if (!waitHandle.WaitOne(TimeSpan.FromSeconds(10))) throw new Exception($"No flush occurred in 10 seconds: {listener}", listener.ObservedException); listener.PublishSuccess.Should().BeTrue("{0}", listener); listener.ObservedException.Should().BeNull(); await Client.Indices.RefreshAsync(dataStream); var response = await Client.SearchAsync<LogEvent>(new SearchRequest(dataStream)); response.IsValidResponse.Should().BeTrue("{0}", response.DebugInformation); response.Total.Should().BeGreaterThan(0); var loggedError = response.Documents.First(); loggedError.Message.Should().Be("an error occurred for userId 1"); loggedError.MessageTemplate.Should().Be("an error occurred for userId {UserId}"); loggedError.Scopes.Should().ContainSingle(s => s == "My Scope value"); } } }