1

Short version

When I add my TelemetryInitializer to my TelemetryConfiguration I sometimes get an ArrayTypeMismatchException. What can I do to make sure I can always add my TelemetryInitializer?

Long version

I have a big WPF application that uses an AssemblyResolver to load dependant assemblies as described here: https://stackoverflow.com/a/33977134/1022179. Both my ApplicationInsights dll:s and the assembly where my custom TelemetryInitializer is defined are placed in a subdirectory.

For some users at some times I get an ArrayTypeMismatchException when trying to call LogEventAI in the code below (slightly simplified), but usually it works. My LogHandler is located in an assembly referenced directly by the WPF program. The TelemetryInitializer is located in a different assembly and is dynamically loaded at runtime since the LogHandler assembly depends on it.

Slightly simplified version of my LogHandler:

public class LogHandler
{
    private static TelemetryClient _telemetryClient;

    private static void EnsureTelemetryClientInitialized()
    {
        if (_telemetryClient != null)
        {
            return;
        }

        var instrumentationKey = Application.Settings.GetSetting("InstrumentationKey");
        TelemetryConfiguration configuration = new TelemetryConfiguration(instrumentationKey);
        configuration.TelemetryInitializers.Add(new PropertyMyModuleFromStackTraceInitializer());
        _telemetryClient = new TelemetryClient(configuration);
    }

    private static void LogExceptionAI(Exception ex, CustomLogPropertiesClient properties)
    {
        EnsureTelemetryClientInitialized();
        _telemetryClient.TrackException(ex, properties.ConvertToDictionary());
    }
}

My TelemetryInitializer is implemented in a different assembly and looks like this:

public class PropertyMyModuleFromStackTraceInitializer : ITelemetryInitializer
{
    public void Initialize(ITelemetry telemetry)
    {
        if (telemetry is ISupportProperties telemetryWithProperties)
        {
            if (telemetryWithProperties.Properties.ContainsKey("MY.Module")) return;

            var sc = new StackTrace();
            var module = MyModuleNameFinder.GetSystemFromExceptionText(sc.ToString()); // This is just a bunch of RegEx examining the stack trace.
            telemetryWithProperties.Properties.Add("MY.Module", module);
        }
    }
}

And this is the stack trace from my log:

MY.Shared.Library.Exceptions.BaseException: Server: **************, User: ********, Sender: TryLogExceptionToAppInsight
   --->System.ArrayTypeMismatchException: Attempted to access an element as a type incompatible with the array.
   at System.Collections.Generic.List`1.Add(T item)
   at Microsoft.ApplicationInsights.Extensibility.Implementation.SnapshottingCollection`2.Add(TItem item)
   at MY.Shared.Library.Logging.LogHandler.EnsureTelemetryClientInitialized()
   atMY.Shared.Library.Logging.LogHandler.LogExceptionAI(Exception ex, CustomLogPropertiesClient properties)
   // The two methods below are used to make the logger backwards compatible:
   at MY.Shared.Library.Logging.LogHandler.TryLogExceptionToAppInsight_TempForUserStory5290(Exception ex, Byte[] imageData, Object sender)
   at MY.Shared.Library.Logging.LogHandler.TryLogExceptionToAppInsight(Exception ex, Byte[] imageData, Object sender)

How can I get rid of this intermittent bug? I've tried debugging it several times but haven't come across the bug in Visual Studio.

Johan Gov
  • 1,262
  • 1
  • 13
  • 26
  • Is it possible to see your constructor for TelemetryConfiguration(instrumentationKey). This type of problem relates to how your list (TelemetryInitializers) is created and cast, which presumably happens in this constructor. – Ross Gurbutt Nov 24 '19 at 23:57
  • @RossGurbutt, The constructor for TelemetryConfiguration is located in Microsoft.ApplicationInsights.dll. It's a property with a backing field that looks like this: ``private readonly SnapshottingList telemetryInitializers = new SnapshottingList();``. The SnapshottingList is also a class in Microsoft.ApplicationInsights.dll. – Johan Gov Nov 25 '19 at 10:12
  • is it random across machines or always the same machine? do you have conflicting versions or multiple versions of an assembly in the path? maybe an old version of an AppInsights assembly is getting loaded somehow? that kind of thing you wouldn't see in VS because your deployment dir might only have the current versions of assemblies, but your service/etc deployment might be adding new versions and not deleting old versions? – John Gardner Nov 27 '19 at 22:25
  • Yes it is random across machines and across users. I have multiple versions of ApplicationInsights but the AssemblyResolver should load required assemblies and their dependencies. I have a modified version that considers versions too. – Johan Gov Nov 29 '19 at 11:11

0 Answers0