Merged PR 1498432: Make telemetry client initialize async and queue events.

The telemetry client now initializes async to improve startup performance.  Calls to TrackEvent() queue event data until the FlushEvents() is called.  This prevents too much work being done on the UI thread when adding instrumentation.  FlushEvents() must be called as part of app suspension to ensure events are sent to the telemetry endpoint.

Related work items: #11992405
This commit is contained in:
Kelly Morris 2018-02-28 19:27:22 +00:00
Родитель 649f3defdd
Коммит ca7fd10c96
2 изменённых файлов: 59 добавлений и 33 удалений

Просмотреть файл

@ -106,6 +106,7 @@ namespace CompositionSampleGallery
var deferral = e.SuspendingOperation.GetDeferral();
//TODO: Save application state and stop any background activity
Shared.AppTelemetryClient.TrackEvent("SessionStop");
Shared.AppTelemetryClient.FlushEvents();
deferral.Complete();
}
}

Просмотреть файл

@ -2,6 +2,7 @@
using Microsoft.ApplicationInsights.Extensibility;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Windows.System.Profile;
namespace CompositionSampleGallery.Shared
@ -11,20 +12,38 @@ namespace CompositionSampleGallery.Shared
private static TelemetryClient _telemetryClient = null;
private static string _sessionId = null;
private static string _machineId = Guid.Empty.ToString();
private static bool _autoFlushEvents = true;
private static bool _isInitialized = false;
public static bool AutoFlushEvents { get => _autoFlushEvents; set => _autoFlushEvents = value; }
private struct AppInsightsEvent
{
public string Name;
public Dictionary<string, string> Properties;
public Dictionary<string, double> Metrics;
public AppInsightsEvent(string eventName, Dictionary<string, string> eventProperties, Dictionary<string, double> eventMetrics)
{
Name = eventName;
Properties = eventProperties;
Metrics = eventMetrics;
}
};
private static Queue<AppInsightsEvent> _eventQueue = new Queue<AppInsightsEvent>();
static AppTelemetryClient()
{
try
InitializeAppTelemetryClientAsync();
}
private static Task InitializeAppTelemetryClientAsync()
{
Task initializeClient = new Task(() =>
{
TelemetryConfiguration.Active.TelemetryChannel.EndpointAddress = "https://vortex.data.microsoft.com/collect/v1";
TelemetryConfiguration.Active.InstrumentationKey = "AIF-a6c90b8a-c7f9-4d3f-96f4-d5f9dbd4b4ce";
_telemetryClient = new TelemetryClient();
_sessionId = Guid.NewGuid().ToString().ToUpperInvariant();
if (Windows.Foundation.Metadata.ApiInformation.IsTypePresent("Windows.System.Profile.SystemIdentification")
&& Windows.Foundation.Metadata.ApiInformation.IsMethodPresent("Windows.System.Profile.SystemIdentification", "GetSystemIdForPublisher"))
{
@ -38,47 +57,53 @@ namespace CompositionSampleGallery.Shared
_machineId = BitConverter.ToString(bytes);
}
}
}
catch (Exception)
{ }
}
_isInitialized = true;
});
initializeClient.Start();
return initializeClient;
}
public static void TrackEvent(string eventName)
{
if (_telemetryClient != null)
TrackEvent(eventName, null, null);
_eventQueue.Enqueue(new AppInsightsEvent(eventName, null, null));
}
public static void TrackEvent(string eventName, Dictionary<string, string> properties, Dictionary<string, double> metrics)
{
if (_telemetryClient != null)
{
if (properties == null)
{
properties = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
properties.Add("SessionId", _sessionId);
properties.Add("MachineId", _machineId);
}
else
{
if (!properties.ContainsKey("SessionId"))
properties.Add("SessionId", _sessionId);
if (!properties.ContainsKey("MachineId"))
properties.Add("MachineId", _machineId);
}
properties.Add("EventTime", DateTime.UtcNow.ToString("yyyy-MM-dd'T'HH:mm:ss.ffffzzz"));
_telemetryClient.TrackEvent(eventName, properties, metrics);
if (AutoFlushEvents)
_telemetryClient.Flush();
}
_eventQueue.Enqueue(new AppInsightsEvent(eventName, properties, metrics));
}
public static void FlushEvents()
{
if (_telemetryClient != null)
_telemetryClient.Flush();
if (_telemetryClient != null && _isInitialized)
{
for (AppInsightsEvent queuedEvent; _eventQueue.Count > 0;)
{
queuedEvent = _eventQueue.Dequeue();
if (queuedEvent.Properties == null)
{
queuedEvent.Properties = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
queuedEvent.Properties.Add("SessionId", _sessionId);
queuedEvent.Properties.Add("MachineId", _machineId);
}
else
{
if (!queuedEvent.Properties.ContainsKey("SessionId"))
queuedEvent.Properties.Add("SessionId", _sessionId);
if (!queuedEvent.Properties.ContainsKey("MachineId"))
queuedEvent.Properties.Add("MachineId", _machineId);
}
queuedEvent.Properties.Add("EventTime", DateTime.UtcNow.ToString("yyyy-MM-dd'T'HH:mm:ss.ffffzzz"));
_telemetryClient.TrackEvent(queuedEvent.Name, queuedEvent.Properties, queuedEvent.Metrics);
_telemetryClient.Flush();
}
}
}
}
}