Detectar si o no (y por qué) Application Insights puede enviar datos de telemetría a Azure

Estoy desarrollando una aplicación de escritorio de Windows y he vinculado con éxito los ensamblados de Application Insights Core. Estoy usandoTrackTrace, TrackEvent, etc. para enviar telemetría personalizada.

En algunas estaciones de trabajo, la telemetría se envía con éxito al portal de Azure, y en otras no, aunque las llamadas aTrackTrace, Flush, etc. tienen éxito (o al menos regresan sin lanzar una excepción.TelemetryClient.IsEnabled() devuelve verdadero Ambas estaciones de trabajo usan unInMemoryChannel, con el mismo punto finalhttps://dc.services.visualstudio.com/v2/track y el intervalo de envío es de 30 segundos.

¿Hay una función API que pueda llamar en mi aplicación para obtener el estado de conexión del TelemetryClient? Algo que me diría que el cliente se ha conectado correctamente o que encontró un errorx mientras intenta, y todavía tieney paquetes de telemetría en espera de ser enviados.

No estoy buscando una lista de verificación comoreinstale el paquete NuGet (Yo hice...),Asegúrese de que su firewall permita el tráfico al puerto xxx (lo hace ...) ointenta instalar kb ... 871 (Yo también hice eso ...). Lo que me gustaría es un informe de estado en el que pueda iniciar sesión en algún lugar de la estación de trabajo del cliente mientras se ejecuta mi aplicación, al menos reconociendo en la barra de estado (Sí, sé que las barras de estado están tan anticuadas en estos días) que hay un problema.

Primera actualización: obtención del tamaño de la cola

Primera victoria, pude obtener el tamaño de la cola. Quería hacerlo sin crear mi propia implementación de canal (todavía). Sin embargo, esto es de poca ayuda para detectar interrupciones, ya que la cola se agotará incluso si el transmisor no puede transmitir los elementos de telemetría (simplemente los descartará); más sobre esto más adelante. Al menos sabes que el hilo del transmisor se está ejecutando ...

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;
}

También necesita una función de utilidad para usar la reflexión para acceder a los campos privados de los objetos (el búfer y el transmisor soninternal sealed...) Hice esto lo más resistente posible a los errores, podrían ser más concisos.

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);
}

Respuestas a la pregunta(2)

Su respuesta a la pregunta