Julian Wen Hsi Lee
Julian Wen Hsi Lee

Reputation: 206

Application Insights Not Receiving Any Data

I'm trying to set up a connection between a .NET Core app that I am using, and Azure Application Insights. The app itself is an API app, where the back end is split into a number of service layers.

Based on code that I've found online, it appears that this should be the bare minimum to get it to work:

TelemetryClient telemetry = new TelemetryClient(TelemetryConfiguration.CreateDefault());
telemetry.InstrumentationKey = "<my instrumentation key>";
telemetry.TrackEvent("Hello event");
telemetry.TrackPageView("Hello event page view");
telemetry.TrackException(new Exception());
telemetry.TrackTrace("Hello trace message");

I am able to go past the code above without any known issues (i.e. no debugger failures, or no displayed errors). However, inspecting on the Network tab in Chrome Inspector, I can see the call to my API function being made, but no tracking call sent to Application Insights. According to https://learn.microsoft.com/en-us/azure/azure-monitor/app/asp-net-troubleshoot-no-data, I should be seeing data being sent to dc.services.visualstudio.com.

Can anyone please shed some light on how this works, or if I am missing anything?

Upvotes: 2

Views: 3409

Answers (2)

Julian Wen Hsi Lee
Julian Wen Hsi Lee

Reputation: 206

To post an answer to the question. There's a few more information I did not think would have been relevant, such as me using Service Stack for .NET Core, so I am posting the information here as well.

The way Logging in Service Stack is implemented is that it is generally defined in the Program and Startup files, then saved to a LogFactory. Service Stack states that in .NET Core, they delegate all logging work to the in-built NetCoreLogFactory class used in .NET Core - NetCoreLogFactory can use pretty much any logging interface by passing in an ILoggerFactory to it, which is defined in Program.cs.

The code I use to configure the logging interface in Program.cs is:

    public static IWebHost BuildWebHost(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
            .ConfigureLogging(logging => {
                logging.ClearProviders();
                logging.SetMinimumLevel(LogLevel.Trace);
            })
            .UseNLog()
            .UseStartup<Startup>()
            .Build();

And in Startup.cs:

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseServiceStack(new AppHost
            {
                AppSettings = new NetCoreAppSettings(Configuration)
            });

            LogManager.LogFactory = new NetCoreLogFactory(loggerFactory, true);
        }

The service layers can then call upon this definition by calling LogManager.GetLogger(GetType()). The issue then is how the LogFactory would be defined.

I have tried to use Microsoft's own Application Insights logging, but in the end I settled with going for NLog with using Application Insights as a target, as shown in the above code.

The code works now and I can see data going into Application Insights.

Upvotes: 1

Dylan Morley
Dylan Morley

Reputation: 1726

In a net core API, the recommended way to configure your app insights setup is via the AddApplicationInsightsTelemetry method on the services collection, e.g.

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{       
    services.AddApplicationInsightsTelemetry();
}

See https://learn.microsoft.com/en-us/azure/azure-monitor/app/asp-net-core for more examples,

If you look at what this method does, it will register a number of components for you with the underlying container, meaning you can now access TelemetryClient and TelemetryConfiguration objects from container created instances

If you want to perform additional configuration to the TelemetryConfiguration object, you can have that added to your Configure method like,

public void Configure(IApplicationBuilder app, IHostingEnvironment env, TelemetryConfiguration config)
{
    // do whatever you want to the config object here
}

In any of your library code, you should now specify that your object takes a dependency on a TelemetryClient object rather than creating them within the lib itself, allowing the host process to inject instances for you, e.g.

public class MyLibraryClass
{
    TelemetryClient _telemetryClient

    public MyLibraryClass(TelemetryClient telemetryClient)
    {
        _telemetryClient = telemetryClient;     
    }   

    public void Foo()
    {
        _telemetryClient.TrackTrace("Foo");
    }
}

The AI SDK will buffer and batch telemetry events in the process being instrumented. This means that each usage of an SDK method - such as TrackTrace, TrackEvent etc - does not immediately result in an HTTP call to the collection endpoint. Data is transmitted when the buffer is full or the buffer interval passes, whichever happens first,

You can override this behaviour if you like, by passing in a DeveloperMode flag to AddApplicationInsightsTelemetry, like,

services.AddApplicationInsightsTelemetry(new ApplicationInsightsServiceOptions() {DeveloperMode = true});

This will transmit after every telemetry event, which is useful if you want faster feedback from your data but obviously not a very efficient way of sending data - don't forget to turn it off!

Upvotes: 2

Related Questions