Valuator
Valuator

Reputation: 3617

Enable ApplicationInsights based on Configuration

I want Azure ApplicationInsights to only be used in an ASP.NET Core application if specified by a Configuration value that is set in appsettings.json.

I put this in my _Layout.cshml to disable client-side insights:

    @if (Configuration.GetSection("UseInsights").Get<bool>())
    {
        @Html.Raw(JavaScriptSnippet.FullScript)
    }

But server-side telemetry is still sent, so I added this when its disabled via Configuration:

TelemetryConfiguration.Active.DisableTelemetry = true;

This stopped Request and Exception data from being sent, but things like CPU usage were still being sent and visible on my Insights dashboard.

What I think would be the proper method is to enable the .UseApplicationInsights() extension on WebHost.CreateDefaultBuilder() conditionally, but this is a chicken and egg scenario since I don't have access to the Configuration settings until after the Host has been built. Is there somewhere I can fully disable insights after calling BuildWebHost()?

Upvotes: 0

Views: 1908

Answers (2)

Valuator
Valuator

Reputation: 3617

Here is what I did to completely get rid of any Azure Application Insights when disabled.

I created an Interface for the JavaScript snippet that gets injected for client-side telemetry:

public interface IInsightsJavaScriptSnippet
{
    string FullScript { get; }
}

With two implementations, one that wraps Microsoft.ApplicationInsights.AspNetCore.JavaScriptSnippet for when Insights are enabled:

public class InsightsJavaScriptSnippet : IInsightsJavaScriptSnippet
{
    private readonly JavaScriptSnippet _snippet;

    public InsightsJavaScriptSnippet(JavaScriptSnippet snippet)
    {
        _snippet = snippet;
    }

    public string FullScript => _snippet.FullScript;
}

And another that outputs an empty string for when they are not:

public class BlankJavaScriptSnippet : IInsightsJavaScriptSnippet
{
    public string FullScript => string.Empty;
}

I then register one or the other depending on the Configuration value. services.AddApplicationInsightsTelemetry() will register JavaScriptSnippet which will then be injected into the constructor for my InsightsJavaScriptSnippet:

if (Configuration.GetSection("UseInsights").Get<bool>())
        {
            services.AddApplicationInsightsTelemetry(Configuration["ApplicationInsights:InstrumentationKey"]);
            services.AddSingleton<IInsightsJavaScriptSnippet, InsightsJavaScriptSnippet>();
        }
        else
        {
            services.AddSingleton<IInsightsJavaScriptSnippet, BlankJavaScriptSnippet>();
        }

Then, I inject IInsightsJavaScriptSnippet into _Layout.cshtml instead of the Microsoft JavaScriptSnippet:

@inject MyApp.Services.IInsightsJavaScriptSnippet JavaScriptSnippet
// ... snipped code
<head>
    @Html.Raw(JavaScriptSnippet.FullScript)
</head>

Which adds nothing to the HTML if we aren't using Insights.

Upvotes: 2

cijothomas
cijothomas

Reputation: 3126

{ "ApplicationInsights": { "InstrumentationKey": "11111111-2222-3333-4444-555555555555" } }

You can control server side telemetry by the presence/absence of instrumentation key in appsettings.json. You may have separate appsettings.json for each environment, and each can contain different instrumentation keys, or do not contain anything at all if you do not want telemetry to be sent to ApplicationInsights service as shown below.

{ "ApplicationInsights": { "InstrumentationKey": "" } }

Upvotes: 1

Related Questions