AlexB
AlexB

Reputation: 4546

.NET Core 3.0 worker - can't make logging work with Application Insights nor EventLog

I need a .NET 3.0 worker service to log into Azure Application Insights and EventLog. None of this works (almost)!

Here's my CreateHostBuilder:

        public static IHostBuilder CreateHostBuilder(string[] args)
        {
            return Host.CreateDefaultBuilder(args)
                .ConfigureServices((hostContext, services) =>
                {
                    IConfiguration configuration = hostContext.Configuration;

                    WatchdogOptions options = configuration.GetSection("WorkerOptions").Get<WatchdogOptions>();
                    if (options == null) throw new WatchdogException("WorkerOptions settings are not set");

                    services.AddSingleton(options);

                    services.AddHostedService<Worker>()
                    // .AddApplicationInsightsTelemetryWorkerService();
                    ;
                })
                .ConfigureLogging(logging =>
                {
                    logging.ClearProviders();
                    //logging.AddConsole();
                    logging.AddApplicationInsights("<instr-key>");
                    logging.AddEventLog(new EventLogSettings
                    {
                        SourceName = "PNWatchdog",
                        LogName = "Watchdog"
                    });
                });
        }

1) Whatever I do the EventLog does not have any records from my worker. And I did set up logging level in app settings:

{
  "Logging": {
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"
    }
  },
  "EventLog": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  }
}

2) Application Insights only get records when .AddApplicationInsightsTelemetryWorkerService() is commented out and the instrumentation key is hardcoded in the logging.AddApplicationInsights("8d3bc77d-1cc3-4c4a-83e4-6d8aaa87f8f7"). What should be done so it gets the key from app settings?

3) Why is this so cumbersome?

UPDATE

Here's the full app.development.settings:

{
  "Logging": {
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"
    },
    "EventLog": {
      "LogLevel": {
        "Default": "Information",
        "Microsoft.Hosting.Lifetime": "Information"
      }
    }
  },
  "ApplicationInsights": {
    "InstrumentationKey": "8d3bc77d-1cc5-what-ever-0000000000"
  }
}

UPDATE 2

ApplicationInsights added to Logging section:

{
  "Logging": {
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"
    },
    "EventLog": {
      "LogLevel": {
        "Default": "Information",
        "Microsoft.Hosting.Lifetime": "Information"
      }
    },
    "ApplicationInsights": {
      "LogLevel": {
        "Default": "Information"
      }
    } 
  },
  "ApplicationInsights": {
    "InstrumentationKey": "8d3bc77d-1cc5-4c4a-83e4-6d8aaa87f8f7"
  }
}

UPDATE 3

Property name changed for Logging:ApplicationInsights:LogLevel:

{
  "Logging": {
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"
    },
    "EventLog": {
      "LogLevel": {
        "Default": "Information",
        "Microsoft.Hosting.Lifetime": "Information"
      }
    },
    "ApplicationInsights": {
      "LogLevel": {
        "PushNotificationsWatchdog.Worker": "Information"
      }
    }
  },
  "ApplicationInsights": {
    "InstrumentationKey": "8d3bc77d-1cc5-4c4a-83e4-6d8aaa87f8f7"
  }
}

Same thing - no records in App Insights. The instrumentation key is correct.

RESOLUTION

Thanks to @peter-bons!

So I changed the order of ConfigureServices() and ConfigureLogging() and used appsettings from UPDATE 2 and it works now! So there we go:

public static IHostBuilder CreateHostBuilder(string[] args)
        {
            return Host.CreateDefaultBuilder(args)
                .ConfigureLogging(logging =>
                {
                    logging.ClearProviders();
                    logging.AddConsole();
                    logging.AddEventLog(new EventLogSettings
                    {
                        SourceName = "PNWatchdog",
                        LogName = "Watchdog"
                    });
                })
                .ConfigureServices((hostContext, services) =>
                {
                    services.AddHostedService<Worker>()
                        .AddApplicationInsightsTelemetryWorkerService();
                })
                .UseWindowsService(); // windows only feature
        }

Upvotes: 2

Views: 6233

Answers (2)

Peter Bons
Peter Bons

Reputation: 29840

TIL there is something like a "Application Insights Telemetry WorkerService" :-)

I got it working using AddApplicationInsightsTelemetryWorkerService. But only if you either do not call logging.ClearProviders(); or call ConfigureLogging before ConfigureServices otherwise the added logging provider is cleared.

This works:

public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureLogging(logging =>
                {
                    logging.ClearProviders();
                    logging.AddConsole();
                })
                .ConfigureServices((hostContext, services) =>
                {
                    services.AddHostedService<Worker>();
                    services.AddApplicationInsightsTelemetryWorkerService();
                });

using this config:

  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    },
    "ApplicationInsights": {
      "LogLevel": {
        "Default": "Information"
      }
    }
  },
  "ApplicationInsights": {
      "InstrumentationKey": "xxx"
    }
  }

As you can see in the output the AI key is correctly picked up:

Application Insights Telemetry: {
    "name": "Microsoft.ApplicationInsights.Dev.3b40adb096064da0816e7b8579aa443c.Message",
    "time": "2019-11-13T07:52:11.0027057Z",
    "iKey": "xxx",
    "tags": {
        "ai.application.ver": "1.0.0.0",
        "ai.cloud.roleInstance": "xxx",
        "ai.internal.sdkVersion": "il:2.11.0-21511",
        "ai.internal.nodeName": "xxx"
    },
    "data": {
        "baseType": "MessageData",
        "baseData": {
            "ver": 2,
            "message": "Application started. Press Ctrl+C to shut down.",
            "severityLevel": "Information",
            "properties": {
                "{OriginalFormat}": "Application started. Press Ctrl+C to shut down.",
                "CategoryName": "Microsoft.Hosting.Lifetime",
                "DeveloperMode": "true"
            }
        }
    }
}

Upvotes: 4

cijothomas
cijothomas

Reputation: 3196

AddApplicationInsightsTelemetryWorkerService() is the recommended way to enable application insights in WorkerService. It can take ikey from appsettings.json. This internally sets up the logging provider (applicationinsightsloggingprovider).

ApplicationInsights logging provider only captures logs of level 'Warning' or above by default (https://learn.microsoft.com/en-us/azure/azure-monitor/app/worker-service#ilogger-logs). So that's my first suspicion. Can you log something of Warning or Error and see if gets captured. Or change the default level captured by application insights to capture info or trace level as well. (https://learn.microsoft.com/en-us/azure/azure-monitor/app/ilogger#control-logging-level)

Upvotes: 0

Related Questions