asp.netwebformsazure-application-insightsevent-viewerilogger

Get an ILogger instance for App Insights from ServiceCollection in a WebForms .NET Framework application


We want to get an ILogger instance so that it can be passed to other library. We tried below, but the ILogger instance does not log into Application Insights. It logs into Event Viewer successfully.

        var serviceCollection = new ServiceCollection();
        serviceCollection.AddLogging(builder => builder
        .AddFilter("Default", LogLevel.Information)
        .AddFilter("Microsoft", LogLevel.Warning)
        .AddFilter("System", LogLevel.Warning)
        .AddEventLog(config => { config.LogName = "Pages"; config.SourceName = "Pages"; })
        .AddApplicationInsights(telemetry =>
        telemetry.ConnectionString = "my-key",
        options => options = new ApplicationInsightsLoggerOptions()));


        var serviceProvider = serviceCollection.BuildServiceProvider();
        var loggerFactory = serviceProvider.GetService<ILoggerFactory>();
        var logger = loggerFactory.CreateLogger("my-logger");
        logger.LogInformation("Hi");

We have added the necessary packages i.e. Microsoft.Extensions.Logging and Microsoft.Extensions.Logging.ApplicationInsights

Is there no way, we can get an ILogger instance from ServiceCollection for AppInsights?


Solution

  • I figured out that it was not logging to AppInsights because there was no TelemetryChannel or TelemetryClient properly configured.

    Approach 1 - Using Telemetry Channel

    using (var channel = new InMemoryChannel()) {
                    var serviceCollection = new ServiceCollection();
                    serviceCollection.Configure<TelemetryConfiguration>(config => config.TelemetryChannel = channel);
                    serviceCollection.AddLogging(builder => builder
                    .AddFilter("Default", LogLevel.Information)
                    .AddFilter("Microsoft", LogLevel.Warning)
                    .AddFilter("System", LogLevel.Warning)
                    .AddEventLog(config => { config.LogName = "Pages"; config.SourceName = "Pages"; })
                    .AddApplicationInsights(config => config.ConnectionString = "my-key",
                    options => { }));
                    var serviceProvider = serviceCollection.BuildServiceProvider();
                    var loggerFactory = serviceProvider.GetService<ILoggerFactory>();
                    var logger = loggerFactory.CreateLogger("my-logger");
                    logger.LogInformation("my new try");                 channel.Flush();
                    System.Threading.Thread.Sleep(1000);
                }
    

    Approach 2 - Injecting Telemetry Client using the Microsoft.ApplicationInsights.WorkerService package

    var serviceCollection = new ServiceCollection();
    
                serviceCollection.AddApplicationInsightsTelemetryWorkerService(options => options.ConnectionString = "my-key");
                serviceCollection.AddLogging(builder => builder
                .AddFilter<Microsoft.Extensions.Logging.ApplicationInsights.ApplicationInsightsLoggerProvider>("", LogLevel.Information)
                .AddFilter("Default", LogLevel.Information)
                .AddFilter("Microsoft", LogLevel.Warning)
                .AddFilter("System", LogLevel.Warning)
                .AddEventLog(config => { config.LogName = "Pages"; config.SourceName = "Pages"; }));
    
                var serviceProvider = serviceCollection.BuildServiceProvider();
                var loggerFactory = serviceProvider.GetService<ILoggerFactory>();
                var telemetryClient = serviceProvider.GetService<TelemetryClient>();
                var logger = loggerFactory.CreateLogger("my-logger");
                logger.LogInformation("my new try");                 
                telemetryClient.Flush();
                System.Threading.Thread.Sleep(1000);
    

    Both approaches will work fine; we used approach 2.