Detecting whether or not (and why) Application Insights can send telemetry data to Azure

倖福魔咒の 提交于 2019-12-03 22:28:15

OK, I managed to make it work... There is no API to do it, so I created a new custom Telemetry Channel that actually reports the errors, and that I can rely on.

Edit: it appears from comments that ReliableTelemetryChannel is not an appropriate name for this class. It should be named ProbingTelemetryChannel. Thanks.

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

Now it's just a matter of creating the channel and a client on that channel:

var _ReliableChannel = new ReliableTelemetryChannel ();
var _ReliableConfiguration = new TelemetryConfiguration ();
_ReliableConfiguration.TelemetryChannel = _ReliableChannel;
var _ReliableClient = new TelemetryClient (_ReliableConfiguration);
_ReliableClient.InstrumentationKey = "...";

Now I just regularly send a probe, and query the channel for error statistics:

_ReliableClient.TrackEvent ("TelemetryProbe");
GlobalLog.Log ("Probe attempts {0} Last Error {1}", _ReliableChannel.Attempts, _ReliableChannel.LastFailure);

It doesn't solve the global problem of detecting whether the active configuration works (the one that I use to send regular telemetry, with buffering etc.), but at least I can safely assume that if my Reliable channel is working, the regular one is working too.

Note: the persistence channel was discontinued shortly after I wrote this.

You got it to work, but all you did was creating a Persistence Channel that already exist.

You should've done the following:

  using Microsoft.ApplicationInsights.Channel;
  using Microsoft.ApplicationInsights.Extensibility;
  ...

  // Set up 
  TelemetryConfiguration.Active.InstrumentationKey = "YOUR INSTRUMENTATION KEY";

  TelemetryConfiguration.Active.TelemetryChannel = new PersistenceChannel();

On Application Exit, make sure you call the

telemetryClient.Flush()

to flush the telemetry data to the channel.

What this does is write your telemetry data to disk and periodically flush the data to the Azure cloud. This is great for intermittent internet connectivity and also for cases where the app closes before all data could be sent.

On startup, you can add a tiny sleep delay to ensure that the data from a previous session is sent to the cloud.

The code samples has been taken from the Application Insights Documentation where more detail can be found.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!