15

I'm trying to log exceptions to Application Insights. I succeeded in doing this by calling TelemetryClient.TrackException directly. However, I would like to abstract away from this in my code in case I'd want to log to other platforms in the future, so I would like to stick to only the ILogger interface.

I found that you can use ILoggerFactory.AddApplicationInsights (as implemented here) but no matter what I did, I don't see the logs showing up in ApplicationInsights with this.

Below is my code:

Startup.cs

    IConfigurationRoot Configuration { get; set; }
    ILoggerFactory LoggerFactory { get; set; }
    IServiceProvider ServiceProvider { get; set; }

    public Startup( IHostingEnvironment hostingEnvironment, ILoggerFactory loggerFactory )
    {
        this.LoggerFactory = loggerFactory;
        string configurationFilePath = "abc.json";

        this.Configuration = new ConfigurationBuilder()
            .SetBasePath( hostingEnvironment.ContentRootPath )
            .AddJsonFile( configurationFilePath, optional: true, reloadOnChange: true )
            .AddEnvironmentVariables()
            .Build();
    }

    public void Configure(
        IApplicationBuilder applicationBuilder,
        IHostingEnvironment hostingEnvironment,
        ILoggerFactory loggerFactory,
        IServiceProvider serviceProvider )
    {
        this.ServiceProvider = serviceProvider;
        loggerFactory.AddApplicationInsights( serviceProvider );
        applicationBuilder.UseMvc();
    }

    public void ConfigureServices( IServiceCollection services )
    {
        services.AddApplicationInsightsTelemetry( this.Configuration );
        services.AddMvc( .... // A bunch of options here ... )
    }

Then, I try to use this in my controller like this:

    ILogger<XController> Logger { get; set; }

    public XController( ILogger<XController> logger )
    {
        this.Logger = logger;
    }

    [HttpPost]
    [Route( "v3.0/abcd" )]
    public async Task PostEvent( [FromBody] XEvent xEvent )
    {
        this.Logger.LogError( 0, new Exception( "1234" ), "1234" );
    }

However, I don't see any exceptions associated with the request at all. If I replace the Logger.LogError line with TelemetryClient.TrackException (and create the TelemetryClient first), then I can see the exception without any issues.

I don't know what I'm doing wrong. Could anyone help?

KangarooWest
  • 768
  • 2
  • 7
  • 20

5 Answers5

13

According to your description, I suggest you could try below codes to enable ILogger log the error to the ApplicationInsights.

You could directly use loggerFactory.AddApplicationInsights() method to enable the ApplicationInsights ILogger.

More details, you could refer to below codes:

The startup class:

public class Startup
{
    public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
            .AddEnvironmentVariables();
        Configuration = builder.Build();
    }

    public IConfigurationRoot Configuration { get; }

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

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {

        loggerFactory.AddApplicationInsights(app.ApplicationServices,LogLevel.Warning);

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseBrowserLink();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
        }

        app.UseStaticFiles();

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
    }
}

The appsettings.json:

{

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

Result:

enter image description here

enter image description here


Update:

The record find in the search feature.

enter image description here

Brando Zhang
  • 22,586
  • 6
  • 37
  • 65
  • Thanks. However, I tried this and it still didn't work. Just to make sure I tried the right thing - how is your answer different to what I already posted in the question, so that I could make the right edits? Also, if it helps, 1) I tried adding AddAzureWebAppDiagnostics() and I could see the log streaming, so I think I'm using the Logger correctly. 2) I can use TrackException directly and see the result on ApplicationInsights, so I think I'm setting the appSettings.json correctly. This is why I'm perplexed things still don't work :| – KangarooWest Jul 11 '17 at 18:02
  • 1
    I suggest you could recheck your AI's record. As far as I know, the log.error means add trace record in AI, so you will not find the record in the failure, you could find it in the trace record. I suggest you could recheck the record from the search button(in AI portal) as my update answer shows. – Brando Zhang Jul 12 '17 at 03:12
  • Thanks Brando for the suggestions. I ended up figuring out the issues. My guess is that our codes were using different versions of the NuGet packages, which have been evolving very quickly, thus the different behaviors. – KangarooWest Jul 13 '17 at 00:21
  • 4
    @BrandoZhang But the real question is..... How do you enable Application Insights for core 2.0 console app with ilogger :)? – Reft Apr 23 '18 at 15:06
  • loggerFactory.AddApplicationInsights – Dainius Kreivys Feb 26 '19 at 13:20
5

There is now first-class support for logging to Application Insights, using the Microsoft.Extensions.Logging.ApplicationInsights provider.

James
  • 1,028
  • 9
  • 20
  • This is supposed to work out of the box, but I seem to be missing something as it's not logging traces. Is the following sufficient? services.AddApplicationInsightsTelemetry(); – tonycdp May 18 '20 at 16:26
  • You may need to check your logging level filters, the default filters out all messages that are more ‘verbose’ than the Information level. – James May 18 '20 at 16:35
  • Event when I do the following : ` _logger.LogTrace("Logging trace"); _logger.LogDebug("Logging debug"); _logger.LogInformation("Logging info"); _logger.LogWarning("Logging warning"); _logger.LogError("Logging error"); _logger.LogCritical("Logging critical"); ` I can see the output on the console but nothing in the AI trace – tonycdp May 18 '20 at 16:46
  • Did you manage to figure this out @tonycdp? Same issue here and nothing helps. – Piedone Jan 14 '21 at 01:28
  • @Piedone yes it was a configuration issue. Set up a dummy app from scratch and then compare with what you've got. Sorry I can't help you more as it's been a while. – tonycdp Jan 18 '21 at 09:23
  • Thanks, no worries. I've tried that too :). – Piedone Jan 18 '21 at 18:51
4

I finally figured out. There are two ways to solve my issue:

Easy way:

I was using older versions of the Application Insights NuGets. Specifically, Microsoft.ApplicationInsights.2.2.0 and Microsoft.ApplicationInsights.AspNetCore.2.0.0.

Once I upgrade to Microsoft.ApplicationInsights.2.4.0 and Microsoft.ApplicationInsights.AspNetCore.2.1.1, everything works as expected. You also see the LogXXX with an exception as an argument showing up as Exception, and one without an exception showing up as Trace as expected.

Slightly more difficult way:

For some reason, the IApplicationBuilder and IServiceProvider in Configure does not provide the correct service provider to use in AddApplicationInsights, so you need to add the provider in the ConfigureServices:

    public void ConfigureServices( IServiceCollection services )
    {
            IServiceProvider serviceProvider = services.BuildServiceProvider();
            this.LoggerFactory.AddApplicationInsights( serviceProvider, Extensions.Logging.LogLevel.Information );
            ...
    }

This means that you need to save the loggerFactory from the constructor into a property/field since it's not available via dependency injection in ConfigureServices.

What I ended up doing (probably the best solution for now in my opinion):

Even though just doing either of the solutions above solves the problem, I decided to do both. This is because I want to be able to log error in ConfigureServices as well. Were I to put loggerFactory.UseApplicationInsights in Configure, then I would not be able to see the error in ConfigureServices on ApplicationInsights. I also prefer to see both Traces and Exceptions, a feature that only comes with the new package version.

KangarooWest
  • 768
  • 2
  • 7
  • 20
2

Unfortunately the SDK was updated to fire Exception Telemetry only recently (see commit), and the change was not published yet.
The only routes I see right now is to either leave the explicit call to TelemetryClient.TrackException in your code, or wrap it all with your own implementation of ILogger - both as temporary solutions until the official SDK support this

EranG
  • 822
  • 4
  • 10
  • Thanks. From the commit, it looks like it will fire ExceptionTelemetry when there's an exception, and TraceTelemetry otherwise. This is also when I get from testing in my code. Are you suggesting that they will remove TraceTelemetry later on? – KangarooWest Jul 13 '17 at 01:21
  • What I meant is that in the current SDK they only for TraceTelemetry. The ability to fire ExceptionTelemetry will be available in future releases of the SDK – EranG Jul 13 '17 at 03:24
1

Here is the documentation of App Insights with ILogger. For me it worked however got tons of Trace log so recommend you to apply custom filters:

builder.AddApplicationInsights("ikey");

builder.AddFilter<Microsoft.Extensions.Logging.ApplicationInsights.ApplicationInsightsLoggerProvider>
            ("", LogLevel.Information);
builder.AddFilter<Microsoft.Extensions.Logging.ApplicationInsights.ApplicationInsightsLoggerProvider>
            ("Microsoft", LogLevel.Warning);
Major
  • 5,948
  • 2
  • 45
  • 60