From f211fedc7b2699853eb29161ba1abdc46678db71 Mon Sep 17 00:00:00 2001 From: Rolf Kristensen Date: Tue, 13 Aug 2024 22:22:06 +0200 Subject: [PATCH] Adjusted unit-test to handle isolated TelemetryClient --- .../NLogTarget/ApplicationInsightsTarget.cs | 50 ++++++++++---- .../test/NLogTarget.Tests/NLogTargetTests.cs | 67 ++----------------- LOGGING/test/Shared/AdapterHelper.cs | 9 +-- 3 files changed, 45 insertions(+), 81 deletions(-) diff --git a/LOGGING/src/NLogTarget/ApplicationInsightsTarget.cs b/LOGGING/src/NLogTarget/ApplicationInsightsTarget.cs index d4ba9304a7..be130e0eec 100644 --- a/LOGGING/src/NLogTarget/ApplicationInsightsTarget.cs +++ b/LOGGING/src/NLogTarget/ApplicationInsightsTarget.cs @@ -30,7 +30,7 @@ namespace Microsoft.ApplicationInsights.NLogTarget public sealed class ApplicationInsightsTarget : TargetWithLayout { private TelemetryClient telemetryClient; - private DateTime lastLogEventTime; + private TelemetryConfiguration telemetryConfiguration; private NLog.Layouts.Layout instrumentationKeyLayout = string.Empty; private NLog.Layouts.Layout connectionStringLayout = string.Empty; @@ -68,12 +68,9 @@ public string ConnectionString public IList ContextProperties { get; } = new List(); /// - /// Gets the logging controller we will be using. + /// Gets or sets the factory for creating TelemetryConfiguration, so unit-tests can override in-memory-channel. /// - internal TelemetryClient TelemetryClient - { - get { return this.telemetryClient; } - } + internal Func TelemetryConfigurationFactory { get; set; } internal void BuildPropertyBag(LogEventInfo logEvent, ITelemetry trace) { @@ -119,9 +116,8 @@ internal void BuildPropertyBag(LogEventInfo logEvent, ITelemetry trace) } /// - /// Initializes the Target and perform instrumentationKey validation. + /// Initializes the Target and configures TelemetryClient. /// - /// Will throw when is not set. protected override void InitializeTarget() { base.InitializeTarget(); @@ -132,9 +128,9 @@ protected override void InitializeTarget() // configure new telemetryclient with the connectionstring otherwise using legacy instrumentationkey. if (!string.IsNullOrWhiteSpace(connectionString)) { - var telemetryConfiguration = TelemetryConfiguration.CreateDefault(); - telemetryConfiguration.ConnectionString = connectionString; - this.telemetryClient = new TelemetryClient(telemetryConfiguration); + this.telemetryConfiguration = this.TelemetryConfigurationFactory?.Invoke() ?? TelemetryConfiguration.CreateDefault(); + this.telemetryConfiguration.ConnectionString = connectionString; + this.telemetryClient = new TelemetryClient(this.telemetryConfiguration); } else { @@ -151,6 +147,18 @@ protected override void InitializeTarget() this.telemetryClient.Context.GetInternalContext().SdkVersion = SdkVersionUtils.GetSdkVersion("nlog:"); } + /// + /// Closes the target and releases resources used by the current instance of the class. + /// + protected override void CloseTarget() + { + var telemetryConfiguration = this.telemetryConfiguration; + this.telemetryConfiguration = null; + telemetryConfiguration?.Dispose(); + + base.CloseTarget(); + } + /// /// Send the log message to Application Insights. /// @@ -162,8 +170,6 @@ protected override void Write(LogEventInfo logEvent) throw new ArgumentNullException(nameof(logEvent)); } - this.lastLogEventTime = DateTime.UtcNow; - if (logEvent.Exception != null) { this.SendException(logEvent); @@ -187,7 +193,7 @@ protected override void FlushAsync(AsyncContinuation asyncContinuation) try { - this.TelemetryClient.FlushAsync(System.Threading.CancellationToken.None).ContinueWith(t => asyncContinuation(t.Exception)); + this.telemetryClient.FlushAsync(System.Threading.CancellationToken.None).ContinueWith(t => asyncContinuation(t.Exception)); } catch (Exception ex) { @@ -195,6 +201,22 @@ protected override void FlushAsync(AsyncContinuation asyncContinuation) } } + /// + /// Releases resources used by the current instance of the class. + /// + /// Dispose managed state (managed objects). + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + + if (disposing) + { + var telemetryConfiguration = this.telemetryConfiguration; + this.telemetryConfiguration = null; + telemetryConfiguration?.Dispose(); + } + } + private static void LoadLogEventProperties(LogEventInfo logEvent, IDictionary propertyBag) { if (logEvent.Properties?.Count > 0) diff --git a/LOGGING/test/NLogTarget.Tests/NLogTargetTests.cs b/LOGGING/test/NLogTarget.Tests/NLogTargetTests.cs index bab41820f9..a2ab9a86c1 100644 --- a/LOGGING/test/NLogTarget.Tests/NLogTargetTests.cs +++ b/LOGGING/test/NLogTarget.Tests/NLogTargetTests.cs @@ -455,64 +455,14 @@ public void NLogTargetFlushesTelemetryClient() NLog.Common.AsyncContinuation asyncContinuation = (ex) => { flushException = ex; flushEvent.Set(); }; aiLogger.Factory.Flush(asyncContinuation, 5000); Assert.IsTrue(flushEvent.WaitOne(5000)); - Assert.IsNotNull(flushException); - Assert.AreEqual("Flush called", flushException.Message); } [TestMethod] [TestCategory("NLogTarget")] - public void NLogInfoIsSentAsInformationTraceItemWithAIConnectionString() + public void NLogTargetWithConnectionString() { - var aiLogger = this.CreateTargetWithGivenConnectionString("Your_ApplicationInsights_ConnectionString"); - aiLogger.Info("Info message"); - - var telemetry = (TraceTelemetry)this.adapterHelper.Channel.SentItems.First(); - Assert.AreEqual($"Info message", telemetry.Message); - } - - [TestMethod] - [TestCategory("NLogTarget")] - public void NLogTraceIsSentAsVerboseTraceItemWithAIConnectionString() - { - var aiLogger = this.CreateTargetWithGivenConnectionString("Your_ApplicationInsights_ConnectionString"); - aiLogger.Trace("Trace message"); - - var telemetry = (TraceTelemetry)this.adapterHelper.Channel.SentItems.FirstOrDefault(); - Assert.AreEqual("Trace message", telemetry.Message); - } - - [TestMethod] - [TestCategory("NLogTarget")] - public void NLogDebugIsSentAsVerboseTraceItemWithAIConnectionString() - { - var aiLogger = this.CreateTargetWithGivenConnectionString("Your_ApplicationInsights_ConnectionString"); - aiLogger.Debug("Debug Message"); - - var telemetry = (TraceTelemetry)this.adapterHelper.Channel.SentItems.FirstOrDefault(); - Assert.AreEqual("Debug Message", telemetry.Message); - } - - [TestMethod] - [TestCategory("NLogTarget")] - public void NLogWarnIsSentAsWarningTraceItemWithAIConnectionString() - { - var aiLogger = this.CreateTargetWithGivenConnectionString("Your_ApplicationInsights_ConnectionString"); - - aiLogger.Warn("Warn message"); - - var telemetry = (TraceTelemetry)this.adapterHelper.Channel.SentItems.FirstOrDefault(); - Assert.AreEqual("Warn message", telemetry.Message); - } - - [TestMethod] - [TestCategory("NLogTarget")] - public void NLogErrorIsSentAsVerboseTraceItemWithAIConnectionString() - { - var aiLogger = this.CreateTargetWithGivenConnectionString("InstrumentationKey=b91a8f48-c77c-4f12-80e2-f96bc1abb126;IngestionEndpoint=https://centralus-2.in.applicationinsights.azure.com/;LiveEndpoint=https://centralus.livediagnostics.monitor.azure.com/"); - aiLogger.Error("Error Message"); - - var telemetry = (TraceTelemetry)this.adapterHelper.Channel.SentItems.FirstOrDefault(); - Assert.AreEqual("Error Message", telemetry.Message); + var aiLogger = this.CreateTargetWithGivenConnectionString("TestAI"); + VerifyMessagesInMockChannel(aiLogger, "TestAI"); } private void VerifyMessagesInMockChannel(Logger aiLogger, string instrumentationKey) @@ -562,19 +512,16 @@ private Logger CreateTargetWithGivenInstrumentationKey( } private Logger CreateTargetWithGivenConnectionString( - string connectionString = "Your_ApplicationInsights_ConnectionString", + string instrumentationKey = "TEST", Action loggerAction = null) { - // Mock channel to validate that our appender is trying to send logs -#pragma warning disable CS0618 // Type or member is obsolete - TelemetryConfiguration.Active.TelemetryChannel = this.adapterHelper.Channel; -#pragma warning restore CS0618 // Type or member is obsolete - ApplicationInsightsTarget target = new ApplicationInsightsTarget { - ConnectionString = connectionString + ConnectionString = $"InstrumentationKey={instrumentationKey};IngestionEndpoint=https://localhost/;LiveEndpoint=https://localhost/" }; + target.TelemetryConfigurationFactory = () => new TelemetryConfiguration() { TelemetryChannel = this.adapterHelper.Channel }; + LoggingRule rule = new LoggingRule("*", LogLevel.Trace, target); LoggingConfiguration config = new LoggingConfiguration(); config.AddTarget("AITarget", target); diff --git a/LOGGING/test/Shared/AdapterHelper.cs b/LOGGING/test/Shared/AdapterHelper.cs index 9106afb3f8..9b926f8599 100644 --- a/LOGGING/test/Shared/AdapterHelper.cs +++ b/LOGGING/test/Shared/AdapterHelper.cs @@ -19,8 +19,6 @@ public class AdapterHelper : IDisposable { public string InstrumentationKey { get; } - public string ConnectionString { get; } - #if NET452 || NET46 private static readonly string ApplicationInsightsConfigFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ApplicationInsights.config"); @@ -29,19 +27,16 @@ public class AdapterHelper : IDisposable Path.Combine(Path.GetDirectoryName(typeof(AdapterHelper).GetTypeInfo().Assembly.Location), "ApplicationInsights.config"); #endif - public AdapterHelper(string instrumentationKey = "F8474271-D231-45B6-8DD4-D344C309AE69" - , string connectionString = "Your_ApplicationInsights_ConnectionString") + public AdapterHelper(string instrumentationKey = "F8474271-D231-45B6-8DD4-D344C309AE69") { this.InstrumentationKey = instrumentationKey; - this.ConnectionString = connectionString; string configuration = string.Format(InvariantCulture, @" {0} ", - instrumentationKey, - connectionString); + instrumentationKey); File.WriteAllText(ApplicationInsightsConfigFilePath, configuration); this.Channel = new CustomTelemetryChannel();