diff --git a/Core/Core.csproj b/Core/Core.csproj index 2ba3f0a..5a20b4d 100644 --- a/Core/Core.csproj +++ b/Core/Core.csproj @@ -21,6 +21,7 @@ + diff --git a/Core/ModuleRegistry/SeqBackgroundServiceModule.cs b/Core/ModuleRegistry/SeqBackgroundServiceModule.cs index fba38a4..ad6c77d 100644 --- a/Core/ModuleRegistry/SeqBackgroundServiceModule.cs +++ b/Core/ModuleRegistry/SeqBackgroundServiceModule.cs @@ -9,7 +9,7 @@ namespace Core.ModuleRegistry { builder.RegisterType() - .As() + .As>() .SingleInstance(); builder.RegisterType() diff --git a/Core/Telemetry/IMessageChannel.cs b/Core/Telemetry/IMessageChannel.cs index e048fbc..e794f98 100644 --- a/Core/Telemetry/IMessageChannel.cs +++ b/Core/Telemetry/IMessageChannel.cs @@ -1,9 +1,9 @@ using System.Threading.Channels; namespace Core.Telemetry { - public interface IMessageChannel : IDisposable + public interface IMessageChannel : IDisposable { - ChannelWriter Writer { get; } - ChannelReader Reader { get; } + ChannelWriter Writer { get; } + ChannelReader Reader { get; } } } diff --git a/Core/Telemetry/MessageChannel.cs b/Core/Telemetry/MessageChannel.cs index c325d63..ae84408 100644 --- a/Core/Telemetry/MessageChannel.cs +++ b/Core/Telemetry/MessageChannel.cs @@ -1,22 +1,23 @@ -using System.Threading.Channels; +using Microsoft.ApplicationInsights.Channel; +using System.Threading.Channels; namespace Core.Telemetry { - public class MessageChannel : IMessageChannel - { - private readonly Channel _channel; + public class MessageChannel : IMessageChannel + { + private readonly Channel _channel; - public MessageChannel() - { - _channel = Channel.CreateUnbounded(); - } + public MessageChannel() + { + _channel = Channel.CreateUnbounded(); + } - public ChannelWriter Writer => _channel.Writer; - public ChannelReader Reader => _channel.Reader; + public ChannelWriter Writer => _channel.Writer; + public ChannelReader Reader => _channel.Reader; - public void Dispose() - { - _channel.Writer.Complete(); - } - } + public void Dispose() + { + _channel.Writer.Complete(); + } + } } diff --git a/Core/Telemetry/SeqBackgroundService.cs b/Core/Telemetry/SeqBackgroundService.cs index 312a789..b60c8da 100644 --- a/Core/Telemetry/SeqBackgroundService.cs +++ b/Core/Telemetry/SeqBackgroundService.cs @@ -1,64 +1,101 @@ using Microsoft.ApplicationInsights; +using Microsoft.ApplicationInsights.Channel; using Microsoft.Extensions.Hosting; +using System.Net.Http.Headers; +using System.Text; namespace Core.Telemetry { - public class SeqBackgroundService : BackgroundService - { - private readonly IMessageChannel _messageChannel; - private readonly TelemetryClient _telemetryClient; - private readonly HttpClient _httpClient; + public class SeqBackgroundService : BackgroundService + { + private readonly IMessageChannel _messageChannel; + private readonly TelemetryClient _telemetryClient; + private readonly HttpClient _httpClient; - public SeqBackgroundService( - TelemetryClient telemetryClient, - IMessageChannel messageChannel, - HttpClient httpClient) - { - _telemetryClient = telemetryClient; - _messageChannel = messageChannel; - _httpClient = httpClient; - } + public SeqBackgroundService(TelemetryClient telemetryClient, + IMessageChannel messageChannel, + HttpClient httpClient) + { + _telemetryClient = telemetryClient; + _messageChannel = messageChannel; + _httpClient = httpClient; - protected override async Task ExecuteAsync(CancellationToken stoppingToken) - { - try - { - while (!stoppingToken.IsCancellationRequested) - await foreach (var message in _messageChannel.Reader.ReadAllAsync(stoppingToken)) - { + _httpClient = new HttpClient() + { + BaseAddress = new Uri("http://localhost:5341"), + Timeout = TimeSpan.FromSeconds(30) + }; - try - { - //using var response = await _httpClient.SendAsync(message, stoppingToken); - //if (!response.IsSuccessStatusCode) - //{ - // _telemetryClient.TrackTrace($"HTTP kald fejlede med status {response.StatusCode}", Microsoft.ApplicationInsights.DataContracts.SeverityLevel.Warning); - // continue; - //} - } - catch (Exception ex) - { - _telemetryClient.TrackException(ex); - } - } - } - catch (Exception ex) - { - if (ex is not OperationCanceledException) - { - _telemetryClient.TrackException(ex); - throw; - } + _httpClient.DefaultRequestHeaders.Accept.Clear(); + _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); - _telemetryClient.TrackTrace("Service shutdown pÃ¥begyndt"); - } - } - public override async Task StopAsync(CancellationToken cancellationToken) - { + } - _messageChannel.Dispose(); - await base.StopAsync(cancellationToken); - } - } + protected override async Task ExecuteAsync(CancellationToken stoppingToken) + { + try + { + while (!stoppingToken.IsCancellationRequested) + await foreach (var message in _messageChannel.Reader.ReadAllAsync(stoppingToken)) + { + + try + { + var eventTelemetry = message as Microsoft.ApplicationInsights.DataContracts.EventTelemetry; + + var level = "Information"; + var seqEvent = new Dictionary + { + { "@t", DateTime.UtcNow.ToString("o") }, + { "@mt", eventTelemetry.Name }, + { "@l", level } // "Information", "Warning", "Error", etc. + }; + + foreach (var prop in eventTelemetry.Context.GlobalProperties) + { + seqEvent.Add(prop.Key, prop.Value); + } + + var content = new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(seqEvent), Encoding.UTF8, "application/vnd.serilog.clef"); + + var key = "4XhWFtY4jJ0NBgohBAFF"; ; + //Gt8hS9ClGNfOCAdswDlW + var requestMessage = new HttpRequestMessage(HttpMethod.Post, $"/ingest/clef?apiKey={key}"); + requestMessage.Content = content; + + var response = await _httpClient.SendAsync(requestMessage, stoppingToken); + + response.EnsureSuccessStatusCode(); + + //if (!response.IsSuccessStatusCode) + //{ + // _telemetryClient.TrackTrace($"HTTP kald fejlede med status {response.StatusCode}", Microsoft.ApplicationInsights.DataContracts.SeverityLevel.Warning); + // continue; + //} + } + catch (Exception ex) + { + //_telemetryClient.TrackException(ex); this is disabled for now, we need to think about the channel structure first + } + } + } + catch (Exception ex) + { + if (ex is not OperationCanceledException) + { + _telemetryClient.TrackException(ex); + throw; + } + + _telemetryClient.TrackTrace("Service shutdown started"); + } + } + + public override async Task StopAsync(CancellationToken cancellationToken) + { + _messageChannel.Dispose(); + await base.StopAsync(cancellationToken); + } + } } diff --git a/Tests/MessageChannelIntegrationTests.cs b/Tests/MessageChannelIntegrationTests.cs index 8a43d43..4c2ca48 100644 --- a/Tests/MessageChannelIntegrationTests.cs +++ b/Tests/MessageChannelIntegrationTests.cs @@ -5,13 +5,15 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.Extensions.Logging; using Core.Telemetry; using Microsoft.ApplicationInsights; +using Microsoft.ApplicationInsights.Channel; +using Microsoft.ApplicationInsights.DataContracts; namespace Tests { [TestClass] public class MessageChannelIntegrationTests : TestFixture { - private IMessageChannel _messageChannel; + private IMessageChannel _messageChannel; private SeqBackgroundService _service; private CancellationTokenSource _cts; @@ -23,36 +25,30 @@ namespace Tests var httpClient = new HttpClient(new TestMessageHandler()); _service = new SeqBackgroundService(telemetryClient, _messageChannel, httpClient); _cts = new CancellationTokenSource(); - } + } [TestMethod] public async Task Messages_ShouldBeProcessedFromQueue() { - // Arrange var processedMessages = new List(); - // Start service var serviceTask = _service.StartAsync(_cts.Token); - // Act - // Send nogle beskeder til køen for (int i = 0; i < 5; i++) { - var message = new HttpRequestMessage(HttpMethod.Post, $"http://test.com/{i}"); - await _messageChannel.Writer.WriteAsync(message); + var eventTelemetry = new EventTelemetry("SomeEvent"); + await _messageChannel.Writer.WriteAsync(eventTelemetry); } - // Vent lidt for at sikre processing + // wait for processing await Task.Delay(5000); - // Stop servicen _cts.Cancel(); await _service.StopAsync(CancellationToken.None); - // Assert - // Check at køen er tom + bool hasMoreMessages = await _messageChannel.Reader.WaitToReadAsync(); - Assert.IsFalse(hasMoreMessages, "Køen burde være tom"); + Assert.IsFalse(hasMoreMessages, "Queue should be empty after 5 seconds"); } private class TestMessageHandler : HttpMessageHandler