4

I am testing out the code directly out of here for a console app: https://learn.microsoft.com/en-us/azure/azure-monitor/app/ilogger#

I basically copied the code and pointed it to a new azure app insights instance. However, none of the logs are showing up in app insights. Am I missing anything?

 static void Main(string[] args)
        {
            // Create DI container.
            IServiceCollection services = new ServiceCollection();

            // Add the logging pipelines to use. We are using Application Insights only here.
            services.AddLogging(loggingBuilder =>
            {
                // Optional: Apply filters to configure LogLevel Trace or above is sent to ApplicationInsights for all
                // categories.
                loggingBuilder.AddFilter<ApplicationInsightsLoggerProvider>("", LogLevel.Trace);
                loggingBuilder.AddApplicationInsights(******);
            });

            // Build ServiceProvider.
            IServiceProvider serviceProvider = services.BuildServiceProvider();

            ILogger<Program> logger = serviceProvider.GetRequiredService<ILogger<Program>>();


            logger.LogCritical("critical message working");
            // Begin a new scope. This is optional. Epecially in case of AspNetCore request info is already
            // present in scope.
            using (logger.BeginScope(new Dictionary<string, object> { { "Method", nameof(Main) } }))
            {
                logger.LogWarning("Logger is working - warning"); // this will be captured by Application Insights.

            }
        }
2
  • stackoverflow.com/a/49029975/1300910 Commented Mar 21, 2019 at 21:39
  • @huysentruitw not related. This question is about Dotnet-Core Logging Extensions for AI. The one you linked to is about AI application instrumentation. Commented Mar 9, 2021 at 17:36

1 Answer 1

6

The code is correct, but you are hitting a known issue with ApplicationInsights and Console apps - the app is dying before ApplicationInsights can send the data to the backend. (data is not sent immediately, but batched and sent at intervals.)

Adding a sleep of ~30 secs should help your case. Thread.Sleep(31000);

In regular console apps, docs suggest doing an explicit flush. https://learn.microsoft.com/en-us/azure/azure-monitor/app/console#full-example

But in the ILogger case, you don't control the TelemetryClient instance. So your best alternative is to control the channel, and call flush on the channel followed by a small sleep. Modified code is given below.

class Program
    {
        static void Main(string[] args)
        {
            // Create DI container.
            IServiceCollection services = new ServiceCollection();

            var channel = new InMemoryChannel();

            services.Configure<TelemetryConfiguration>(
              (config) =>
                {
                    config.TelemetryChannel = channel;                    
                }
           );

            // Add the logging pipelines to use. We are using Application Insights only here.
            services.AddLogging(loggingBuilder =>
            {
                // Optional: Apply filters to configure LogLevel Trace or above is sent to ApplicationInsights for all
                // categories.
                loggingBuilder.AddFilter<ApplicationInsightsLoggerProvider>("", LogLevel.Trace);
                loggingBuilder.AddApplicationInsights("***");
            });

            // Build ServiceProvider.
            IServiceProvider serviceProvider = services.BuildServiceProvider();

            ILogger<Program> logger = serviceProvider.GetRequiredService<ILogger<Program>>();


            logger.LogCritical("critical message working");
            // Begin a new scope. This is optional. Epecially in case of AspNetCore request info is already
            // present in scope.
            using (logger.BeginScope(new Dictionary<string, object> { { "Method", nameof(Main) } }))
            {
                logger.LogWarning("Logger is working - warning"); // this will be captured by Application Insights.

            }

            channel.Flush();
            Thread.Sleep(1000);            
        }
    }
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you. I suspected something of the sort when I did a large for loop for logger.log... and then the logs showed up. One would think ending the logger scope would flush the channel.
channel is by-default flushed once every 30 secs or once 500 items are buffered. Flushing with every scope is not likely the right approach, as it might be inefficient to just send few items.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.