Skip to content

[Advanced] How to enable self diagnostics for ApplicationInsights.Kubernetes

Saar Shen edited this page May 1, 2017 · 8 revisions

This is a draft page for how to enable logging for ApplicationInsights.Kubernetes in ASP.NET Core application.

Enable self-diagnostics

We understand ApplicationInsights.Kubernetes is far from perfect. Enabling self-diagnostics will help find issues easier. Please feel free to open issues and we will be glad to look into them.

To enable self-diagnostics, configure the console logging to the level of Debug while setting up the WebHost like this:

    using Microsoft.Extensions.Logging;
    public class Program
    {
        public static void Main(string[] args)
        {
            var host = new WebHostBuilder()
                .UseKestrel()
                .UseContentRoot(Directory.GetCurrentDirectory())
                // The following line adds a console output for logs >= LogLevel.Debug
                .ConfigureLogging(f => f.AddConsole(LogLevel.Trace))
                .UseIISIntegration()
                .UseStartup<Startup>()
                .UseApplicationInsights()
                .Build();

            host.Run();
        }
    }

When self-diagnostics is enabled, you will see logging being written into the pod logs. You may watch it in the Kubernetes Dashboard like it below:

Or you can fetch the log by calling kubectl logs <PodName> [ContainerName]. For example:

kubectl logs x-u-service-20450933-b61w2 x-webapi

A similar log shall be output to the terminal.

What happened when self-diagnostics is enabled

Gets the ILoggerFactory

Firstly, WebHostBuilder.ConfigureLogging(f => f.AddConsole(LogLevel.Trace)) is called, the Console output will be added as providers to ILoggerFactory. Secondly, services.EnableK8s() is called to initialize the ApplicationInsights.Kubernetes.

In that second step, ApplicationInsights.Kubernetes will fetch the existing ILoggerFactory:

        public static IServiceCollection EnableK8s(this IServiceCollection services, TimeSpan? timeout = null)
        {
            // ...
            // Fetch the logger factory
            ILoggerFactory loggerFactory = (ILoggerFactory)services.FirstOrDefault(
                s => s.ServiceType == typeof(ILoggerFactory))?.ImplementationInstance;
        }

Create ILogger using the ILoggerFactory

Now that ApplicaitonInsights.Kubernetes has a handle on the loggerFactory, it is easy to infer that we use loggerFactory to create ILogger objects:

ILogger logger = loggerFactory?.CreateLogger("K8sEnvInitializer");

or

ILogger logger = loggerFactory?.CreateLogger<K8sEnvironment>();

Consume ILogger:

ILogger provides methods to log messages in different levels:

logger?.LogDebug(Invariant($"Getting container status of container-id: {settings.ContainerId}"));

or

logger?.LogError(Invariant($"Kubernetes info is not available within given time of {timeout.TotalMilliseconds} ms."));