Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Add support for connection string to Microsoft.ApplicationInsights.NLogTarget microsoft#2714
  • Loading branch information
saidi-adot committed Mar 10, 2023
1 parent 24e5b04 commit 59b35e9
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 13 deletions.
31 changes: 28 additions & 3 deletions LOGGING/src/NLogTarget/ApplicationInsightsTarget.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ namespace Microsoft.ApplicationInsights.NLogTarget

using Microsoft.ApplicationInsights.Channel;
using Microsoft.ApplicationInsights.DataContracts;
using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.ApplicationInsights.Extensibility.Implementation;
using Microsoft.ApplicationInsights.Implementation;

Expand All @@ -31,6 +32,7 @@ public sealed class ApplicationInsightsTarget : TargetWithLayout
private TelemetryClient telemetryClient;
private DateTime lastLogEventTime;
private NLog.Layouts.Layout instrumentationKeyLayout = string.Empty;
private NLog.Layouts.Layout connectionStringLayout = string.Empty;

/// <summary>
/// Initializers a new instance of ApplicationInsightsTarget type.
Expand All @@ -50,6 +52,15 @@ public string InstrumentationKey
set => this.instrumentationKeyLayout = value ?? string.Empty;
}

/// <summary>
/// Gets or sets the Application Insights connectionstring for your application
/// </summary>
public string ConnectionString
{
get => (this.connectionStringLayout as NLog.Layouts.SimpleLayout)?.Text ?? null;
set => this.connectionStringLayout = value ?? string.Empty;
}

/// <summary>
/// Gets the array of custom attributes to be passed into the logevent context.
/// </summary>
Expand Down Expand Up @@ -118,10 +129,24 @@ protected override void InitializeTarget()
this.telemetryClient = new TelemetryClient();
#pragma warning restore CS0618 // Type or member is obsolete

string instrumentationKey = this.instrumentationKeyLayout.Render(LogEventInfo.CreateNullEvent());
if (!string.IsNullOrWhiteSpace(instrumentationKey))
string connectionString = this.connectionStringLayout.Render(LogEventInfo.CreateNullEvent());

// Check if nlog application insights target has connectionstring in config file then
// configure telemetryclient with the connectionstring otherwise using instrumentationkey.
if (!string.IsNullOrWhiteSpace(connectionString))
{
this.telemetryClient.Context.InstrumentationKey = instrumentationKey;
var configuration = TelemetryConfiguration.CreateDefault();
configuration.ConnectionString = connectionString;

this.telemetryClient.TelemetryConfiguration.ConnectionString = connectionString;
}
else
{
string instrumentationKey = this.instrumentationKeyLayout.Render(LogEventInfo.CreateNullEvent());
if (!string.IsNullOrWhiteSpace(instrumentationKey))
{
this.telemetryClient.Context.InstrumentationKey = instrumentationKey;
}
}

this.telemetryClient.Context.GetInternalContext().SdkVersion = SdkVersionUtils.GetSdkVersion("nlog:");
Expand Down
105 changes: 97 additions & 8 deletions LOGGING/test/NLogTarget.Tests/NLogTargetTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -226,11 +226,11 @@ public void TraceHasCustomProperties()

var telemetry = (TraceTelemetry)this.adapterHelper.Channel.SentItems.FirstOrDefault();
Assert.IsNotNull(telemetry, "Didn't get the log event from the channel");
Assert.AreEqual("Value", telemetry.Properties["Name"]);
Assert.AreEqual("Value", telemetry.Properties["Name"]);
}


[TestMethod]
[TestMethod]
[TestCategory("NLogTarget")]
public void GlobalDiagnosticContextPropertiesAreAddedToProperties()
{
Expand Down Expand Up @@ -260,8 +260,8 @@ public void GlobalDiagnosticContextPropertiesSupplementEventProperties()
aiLogger.Log(eventInfo);

var telemetry = (TraceTelemetry)this.adapterHelper.Channel.SentItems.FirstOrDefault();
Assert.AreEqual("global_value", telemetry.Properties["global_prop"]);
Assert.AreEqual("Value", telemetry.Properties["Name"]);
Assert.AreEqual("global_value", telemetry.Properties["global_prop"]);
Assert.AreEqual("Value", telemetry.Properties["Name"]);
}

[TestMethod]
Expand All @@ -280,10 +280,10 @@ public void EventPropertyKeyNameIsAppendedWith_1_IfSameAsGlobalDiagnosticContext
aiLogger.Log(eventInfo);

var telemetry = (TraceTelemetry)this.adapterHelper.Channel.SentItems.FirstOrDefault();
Assert.IsTrue(telemetry.Properties.ContainsKey("Name"));
Assert.AreEqual("Global Value", telemetry.Properties["Name"]);
Assert.IsTrue(telemetry.Properties.ContainsKey("Name_1"), "Key name altered");
Assert.AreEqual("Value", telemetry.Properties["Name_1"]);
Assert.IsTrue(telemetry.Properties.ContainsKey("Name"));
Assert.AreEqual("Global Value", telemetry.Properties["Name"]);
Assert.IsTrue(telemetry.Properties.ContainsKey("Name_1"), "Key name altered");
Assert.AreEqual("Value", telemetry.Properties["Name_1"]);
}

[TestMethod]
Expand Down Expand Up @@ -459,6 +459,62 @@ public void NLogTargetFlushesTelemetryClient()
Assert.AreEqual("Flush called", flushException.Message);
}

[TestMethod]
[TestCategory("NLogTarget")]
public void NLogInfoIsSentAsInformationTraceItemWithAIConnectionString()
{
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("Your_ApplicationInsights_ConnectionString");
aiLogger.Error("Error Message");

var telemetry = (TraceTelemetry)this.adapterHelper.Channel.SentItems.FirstOrDefault();
Assert.AreEqual("Error Message", telemetry.Message);
}

private void VerifyMessagesInMockChannel(Logger aiLogger, string instrumentationKey)
{
aiLogger.Trace("Sample trace message");
Expand Down Expand Up @@ -504,5 +560,38 @@ private Logger CreateTargetWithGivenInstrumentationKey(

return aiLogger;
}

private Logger CreateTargetWithGivenConnectionString(
string connectionString = "Your_ApplicationInsights_ConnectionString",
Action<Logger> 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
};

LoggingRule rule = new LoggingRule("*", LogLevel.Trace, target);
LoggingConfiguration config = new LoggingConfiguration();
config.AddTarget("AITarget", target);
config.LoggingRules.Add(rule);

LogManager.Configuration = config;
Logger aiLogger = LogManager.GetLogger("AITarget");

if (loggerAction != null)
{
loggerAction(aiLogger);
target.Dispose();
return null;
}

return aiLogger;
}

}
}
9 changes: 7 additions & 2 deletions LOGGING/test/Shared/AdapterHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ 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");
Expand All @@ -27,16 +29,19 @@ 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")
public AdapterHelper(string instrumentationKey = "F8474271-D231-45B6-8DD4-D344C309AE69",
string connectionString= "Your_ApplicationInsights_ConnectionString")
{
this.InstrumentationKey = instrumentationKey;
this.ConnectionString = connectionString;

string configuration = string.Format(InvariantCulture,
@"<?xml version=""1.0"" encoding=""utf-8"" ?>
<ApplicationInsights xmlns=""http://schemas.microsoft.com/ApplicationInsights/2013/Settings"">
<InstrumentationKey>{0}</InstrumentationKey>
<ConnectionString>{1}</ConnectionString>
</ApplicationInsights>",
instrumentationKey);
instrumentationKey, connectionString);

File.WriteAllText(ApplicationInsightsConfigFilePath, configuration);
this.Channel = new CustomTelemetryChannel();
Expand Down

0 comments on commit 59b35e9

Please sign in to comment.