1

I have the unfortunate task of updating a WCF project to .NET Framework 4.8 and replacing the existing log4net exception handling with Microsoft Logging and Application Insights.

My approach was to implement Dependency Injection to make instantiation easier and because I am already used to that design approach with .NET Core. As you may know, WCF services adds its own complexity since WCF is responsible for instantiating the services and lower level objects (like custom customUserNamePasswordValidatorType). I was able to handle most of this by implementing a WCF Service Factory and updating the svc markup with it.

I have added Application Insights to the project via the appropriate NuGet packages which updates the web.config with appropriate httpModules for general exception handling. I was even able to add a custom TelemetryInitializer in Application_Start to include a few custom properties in the message.

My problem is getting an instance of ILogger<T> with the attached Application Insights provider into the instantiated service.

At first, I was getting an exception because of the parameterless constructor of Logger<T>. This was fixed by updating my WcfServiceFactory to the following

container
    ...
    .RegisterType<ILoggerFactory, LoggerFactory>(TypeLifetime.Singleton)
    .RegisterType(typeof(ILogger<>), typeof(Logger<>), TypeLifetime.Singleton);

This allowed an instance of the logger to be passed into the constructor of each service. However, calls to log messages are never written to App Insights and an inspection of the logger shows zero providers.

My guess is that because a new instance of LoggerFactory is being created, the already existing instance used in the httpModules is ignored.

According to https://github.com/unitycontainer/microsoft-logging, I need to refactor what I am doing and actually create an instance of a LoggerFactory and manually add the desired providers. My issue is that I cannot figure out how to do that with Application Insights. Everywhere else I used it, I would just call the AddApplicationInsights() extension method but that does not seem to be an option here (at least not with Unity).

So I guess my issue boils down to the following questions

  1. Can I get the WcfServiceFactory to use the existing App Insights logging? Maybe establish something in Global.asx?
  2. How can I manually register App Insights as a provider in the WcfServiceFactory including the custom telemetry?
Jason
  • 2,806
  • 2
  • 28
  • 38

1 Answers1

0

No need to use ILogger if the intention is just to log a custom error. You can log exception on AppInsights directly using the telemetry client, like this:

var telemetryClient = new TelemetryClient(TelemetryConfiguration.Active);
telemetryClient.TrackException(new Exception("Logged random exception message."));
Nic H
  • 1
  • 1
  • 2
    This solution potentially causes two issues -- (1) It is not using dependency injection like the rest of my site. Would have to see if TelemetryClient can be injected or do I still have same problem and (2) typically when using `ILogger` you would hook up multiple Providers...say AppInsights and Serilog (for file logging). Directly instantiating `TelemetryClient` would miss the file logging. – Jason Feb 04 '21 at 13:44