Skip to content

Commit 16c877a

Browse files
Merge pull request #3055 from microsoft/rajrang/aad
Entra Id - NLog update
2 parents 51ecd1e + 73c2867 commit 16c877a

File tree

5 files changed

+94
-19
lines changed

5 files changed

+94
-19
lines changed

.publicApi/Microsoft.ApplicationInsights.NLogTarget.dll/Stable/PublicAPI.Unshipped.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
Microsoft.ApplicationInsights.NLogTarget.ApplicationInsightsTarget
22
Microsoft.ApplicationInsights.NLogTarget.ApplicationInsightsTarget.ApplicationInsightsTarget() -> void
3-
Microsoft.ApplicationInsights.NLogTarget.ApplicationInsightsTarget.ContextProperties.get -> System.Collections.Generic.IList<Microsoft.ApplicationInsights.NLogTarget.TargetPropertyWithContext>
43
Microsoft.ApplicationInsights.NLogTarget.ApplicationInsightsTarget.ConnectionString.get -> string
54
Microsoft.ApplicationInsights.NLogTarget.ApplicationInsightsTarget.ConnectionString.set -> void
5+
Microsoft.ApplicationInsights.NLogTarget.ApplicationInsightsTarget.ContextProperties.get -> System.Collections.Generic.IList<Microsoft.ApplicationInsights.NLogTarget.TargetPropertyWithContext>
6+
Microsoft.ApplicationInsights.NLogTarget.ApplicationInsightsTarget.Credential.get -> Azure.Core.TokenCredential
7+
Microsoft.ApplicationInsights.NLogTarget.ApplicationInsightsTarget.Credential.set -> void
68
Microsoft.ApplicationInsights.NLogTarget.TargetPropertyWithContext
79
Microsoft.ApplicationInsights.NLogTarget.TargetPropertyWithContext.Layout.get -> NLog.Layouts.Layout
810
Microsoft.ApplicationInsights.NLogTarget.TargetPropertyWithContext.Layout.set -> void

LOGGING/README.md

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,19 +39,26 @@ If your application does not have web.config then it can also be configured manu
3939

4040
### Azure Active Directory (AAD) Authentication
4141

42-
To use AAD authentication with NLog, configure the TelemetryConfiguration before initializing NLog:
42+
To use AAD authentication with NLog, set the `Credential` property on the `ApplicationInsightsTarget`:
4343

4444
```csharp
45-
using Microsoft.ApplicationInsights.Extensibility;
45+
using Microsoft.ApplicationInsights.NLogTarget;
4646
using Azure.Identity;
4747
using NLog;
48+
using NLog.Config;
4849

49-
// Configure Application Insights with AAD authentication BEFORE NLog initialization
50-
var telemetryConfig = TelemetryConfiguration.CreateDefault();
51-
telemetryConfig.ConnectionString = "InstrumentationKey=YOUR_IKEY;IngestionEndpoint=https://ingestion-endpoint.applicationinsights.azure.com/";
52-
telemetryConfig.SetAzureTokenCredential(new DefaultAzureCredential());
50+
// Configure NLog programmatically with AAD
51+
var config = new LoggingConfiguration();
52+
var aiTarget = new ApplicationInsightsTarget
53+
{
54+
Name = "aiTarget",
55+
ConnectionString = "InstrumentationKey=YOUR_IKEY;IngestionEndpoint=https://ingestion-endpoint.applicationinsights.azure.com/",
56+
Credential = new DefaultAzureCredential() // Set AAD credential
57+
};
58+
config.AddTarget(aiTarget);
59+
config.AddRule(LogLevel.Trace, LogLevel.Fatal, aiTarget);
60+
LogManager.Configuration = config;
5361

54-
// Now initialize NLog - it will use the configured TelemetryConfiguration
5562
var logger = LogManager.GetCurrentClassLogger();
5663
logger.Info("Using AAD authentication");
5764
```

LOGGING/src/NLogTarget/ApplicationInsightsTarget.cs

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,16 @@ namespace Microsoft.ApplicationInsights.NLogTarget
1010
using System;
1111
using System.Collections.Generic;
1212
using System.Globalization;
13+
using Azure.Core;
1314
using Microsoft.ApplicationInsights.Channel;
1415
using Microsoft.ApplicationInsights.DataContracts;
1516
using Microsoft.ApplicationInsights.Extensibility;
1617
using NLog;
1718
using NLog.Common;
1819
using NLog.Config;
1920
using NLog.Targets;
21+
using OpenTelemetry;
22+
using OpenTelemetry.Resources;
2023

2124
/// <summary>
2225
/// NLog Target that routes all logging output to the Application Insights logging framework.
@@ -41,6 +44,13 @@ public ApplicationInsightsTarget()
4144
this.OptimizeBufferReuse = true;
4245
}
4346

47+
/// <summary>
48+
/// Gets or sets the Azure Active Directory (AAD) TokenCredential for authentication.
49+
/// When set, this credential will be used to authenticate with Azure Monitor.
50+
/// </summary>
51+
[CLSCompliant(false)]
52+
public TokenCredential Credential { get; set; }
53+
4454
/// <summary>
4555
/// Gets or sets the Application Insights connection string for your application.
4656
/// </summary>
@@ -122,10 +132,23 @@ protected override void InitializeTarget()
122132

123133
this.telemetryConfiguration = new TelemetryConfiguration();
124134
this.telemetryConfiguration.ConnectionString = connectionString;
135+
136+
// Configure OpenTelemetry resource with distro name
137+
this.telemetryConfiguration.ConfigureOpenTelemetryBuilder(builder =>
138+
{
139+
builder.ConfigureResource(r => r.AddAttributes(new[]
140+
{
141+
new System.Collections.Generic.KeyValuePair<string, object>("telemetry.distro.name", "Microsoft.ApplicationInsights.NLogTarget"),
142+
}));
143+
});
144+
145+
// Set AAD credential if provided
146+
if (this.Credential != null)
147+
{
148+
this.telemetryConfiguration.SetAzureTokenCredential(this.Credential);
149+
}
150+
125151
this.telemetryClient = new TelemetryClient(this.telemetryConfiguration);
126-
127-
// TODO: Uncomment once SdkVersionUtils is available.
128-
// this.telemetryClient.Context.GetInternalContext().SdkVersion = SdkVersionUtils.GetSdkVersion("nlog:");
129152
}
130153

131154
/// <summary>

LOGGING/test/NLogTarget.Tests/NLogTargetTests.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,20 @@ public void ExceptionsDoNotEscapeNLog()
9494
logger.Trace("Hello World");
9595
}
9696

97+
[Trait("Category", "NLogTarget")]
98+
[Fact]
99+
public void CredentialPropertyCanBeSetAndRetrieved()
100+
{
101+
var mockCredential = new MockTokenCredential();
102+
var target = new ApplicationInsightsTarget
103+
{
104+
ConnectionString = DefaultConnectionString,
105+
Credential = mockCredential
106+
};
107+
108+
Assert.Same(mockCredential, target.Credential);
109+
}
110+
97111
[Fact]
98112
[Trait("Category", "NLogTarget")]
99113
public async Task TracesAreCapturedByExporter()
@@ -580,4 +594,18 @@ private static string NormalizeConnectionString(string value)
580594
return (SeverityLevel)severity.Value;
581595
}
582596
}
597+
598+
// Mock TokenCredential for testing
599+
internal class MockTokenCredential : Azure.Core.TokenCredential
600+
{
601+
public override Azure.Core.AccessToken GetToken(Azure.Core.TokenRequestContext requestContext, CancellationToken cancellationToken)
602+
{
603+
return new Azure.Core.AccessToken("mock_token", DateTimeOffset.UtcNow.AddHours(1));
604+
}
605+
606+
public override ValueTask<Azure.Core.AccessToken> GetTokenAsync(Azure.Core.TokenRequestContext requestContext, CancellationToken cancellationToken)
607+
{
608+
return new ValueTask<Azure.Core.AccessToken>(GetToken(requestContext, cancellationToken));
609+
}
610+
}
583611
}

examples/NLogConsoleApp/Program.cs

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,36 @@
11
using NLog;
2-
// Uncomment these for Azure Active Directory (AAD) authentication
3-
// using Microsoft.ApplicationInsights.Extensibility;
4-
// using Azure.Identity;
52

63
Console.WriteLine("NLog Console App - Application Insights Example");
74
Console.WriteLine("================================================\n");
85

96
NLog.Common.InternalLogger.LogToConsole = true;
107
NLog.Common.InternalLogger.LogLevel = NLog.LogLevel.Warn;
118

9+
/*
1210
// Optional: Configure Azure Active Directory (AAD) authentication
13-
// This must be done BEFORE LogManager.GetCurrentClassLogger() is called
1411
// Requires: Install-Package Azure.Identity
15-
/*
16-
var telemetryConfig = TelemetryConfiguration.CreateDefault();
17-
telemetryConfig.ConnectionString = "InstrumentationKey=YOUR_IKEY;IngestionEndpoint=https://ingestion-endpoint.applicationinsights.azure.com/";
18-
telemetryConfig.SetAzureTokenCredential(new DefaultAzureCredential());
12+
13+
var config = new LoggingConfiguration();
14+
15+
// Add console target so you can see the output
16+
var consoleTarget = new NLog.Targets.ConsoleTarget("console")
17+
{
18+
Layout = "${longdate}|${level:uppercase=true}|${logger}|${message} ${exception:format=tostring}"
19+
};
20+
config.AddTarget(consoleTarget);
21+
config.AddRule(LogLevel.Trace, LogLevel.Fatal, consoleTarget);
22+
23+
// Add AI target with AAD
24+
var aiTarget = new ApplicationInsightsTarget
25+
{
26+
Name = "aiTarget",
27+
ConnectionString = "InstrumentationKey=YOUR_IKEY;IngestionEndpoint=https://ingestion-endpoint.applicationinsights.azure.com/",
28+
Credential = new DefaultAzureCredential()
29+
};
30+
config.AddTarget("aiTarget", aiTarget);
31+
config.AddRule(LogLevel.Info, LogLevel.Fatal, aiTarget);
32+
33+
LogManager.Configuration = config;
1934
*/
2035

2136
// Get NLog logger - the ApplicationInsightsTarget will handle telemetry

0 commit comments

Comments
 (0)