Erkennen, ob (und warum) Application Insights Telemetriedaten an Azure senden kann

Ich entwickle eine Windows Desktop-Anwendung und habe die Application Insights Core-Assemblys erfolgreich verknüpft. Ich benutzeTrackTrace, TrackEvent usw., um benutzerdefinierte Telemetrie zu senden.

uf einigen Arbeitsstationen wird Telemetrie erfolgreich an das Azure-Portal gesendet, auf anderen nicht, obwohl Anrufe anTrackTrace, Flush usw. sind erfolgreich (oder kehren zumindest zurück, ohne eine Ausnahme auszulösen.TelemetryClient.IsEnabled() gibt true zurück. Beide Workstations verwenden einInMemoryChannel, mit dem gleichen Endpunkthttps://dc.services.visualstudio.com/v2/track und das Sendeintervall beträgt 30 Sekunden.

Gibt es eine API-Funktion, die ich in meiner Anwendung aufrufen kann, um den Verbindungsstatus des TelemetryClient abzurufen? Etwas, das mir sagen würde, dass der Client erfolgreich verbunden ist oder dass ein Fehler aufgetreten istx beim Versuch, und hat immer nochy Telemetriepakete, die darauf warten, gesendet zu werden.

Ich suche keine Checkliste wienstallieren Sie das NuGet-Paket erneu (Ich tat...),Stellen Sie sicher, dass Ihre Firewall Datenverkehr zu Port xxx @ zuläss (tut es ...) oder versuchen, kb zu installieren ... 871 (Das habe ich auch gemacht ...). Was ich möchte, ist ein Statusbericht, den ich irgendwo auf der Client-Workstation protokollieren kann, während meine Anwendung ausgeführt wird. Dies wird zumindest in der Statusleiste bestätigt (Ja, ich weiß, dass Statusleisten heutzutage so altmodisch sind), dass ein Problem vorliegt.

Erstes Update - Größe der Warteschlange ermitteln

eim ersten Sieg konnte ich die Warteschlangengröße ermitteln. Ich wollte das tun, ohne (noch) eine eigene Channel-Implementierung zu erstellen. Dies ist jedoch wenig hilfreich, um Ausfälle zu erkennen, da die Warteschlange auch dann leer wird, wenn der Sender die Telemetrieelemente nicht senden kann (sie werden einfach verworfen) - dazu später mehr. Zumindest wissen Sie, dass der Sender-Thread läuft ...

private ITelemetryChannel _TelemetryChannel;
private InMemoryChannel _InMemoryChannel;
private object _TelemetryBuffer;
private object _BufferLock;
private object _InMemoryTransmitter;

_TelemetryChannel = TelemetryConfiguration.Active?.TelemetryChannel;
if (_TelemetryChannel != null && _TelemetryChannel is InMemoryChannel)
{
  _InMemoryChannel = (InMemoryChannel)_TelemetryChannel;
  _TelemetryBuffer = GetInstanceField (_InMemoryChannel, "buffer");
  _BufferLock = GetInstanceField (_TelemetryBuffer, "lockObj");
  _InMemoryTransmitter = GetInstanceField (_InMemoryChannel, "transmitter");
}

public int GetTelemetryQueueSize ()
{
    if (_BufferLock != null)
    {
        lock (_BufferLock)
        {
            object l = GetInstanceField (_TelemetryBuffer, "items");
            if (l is List<ITelemetry>)
            {
                return ((List<ITelemetry>)l).Count;
            }
        }
    }
    return -1;
}

Sie benötigen auch eine Utility-Funktion, um mit Reflection auf die privaten Felder der Objekte zuzugreifen (Puffer und Sender sindinternal sealed ...) Ich habe diese so fehlersicher wie möglich gemacht, sie könnten prägnanter sein.

private static object GetInstanceField (Type type, object instance, string fieldName)
{
    if (instance == null)
    {
        return null;
    }
    try
    {
        BindingFlags bindFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static;
        FieldInfo field = type.GetField (fieldName, bindFlags);
        return field.GetValue (instance);
    }
    catch
    {
        return null;
    }
}

private static object GetInstanceField (object instance, string fieldName)
{
    if (instance == null)
    {
        return null;
    }
    return GetInstanceField (instance.GetType (), instance, fieldName);
}

Antworten auf die Frage(4)

Ihre Antwort auf die Frage