C# 检测Application Insights是否(以及为什么)可以将遥测数据发送到Azure
我正在开发一个Windows桌面应用程序,并已成功链接了application Insights核心程序集。我正在使用C# 检测Application Insights是否(以及为什么)可以将遥测数据发送到Azure,c#,azure,azure-application-insights,C#,Azure,Azure Application Insights,我正在开发一个Windows桌面应用程序,并已成功链接了application Insights核心程序集。我正在使用TrackTrace,TrackEvent等发送自定义遥测数据 在某些工作站上,遥测成功发送到Azure门户,而在另一些工作站上,虽然对TrackTrace、Flush等的调用成功(或者至少返回而不引发异常。TelemetryClient.IsEnabled()返回true。两个工作站使用内存通道中的,,具有相同的端点https://dc.services.visualstudi
TrackTrace
,TrackEvent
等发送自定义遥测数据
在某些工作站上,遥测成功发送到Azure门户,而在另一些工作站上,虽然对TrackTrace
、Flush
等的调用成功(或者至少返回而不引发异常。TelemetryClient.IsEnabled()
返回true。两个工作站使用内存通道中的,,具有相同的端点https://dc.services.visualstudio.com/v2/track
,发送间隔为30秒
我是否可以在应用程序中调用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;
}
好的,我设法让它工作了…没有API来做它,所以我创建了一个新的自定义遥测通道,它实际上报告了错误,我可以依赖它
编辑:从评论中可以看出,reliablemetrychannel
不是此类的合适名称。应将其命名为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云。这对于间歇性互联网连接以及在发送所有数据之前关闭应用程序的情况都非常有用
在启动时,您可以添加一个微小的睡眠延迟,以确保将来自上一个会话的数据发送到云
代码示例取自,可以从中找到更多详细信息。ApplicationInsights使用ETW记录故障。您可以订阅它并重新发布到日志。或者使用perfview进行一次性调查。这里有更多信息:确实如此(我也尝试过)。不幸的是,错误记录是自由形式的(它使用CoreEventSource.Log.LogVerbose报告错误)并需要重新解析(和手指交叉,希望周围的文本永远不会被本地化)以检测出哪里出了问题…您好。虽然我重视您的输入,但它并没有完全回答我的问题,即了解遥测数据是否存在以及为什么存在(不存在)我在我的帖子中特别解释说,我不想为了让它工作而尝试一系列事情,我想要一种在运行时检测它不工作的方法(顺便说一句,这也排除了“启用日志记录”作为有效答案)…FYI遥测未发送,因为应用程序正在Windows XP SP1工作站上运行,并且SSL根证书已过期。在这种情况下,刷新和存储到磁盘将没有帮助…好的,有效点。在某种程度上,我的回答对不需要详细ProbingChannel的其他用户是有效的。在大多数情况下,会持续存在ent通道应该足够了,尽管在您的例子中显然不是这样。它确实有助于有趣的阅读…是的,事实上,遥测的大多数使用场景都是“火与忘”的。我肯定会使用永久通道进行常规遥测(探测通道仅在那里每隔15分钟左右发送一次探测器)我将查看是否可以通过查看私有字段从中提取队列大小等信息(尽管这似乎很困难,发送器触发了多个来来去去的发送器线程,信息可能非常不稳定)。PersistenceChannel在编写此答案大约一个月后停止存在。
telemetryClient.Flush()