Skip to content

Commit

Permalink
[AzureMonitorDistro] Read APPLICATIONINSIGHTS_CONNECTION_STRING from …
Browse files Browse the repository at this point in the history
…IConfiguration (#45292)

* Fix: Read APPLICATIONINSIGHTS_CONNECTION_STRING from IConfiguration if not set via Action<AzureMonitorOptions>

* changelog patch
  • Loading branch information
rajkumar-rangaraj authored Jul 31, 2024
1 parent 4503f47 commit d15d4aa
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@

### Bugs Fixed

* Fixed an issue where `APPLICATIONINSIGHTS_CONNECTION_STRING` was not read from
`IConfiguration` when using the `UseAzureMonitor` overload with the
`Action<AzureMonitorOptions>` parameter. If the connection string is not set
using the `Action<AzureMonitorOptions>` delegate, the distro will now check if
`APPLICATIONINSIGHTS_CONNECTION_STRING` is present in `IConfiguration`.
([#45292](https://github.com/Azure/azure-sdk-for-net/pull/45292))

### Other Changes

## 1.3.0-beta.1 (2024-07-12)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using Azure.Monitor.OpenTelemetry.Exporter.Internals.Platform;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;

Expand All @@ -10,7 +10,6 @@ namespace Azure.Monitor.OpenTelemetry.AspNetCore
internal class DefaultAzureMonitorOptions : IConfigureOptions<AzureMonitorOptions>
{
private const string AzureMonitorSectionFromConfig = "AzureMonitor";
private const string ConnectionStringEnvironmentVariable = "APPLICATIONINSIGHTS_CONNECTION_STRING";
private readonly IConfiguration? _configuration;

/// <summary>
Expand All @@ -31,15 +30,15 @@ public void Configure(AzureMonitorOptions options)
_configuration.GetSection(AzureMonitorSectionFromConfig).Bind(options);

// IConfiguration can read from EnvironmentVariables or InMemoryCollection if configured to do so.
var connectionStringFromIConfig = _configuration[ConnectionStringEnvironmentVariable];
var connectionStringFromIConfig = _configuration[EnvironmentVariableConstants.APPLICATIONINSIGHTS_CONNECTION_STRING];
if (!string.IsNullOrEmpty(connectionStringFromIConfig))
{
options.ConnectionString = connectionStringFromIConfig;
}
}

// Environment Variable should take precedence.
var connectionStringFromEnvVar = Environment.GetEnvironmentVariable(ConnectionStringEnvironmentVariable);
var connectionStringFromEnvVar = Environment.GetEnvironmentVariable(EnvironmentVariableConstants.APPLICATIONINSIGHTS_CONNECTION_STRING);
if (!string.IsNullOrEmpty(connectionStringFromEnvVar))
{
options.ConnectionString = connectionStringFromEnvVar;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,12 @@ public static OpenTelemetryBuilder UseAzureMonitor(this OpenTelemetryBuilder bui
{
config[EnvironmentVariableConstants.HTTPCLIENT_DISABLE_URL_QUERY_REDACTION] = Boolean.TrueString;
}

// If connection string is not set in the options, try to get it from configuration.
if (string.IsNullOrWhiteSpace(options.ConnectionString) && config[EnvironmentVariableConstants.APPLICATIONINSIGHTS_CONNECTION_STRING] != null)
{
options.ConnectionString = config[EnvironmentVariableConstants.APPLICATIONINSIGHTS_CONNECTION_STRING];
}
});

return builder;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Azure.Monitor.OpenTelemetry.Exporter;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using OpenTelemetry.Trace;
using Xunit;

namespace Azure.Monitor.OpenTelemetry.AspNetCore.Tests
{
public class OpenTelemetryBuilderExtensionsTests
{
#if !NETFRAMEWORK
private const string ConnectionStringEnvironmentVariable = "APPLICATIONINSIGHTS_CONNECTION_STRING";

[Theory]
[InlineData(false, false, false, false, false, false, null)] // If nothing set, ConnectionString will be null.
[InlineData(true, false, false, false, false, false, null)] // If nothing set, ConnectionString will be null.
[InlineData(false, true, false, false, false, false, "testJsonValue")] // only AzureMonitor in json
[InlineData(true, true, false, false, false, false, null)] // only AzureMonitor in json
[InlineData(false, false, true, false, false, false, "testJsonEnvVarValue")] // only EnvVar in json
[InlineData(true, false, true, false, false, false, "testJsonEnvVarValue")] // only EnvVar in json
[InlineData(false, true, true, false, false, false, "testJsonEnvVarValue")] // both AzureMonitor & EnvVar in json
[InlineData(true, true, true, false, false, false, "testJsonEnvVarValue")] // both AzureMonitor & EnvVar in json
[InlineData(false, false, false, true, false, false, "testInMemoryCollectionValue")] // only IConfig InMemoryCollection
[InlineData(true, false, false, true, false, false, "testInMemoryCollectionValue")] // only IConfig InMemoryCollection
[InlineData(false, false, false, false, true, false, null)] // only IConfig EnvVars, without EnvVar set.
[InlineData(true, false, false, false, true, false, null)] // only IConfig EnvVars, without EnvVar set.
[InlineData(false, false, false, false, true, true, "testEnvVarValue")] // only IConfig EnvVars, with EnvVar set.
[InlineData(true, false, false, false, true, true, "testEnvVarValue")] // only IConfig EnvVars, with EnvVar set.
[InlineData(false, false, false, true, true, true, "testEnvVarValue")] // both IConfig InMemoryCollection & IConfig EnvVars with EnvVar set
[InlineData(true, false, false, true, true, true, "testEnvVarValue")] // both IConfig InMemoryCollection & IConfig EnvVars with EnvVar set
[InlineData(false, false, false, true, true, false, "testInMemoryCollectionValue")] // both IConfig InMemoryCollection & IConfig EnvVars without EnvVar set
[InlineData(true, false, false, true, true, false, "testInMemoryCollectionValue")] // both IConfig InMemoryCollection & IConfig EnvVars without EnvVar set
[InlineData(false, false, false, false, false, true, "testEnvVarValue")] // only EnvironmentVariable
[InlineData(true, false, false, false, false, true, "testEnvVarValue")] // only EnvironmentVariable
[InlineData(false, true, true, true, true, true, "testEnvVarValue")]
[InlineData(true, true, true, true, true, true, "testEnvVarValue")]
public void Verify_UseAzureMonitor_SetsConnectionString(bool useConfigure, bool jsonAzureMonitor, bool jsonEnvVar, bool iconfigCollection, bool iconfigEnvVar, bool setEnvVar, string expectedConnectionStringValue)
{
try
{
Environment.SetEnvironmentVariable(ConnectionStringEnvironmentVariable, setEnvVar ? "testEnvVarValue" : null);

// BUILD JSON STRING
var jsonString = "{";

if (jsonAzureMonitor)
{
jsonString += @"""AzureMonitor"":{ ""ConnectionString"" : ""testJsonValue"" }";
}

if (jsonAzureMonitor && jsonEnvVar)
{
jsonString += ",";
}

if (jsonEnvVar)
{
jsonString += @"""APPLICATIONINSIGHTS_CONNECTION_STRING"" : ""testJsonEnvVarValue""";
}

jsonString += "}";

// BUILD CONFIGURATION OBJECT
var configBulider = new ConfigurationBuilder();
bool usesConfigBuilder = false;

if (jsonAzureMonitor || jsonEnvVar)
{
configBulider.AddJsonStream(new MemoryStream(Encoding.UTF8.GetBytes(jsonString)));
usesConfigBuilder = true;
}

if (iconfigCollection)
{
configBulider.AddInMemoryCollection(new Dictionary<string, string?> { [ConnectionStringEnvironmentVariable] = "testInMemoryCollectionValue" });
usesConfigBuilder = true;
}

if (iconfigEnvVar)
{
configBulider.AddEnvironmentVariables();
}

// ACT
var serviceCollection = new ServiceCollection();

if (usesConfigBuilder)
{
var configuration = configBulider.Build();
serviceCollection.AddSingleton<IConfiguration>(configuration);
}

if (useConfigure)
{
serviceCollection.AddOpenTelemetry().UseAzureMonitor(x => { });
}
else
{
serviceCollection.AddOpenTelemetry().UseAzureMonitor();
}

using var serviceProvider = serviceCollection.BuildServiceProvider();

// ASSERT
var azureMonitorOptions = serviceProvider.GetServices<IOptions<AzureMonitorOptions>>().Single().Value;
Assert.Equal(expectedConnectionStringValue, azureMonitorOptions.ConnectionString);

var azureMonitorExporterOptions = serviceProvider.GetServices<IOptions<AzureMonitorExporterOptions>>().Single().Value;
Assert.Equal(expectedConnectionStringValue, azureMonitorExporterOptions.ConnectionString);
}
finally
{
Environment.SetEnvironmentVariable(ConnectionStringEnvironmentVariable, null);
}
}
#endif
}
}

0 comments on commit d15d4aa

Please sign in to comment.