diff --git a/src/Microsoft.Azure.WebJobs.Logging.ApplicationInsights/DefaultTelemetryClientFactory.cs b/src/Microsoft.Azure.WebJobs.Logging.ApplicationInsights/DefaultTelemetryClientFactory.cs
index 905986414..561407cf8 100644
--- a/src/Microsoft.Azure.WebJobs.Logging.ApplicationInsights/DefaultTelemetryClientFactory.cs
+++ b/src/Microsoft.Azure.WebJobs.Logging.ApplicationInsights/DefaultTelemetryClientFactory.cs
@@ -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;
@@ -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());
diff --git a/src/Microsoft.Azure.WebJobs.Logging.ApplicationInsights/WebJobs.Logging.ApplicationInsights.csproj b/src/Microsoft.Azure.WebJobs.Logging.ApplicationInsights/WebJobs.Logging.ApplicationInsights.csproj
index 00df1a262..48d26f242 100644
--- a/src/Microsoft.Azure.WebJobs.Logging.ApplicationInsights/WebJobs.Logging.ApplicationInsights.csproj
+++ b/src/Microsoft.Azure.WebJobs.Logging.ApplicationInsights/WebJobs.Logging.ApplicationInsights.csproj
@@ -147,6 +147,7 @@
+
diff --git a/src/Microsoft.Azure.WebJobs.Logging.ApplicationInsights/WebJobsRoleEnvironmentTelmetryInitializer.cs b/src/Microsoft.Azure.WebJobs.Logging.ApplicationInsights/WebJobsRoleEnvironmentTelmetryInitializer.cs
new file mode 100644
index 000000000..224c2383c
--- /dev/null
+++ b/src/Microsoft.Azure.WebJobs.Logging.ApplicationInsights/WebJobsRoleEnvironmentTelmetryInitializer.cs
@@ -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.
+
+ ///
+ /// A telemetry initializer that will gather Azure Web App Role Environment context information.
+ ///
+ 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";
+
+ ///
+ /// Initializes device context.
+ ///
+ /// The telemetry to initialize.
+ 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;
+ }
+
+ ///
+ /// Gets a value that uniquely identifies the site and slot.
+ ///
+ 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();
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/Microsoft.Azure.WebJobs.Host.UnitTests/Loggers/DefaultTelemetryClientFactoryTests.cs b/test/Microsoft.Azure.WebJobs.Host.UnitTests/Loggers/DefaultTelemetryClientFactoryTests.cs
index d55b426c2..95f10a7ba 100644
--- a/test/Microsoft.Azure.WebJobs.Host.UnitTests/Loggers/DefaultTelemetryClientFactoryTests.cs
+++ b/test/Microsoft.Azure.WebJobs.Host.UnitTests/Loggers/DefaultTelemetryClientFactoryTests.cs
@@ -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;
@@ -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().Single();
+ config.TelemetryInitializers.OfType().Single();
config.TelemetryInitializers.OfType().Single();
// Verify Channel
diff --git a/test/Microsoft.Azure.WebJobs.Host.UnitTests/Loggers/WebJobsRoleEnvironmentTelemetryInitializerTests.cs b/test/Microsoft.Azure.WebJobs.Host.UnitTests/Loggers/WebJobsRoleEnvironmentTelemetryInitializerTests.cs
new file mode 100644
index 000000000..176cd948e
--- /dev/null
+++ b/test/Microsoft.Azure.WebJobs.Host.UnitTests/Loggers/WebJobsRoleEnvironmentTelemetryInitializerTests.cs
@@ -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);
+ }
+ }
+}
diff --git a/test/Microsoft.Azure.WebJobs.Host.UnitTests/WebJobs.Host.UnitTests.csproj b/test/Microsoft.Azure.WebJobs.Host.UnitTests/WebJobs.Host.UnitTests.csproj
index 1c7254f99..e48e8b355 100644
--- a/test/Microsoft.Azure.WebJobs.Host.UnitTests/WebJobs.Host.UnitTests.csproj
+++ b/test/Microsoft.Azure.WebJobs.Host.UnitTests/WebJobs.Host.UnitTests.csproj
@@ -316,6 +316,7 @@
+