Search code examples
c#azureazure-application-insights

Live Metrics Displaying <Empty Role> in Application Insights


Hi all I am having an issue while setting up live metrics for my app, following the guidance provided in this thread:

Unable to configure Live Stream in Application Insights for ASP Core application

I've managed to obtain live metrics, but they're displayed with the label < Empty Role>, as shown in the screenshots below:enter image description here

This behaviour is consistent in the performance tab as well: enter image description here

I attempted to set the role name using telemetry.Context.Cloud.RoleName = "tempRoleName"; but this approach only overrides the role name in the performance tab, leaving no role name in the live metrics page.

Below is the code where I am trying to solve this problem, if anyone is able to help me that would be really appreciated, thank you so much.

using Microsoft.ApplicationInsights;
using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.QuickPulse;
using Microsoft.Extensions.DependencyInjection;
using MongoDB.Driver;
using MongoDB.Driver.Core.Events;
using System.Diagnostics;
using System.Text.Json;

namespace Functions.Extensions.MongoDb
{
    public static class MongoDbTelemetryExtensions
    {
        public static readonly JsonSerializerOptions JsonOptions = new(JsonSerializerDefaults.Web);

        public static IServiceCollection AddMongoClientWithDependencyTelemetry(this IServiceCollection services, string connectionSettingName, double maxTelemetryItemsPerSecond, string? excludedTypes = null, string? includedTypes = null)
        {
            ArgumentNullException.ThrowIfNull(connectionSettingName);

            // Read connection string from local.settings.json
            var connectionString = Environment.GetEnvironmentVariable(connectionSettingName) ?? throw new InvalidOperationException("Connection string missing");

            var mongoClientSettings = MongoClientSettings.FromConnectionString(connectionString);

            TelemetryConfiguration configuration = TelemetryConfiguration.CreateDefault();

            if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("APPLICATIONINSIGHTS_CONNECTION_STRING")))
                configuration.ConnectionString = Environment.GetEnvironmentVariable("APPLICATIONINSIGHTS_CONNECTION_STRING");

            var chainBuilder = configuration.DefaultTelemetrySink.TelemetryProcessorChainBuilder;

            chainBuilder.UseAdaptiveSampling(maxTelemetryItemsPerSecond: maxTelemetryItemsPerSecond, excludedTypes: excludedTypes, includedTypes: includedTypes);

            chainBuilder.Build();

            // Enable Live Metrics
            QuickPulseTelemetryProcessor processor = null!;
            configuration.TelemetryProcessorChainBuilder
                .Use((next) =>
                {
                    processor = new QuickPulseTelemetryProcessor(next);
                    return processor;
                })
                .Build();

            var quickPulse = new QuickPulseTelemetryModule();
            quickPulse.Initialize(configuration);
            quickPulse.RegisterTelemetryProcessor(processor);

            var telemetry = new TelemetryClient(configuration);

            //TRIED TO OVERRIDE THE ROLE NAME
            telemetry.Context.Cloud.RoleName = "tempRoleName";

            mongoClientSettings.ClusterConfigurator = config =>
            {
                config.Subscribe<CommandSucceededEvent>(e =>
                {
                    telemetry.Context.Operation.Id = Activity.Current?.RootId;
                    telemetry.TrackDependency($"MongoDb ({e.DatabaseNamespace})", e.CommandName, null, e.Timestamp, e.Duration, true);
                });
                config.Subscribe<CommandFailedEvent>(e =>
                {
                    telemetry.Context.Operation.Id = Activity.Current?.RootId;
                    telemetry.TrackDependency(nameof(MongoDB), e.CommandName, null, e.Timestamp, e.Duration, false);
                });
            };           

            services.AddSingleton(telemetry)
                    .AddSingleton<IMongoClient>((sp) =>
                       {
                           return new MongoClient(mongoClientSettings);
                       });

            // Test
            var testCounter = 5;
           
            while (testCounter > 0)
            {
                testCounter--;
                // Send dependency and request telemetry.
                // These will be shown in Live Metrics.
                // CPU/Memory Performance counter is also shown
                // automatically without any additional steps.
                telemetry.TrackDependency("My dependency", "target", "http://sample",
                    DateTimeOffset.Now, TimeSpan.FromMilliseconds(300), true);
                telemetry.TrackRequest("My Request test", DateTimeOffset.Now,
                    TimeSpan.FromMilliseconds(230), "200", true);
                Task.Delay(1000).Wait();
            }
            // Test

            return services;


        }       
    }
}

Solution

  • I've managed to obtain live metrics, but they're displayed with the label < Empty Role>

    • I have configured Application Insights from Connected Services in a sample .NET Core Application and deployed to Azure App Service.

    enter image description here

    • Without any changes I am able to see the role name(as Azure App Service name) in Live metrics.

    enter image description here

    • I have tried to set and override the rolename from code.

    • Add a new class file with CustomRoleName.cs.

    My Custom class file:

    using Microsoft.ApplicationInsights.Channel;
    using Microsoft.ApplicationInsights.Extensibility;
    
    namespace WebApplication1
    {
        public class CustomRoleName : ITelemetryInitializer
        {
            private readonly string RName;
    
            public CustomRoleName(string roleName)
            {
                this.RName = roleName;
            }
    
            public void Initialize(ITelemetry tel)
            {
                if (tel.Context.Cloud.RoleName == null)
                {
                    tel.Context.Cloud.RoleName = RName;
                }
            }
        }
    }
    
    • Register the custom class in Program.cs file and set the RoleName.

    My Program.cs file:

    builder.Services.AddRazorPages();
    builder.Services.AddApplicationInsightsTelemetry(new Microsoft.ApplicationInsights.AspNetCore.Extensions.ApplicationInsightsServiceOptions
    {
        ConnectionString = builder.Configuration["APPLICATIONINSIGHTS_CONNECTION_STRING"]
    });
    builder.Services.AddSingleton<ITelemetryInitializer>(new CustomRoleName("SampleRoleName"));
    

    My .csproj file:

    <Project Sdk="Microsoft.NET.Sdk.Web">
    
      <PropertyGroup>
        <TargetFramework>net6.0</TargetFramework>
        <Nullable>enable</Nullable>
        <ImplicitUsings>enable</ImplicitUsings>
        <ApplicationInsightsResourceId>/subscriptions/b83c1ed3-c5b6-44fb-b5ba-2b83a074c23f/resourceGroups/*****/providers/microsoft.insights/components/AppRoleNames</ApplicationInsightsResourceId>
        <UserSecretsId>**********</UserSecretsId>
      </PropertyGroup>
    
      <ItemGroup>
        <PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.21.0" />
      </ItemGroup>
    </Project>
    
    • You can see the same in Live Metrics and Performance as well.

    Output:

    enter image description here

    enter image description here

    enter image description here