![](/img/trans.png)
[英]Not seeing telemetry in azure application insights and application insight resource randomly disappearing
[英]Detecting whether or not (and why) Application Insights can send telemetry data to Azure
我正在開發Windows桌面應用程序,並已成功鏈接Application Insights Core程序集。 我正在使用TrackTrace
, TrackEvent
等發送自定義遙測。
在某些工作站上,遙測已成功發送到Azure門戶,但在某些工作站上,遙測未成功,盡管對TrackTrace
, Flush
等的調用成功(或至少返回而沒有引發異常TelemetryClient.IsEnabled()
返回true。兩個工作站)使用具有相同端點https://dc.services.visualstudio.com/v2/track
的InMemoryChannel
,發送間隔為30秒。
我可以在應用程序中調用以獲取TelemetryClient的連接狀態的API函數嗎? 這可能告訴我客戶端已成功連接,或者嘗試時遇到錯誤x ,並且仍有y個遙測數據包等待發送。
我不是在尋找像重新安裝NuGet程序包的清單(我做了...), 請確保您的防火牆允許流量流向端口xxx (它確實...)或嘗試安裝kb ... 871 (我做到了)太...)。 我想要的是一個狀態報告,我可以在我的應用程序運行時在客戶端工作站上的某個位置登錄,至少要在狀態欄中確認(是的,我知道狀態欄如今已經過時了)以至於出現了問題。
第一次更新-獲取隊列大小
第一個勝利,我能夠獲得隊列的大小。 我想做到這一點而沒有創建自己的渠道實現(尚未)。 但是,這對檢測中斷幾乎沒有幫助,因為即使發送器無法發送遙測項目(它將直接丟棄它們),隊列也會耗盡(稍后會詳細介紹)。 至少您知道發送器線程正在運行...
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;
}
您還需要一個實用程序函數,以使用反射來訪問對象的私有字段(緩沖區和發送器是internal sealed
……)我使它們盡可能地抗錯誤,它們可能更簡潔。
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);
}
好的,我設法使其工作了……沒有API可以做到,所以我創建了一個新的自定義遙測通道,該通道實際報告錯誤,並且可以依靠。
編輯:從注釋中可以看出ReliableTelemetryChannel
不是此類的適當名稱。 它應命名為ProbingTelemetryChannel
。 謝謝。
using System;
using Microsoft.ApplicationInsights.Channel;
using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.ApplicationInsights.Extensibility.Implementation;
namespace Streambolics.Telemetry
{
public class ReliableTelemetryChannel : ITelemetryChannel
{
private Uri _EndpointAddress;
private int _Attempts, _Successes, _Failures;
private Exception _LastFailure;
private DateTime _LastFailureTime;
public ReliableTelemetryChannel ()
{
EndpointAddress = TelemetryConfiguration.Active?.TelemetryChannel?.EndpointAddress;
}
public bool? DeveloperMode {
get { return true; }
set { }
}
public string EndpointAddress {
get { return _EndpointAddress?.ToString (); }
set {
if (String.IsNullOrEmpty (value))
_EndpointAddress = null;
else
_EndpointAddress = new Uri (value);
}
}
public void Flush () { }
public void Send (ITelemetry item)
{
_Attempts++;
try
{
item.Timestamp = DateTime.Now;
byte[] data = JsonSerializer.Serialize (new ITelemetry[] { item });
var transmission = new Transmission (_EndpointAddress, data, "application/x-json-stream", JsonSerializer.CompressionType);
transmission.SendAsync ().GetAwaiter ().GetResult ();
_Successes++;
}
catch (Exception ex)
{
_Failures++;
_LastFailure = ex;
_LastFailureTime = DateTime.Now;
}
}
protected virtual void Dispose (bool disposing) { }
public void Dispose ()
{ Dispose (true); }
}
}
現在只需要創建頻道和該頻道上的客戶即可:
var _ReliableChannel = new ReliableTelemetryChannel ();
var _ReliableConfiguration = new TelemetryConfiguration ();
_ReliableConfiguration.TelemetryChannel = _ReliableChannel;
var _ReliableClient = new TelemetryClient (_ReliableConfiguration);
_ReliableClient.InstrumentationKey = "...";
現在,我只是定期發送一個探針,並查詢通道以獲取錯誤統計信息:
_ReliableClient.TrackEvent ("TelemetryProbe");
GlobalLog.Log ("Probe attempts {0} Last Error {1}", _ReliableChannel.Attempts, _ReliableChannel.LastFailure);
它不能解決檢測活動配置是否有效的全局問題(我用來發送常規遙測,使用緩沖等),但是至少我可以安全地假設,如果我的可靠通道正常工作,則常規通道也正在工作。
注意:我寫完這篇文章后不久就停止了持久性通道。
您可以使用它,但是您要做的就是創建一個已經存在的持久性通道。
您應該執行以下操作:
using Microsoft.ApplicationInsights.Channel;
using Microsoft.ApplicationInsights.Extensibility;
...
// Set up
TelemetryConfiguration.Active.InstrumentationKey = "YOUR INSTRUMENTATION KEY";
TelemetryConfiguration.Active.TelemetryChannel = new PersistenceChannel();
在應用程序退出時,請確保您致電
telemetryClient.Flush()
將遙測數據刷新到通道。
這是將遙測數據寫入磁盤,並定期將數據刷新到Azure雲。 這非常適合間歇性的Internet連接,也適用於在發送所有數據之前關閉應用程序的情況。
在啟動時,您可以添加一個微小的睡眠延遲,以確保將來自先前會話的數據發送到雲。
該代碼示例摘自Application Insights文檔 ,該文檔提供了更多詳細信息。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.