Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
using Microsoft.ApplicationInsights.Extensibility.Implementation;
using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector;
using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.QuickPulse;
using Microsoft.ApplicationInsights.WindowsServer;
using Microsoft.ApplicationInsights.WindowsServer.Channel.Implementation;
using Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel;
using Microsoft.Extensions.Logging;
Expand Down Expand Up @@ -142,7 +141,7 @@ protected virtual QuickPulseTelemetryModule CreateQuickPulseTelemetryModule()
internal static void AddInitializers(TelemetryConfiguration config)
{
// This picks up the RoleName from the server
config.TelemetryInitializers.Add(new AzureWebAppRoleEnvironmentTelemetryInitializer());
config.TelemetryInitializers.Add(new WebJobsRoleEnvironmentTelemetryInitializer());

// This applies our special scope properties and gets RoleInstance name
config.TelemetryInitializers.Add(new WebJobsTelemetryInitializer());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@
<Compile Include="GlobalSuppressions.cs" />
<Compile Include="ITelemetryClientFactory.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="WebJobsRoleEnvironmentTelmetryInitializer.cs" />
<Compile Include="WebJobsTelemetryInitializer.cs" />
</ItemGroup>
<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

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

namespace Microsoft.Azure.WebJobs.Logging.ApplicationInsights
{
// This class was taken largely from https://raw.githubusercontent.com/Microsoft/ApplicationInsights-dotnet-server/91016d62f3181e10d4cf589ef8fd64dadb6b54a2/Src/WindowsServer/WindowsServer.Shared/AzureWebAppRoleEnvironmentTelemetryInitializer.cs,
// but refactored so that it did not use WEBSITE_HOSTNAME, which is determined to be unreliable for functions during slot swaps.

/// <summary>
/// A telemetry initializer that will gather Azure Web App Role Environment context information.
/// </summary>
internal class WebJobsRoleEnvironmentTelemetryInitializer : ITelemetryInitializer
{
internal const string AzureWebsiteName = "WEBSITE_SITE_NAME";
internal const string AzureWebsiteSlotName = "WEBSITE_SLOT_NAME";
private const string DefaultProductionSlotName = "production";
private const string WebAppSuffix = ".azurewebsites.net";

/// <summary>
/// Initializes <see cref="ITelemetry" /> device context.
/// </summary>
/// <param name="telemetry">The telemetry to initialize.</param>
public void Initialize(ITelemetry telemetry)
{
if (telemetry == null)
{
return;
}

// We cannot cache these values as the environment variables can change on the fly.
if (string.IsNullOrEmpty(telemetry.Context.Cloud.RoleName))
{
telemetry.Context.Cloud.RoleName = GetRoleName();
}

if (string.IsNullOrEmpty(telemetry.Context.GetInternalContext().NodeName))
{
telemetry.Context.GetInternalContext().NodeName = GetNodeName();
}
}

private static string GetRoleName()
{
return GetAzureWebsiteUniqueSlotName();
}

private static string GetNodeName()
{
string name = GetAzureWebsiteUniqueSlotName();

if (!string.IsNullOrEmpty(name))
{
// maintain previous behavior of node having the full url
name = name + WebAppSuffix;
}

return name;
}

/// <summary>
/// Gets a value that uniquely identifies the site and slot.
/// </summary>
private static string GetAzureWebsiteUniqueSlotName()
{
string name = Environment.GetEnvironmentVariable(AzureWebsiteName);
string slotName = Environment.GetEnvironmentVariable(AzureWebsiteSlotName);

if (!string.IsNullOrEmpty(slotName) &&
!string.Equals(slotName, DefaultProductionSlotName, StringComparison.OrdinalIgnoreCase))
{
name += $"-{slotName}";
}

return name?.ToLowerInvariant();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Licensed under the MIT License. See License.txt in the project root for license information.

using System.Linq;
using Microsoft.ApplicationInsights.WindowsServer;
using Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel;
using Microsoft.Azure.WebJobs.Logging.ApplicationInsights;
using Xunit;
Expand All @@ -20,7 +19,7 @@ public void InitializeConfiguguration_Configures()
// Verify Initializers
Assert.Equal(2, config.TelemetryInitializers.Count);
// These will throw if there are not exactly one
config.TelemetryInitializers.OfType<AzureWebAppRoleEnvironmentTelemetryInitializer>().Single();
config.TelemetryInitializers.OfType<WebJobsRoleEnvironmentTelemetryInitializer>().Single();
config.TelemetryInitializers.OfType<WebJobsTelemetryInitializer>().Single();

// Verify Channel
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System;
using Microsoft.ApplicationInsights.DataContracts;
using Microsoft.ApplicationInsights.Extensibility.Implementation;
using Microsoft.Azure.WebJobs.Logging.ApplicationInsights;
using Xunit;

namespace Microsoft.Azure.WebJobs.Host.UnitTests.Loggers
{
public class WebJobsRoleEnvironmentTelemetryInitializerTests : IDisposable
{
public WebJobsRoleEnvironmentTelemetryInitializerTests()
{
// make sure these are clear before each test
SetEnvironmentVariables(null, null);
}

[Fact]
public void Initialize_DoesNotThrow_WhenNoEnvironmentVariables()
{
var initializer = new WebJobsRoleEnvironmentTelemetryInitializer();

var telemetry = new TraceTelemetry();
initializer.Initialize(telemetry);

Assert.Null(telemetry.Context.Cloud.RoleName);
Assert.Null(telemetry.Context.GetInternalContext().NodeName);
}

[Fact]
public void Initialize_WithSlot()
{
SetEnvironmentVariables("mytestsite", "Staging");

var initializer = new WebJobsRoleEnvironmentTelemetryInitializer();

var telemetry = new TraceTelemetry();
initializer.Initialize(telemetry);

Assert.Equal("mytestsite-staging", telemetry.Context.Cloud.RoleName);
Assert.Equal("mytestsite-staging.azurewebsites.net", telemetry.Context.GetInternalContext().NodeName);
}

[Fact]
public void Initialize_WithProductionSlot()
{
SetEnvironmentVariables("mytestsite", "Production");

var initializer = new WebJobsRoleEnvironmentTelemetryInitializer();

var telemetry = new TraceTelemetry();
initializer.Initialize(telemetry);

Assert.Equal("mytestsite", telemetry.Context.Cloud.RoleName);
Assert.Equal("mytestsite.azurewebsites.net", telemetry.Context.GetInternalContext().NodeName);
}

private static void SetEnvironmentVariables(string websiteName, string slotName)
{
Environment.SetEnvironmentVariable(WebJobsRoleEnvironmentTelemetryInitializer.AzureWebsiteName, websiteName);
Environment.SetEnvironmentVariable(WebJobsRoleEnvironmentTelemetryInitializer.AzureWebsiteSlotName, slotName);
}

public void Dispose()
{
SetEnvironmentVariables(null, null);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,7 @@
<Compile Include="Loggers\LoggerExtensionsTests.cs" />
<Compile Include="Loggers\TestTelemetryChannel.cs" />
<Compile Include="Loggers\TraceWriterFunctionInstanceLoggerTests.cs" />
<Compile Include="Loggers\WebJobsRoleEnvironmentTelemetryInitializerTests.cs" />
<Compile Include="NullExtensionTypeLocator.cs" />
<Compile Include="Protocols\FunctionStartedMessageExtensionsTests.cs" />
<Compile Include="Protocols\ProtocolSerializationTests.cs" />
Expand Down