Detectando se (e por que) o Application Insights pode enviar dados de telemetria para o Azure
Estou desenvolvendo um aplicativo da área de trabalho do Windows e vinculei com êxito os assemblies principais do Application Insights. estou a usarTrackTrace
, TrackEvent
etc. para enviar telemetria personalizada.
Em algumas estações de trabalho, a telemetria é enviada com êxito para o portal do Azure e, em outras, não, embora chamadas paraTrackTrace
, Flush
, etc. ter êxito (ou pelo menos retornar sem gerar uma exceção.TelemetryClient.IsEnabled()
retorna verdadeiro. Ambas as estações de trabalho usam umInMemoryChannel
, com o mesmo terminalhttps://dc.services.visualstudio.com/v2/track
e o intervalo de envio é de 30 segundos.
Existe uma função de API que eu possa chamar no meu aplicativo para obter o status da conexão do TelemetryClient? Algo que me diria que o cliente está conectado com sucesso ou que encontrou um errox enquanto tenta, e ainda temy pacotes de telemetria aguardando envio.
Não estou procurando uma lista de verificação comoreinstalar o pacote NuGet (Eu fiz...),Verifique se o firewall permite que o tráfego seja portado xxx (faz ...) outente instalar o kb ... 871 (Eu fiz isso também ...). O que eu gostaria é de um relatório de status que eu possa registrar em algum lugar na estação de trabalho do cliente enquanto meu aplicativo é executado, pelo menos reconhecendo na barra de status (Sim, eu sei que as barras de status são tão antiquadas hoje em dia) que há um problema.
Primeira atualização - Obtendo o tamanho da fila
Primeira vitória, consegui obter o tamanho da fila. Eu queria fazer isso sem criar minha própria implementação de canal (ainda). No entanto, isso é de pouca ajuda para detectar interrupções, porque a fila será drenada, mesmo que o transmissor não consiga transmitir os itens de telemetria (apenas os descartará) - mais sobre isso posteriormente. Pelo menos você sabe que o fio do transmissor está em execução ...
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;
}
Você também precisa de uma função utilitária para usar a reflexão para acessar os campos particulares dos objetos (o buffer e o transmissor sãointernal sealed
...) Eu os tornei o mais resistentes a erros possível, eles poderiam ser mais 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);
}