[Serializable]
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
public sealed class TelemetryCallHandlerAttribute : HandlerAttribute, ICallHandler
{
#region Public constructors
public TelemetryCallHandlerAttribute()
{
}
public TelemetryCallHandlerAttribute(string instrumentationKey)
{
this.InstrumentationKey = instrumentationKey;
}
public string InstrumentationKey { get; set; }
public bool Async { get; set; }
#endregion
#region Public override methods
public override ICallHandler CreateHandler(IUnityContainer ignored)
{
return (this);
}
#endregion
#region ICallHandler Members
IMethodReturn ICallHandler.Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
TelemetryConfiguration config = null;
if (string.IsNullOrWhiteSpace(this.InstrumentationKey) == true)
{
config = TelemetryConfiguration.Active;
}
else
{
config = TelemetryConfiguration.CreateDefault();
config.InstrumentationKey = this.InstrumentationKey;
}
var telemetryClient = new TelemetryClient(config);
var watch = Stopwatch.StartNew();
var result = getNext()(input, getNext);
var elapsedMilliseconds = watch.ElapsedMilliseconds;
var exception = result.Exception;
var returnValue = result.ReturnValue;
var properties = new Dictionary<string, string>();
for (var i = 0; i < input.Arguments.Count; ++i)
{
var key = input.Arguments.ParameterName(i);
properties[key] = (input.Arguments[i] ?? string.Empty).ToString();
}
if (exception != null)
{
properties["$Exception"] = exception.Message;
}
if (returnValue != null)
{
properties["$ReturnValue"] = returnValue.ToString();
}
var metrics = new Dictionary<string, double>();
metrics["ElapsedMilliseconds"] = elapsedMilliseconds;
if (this.Async == false)
{
this.TrackEvent(telemetryClient, input.MethodBase.Name, properties, metrics);
}
else
{
this.TrackEventAsync(telemetryClient, input.MethodBase.Name, properties, metrics);
}
return (result);
}
private void TrackEvent(TelemetryClient telemetryClient, string name, IDictionary<string, string> properties, IDictionary<string, double> metrics)
{
telemetryClient.TrackEvent(name, properties, metrics);
}
private async void TrackEventAsync(TelemetryClient telemetryClient, string name, IDictionary<string, string> properties, IDictionary<string, double> metrics)
{[Serializable]
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
public sealed class TelemetryCallHandlerAttribute : HandlerAttribute, ICallHandler
{
#region Public constructors
public TelemetryCallHandlerAttribute()
{
}
public TelemetryCallHandlerAttribute(string instrumentationKey)
{
this.InstrumentationKey = instrumentationKey;
}
public string InstrumentationKey { get; set; }
public bool Async { get; set; }
#endregion
#region Public override methods
public override ICallHandler CreateHandler(IUnityContainer ignored)
{
return (this);
}
#endregion
#region ICallHandler Members
IMethodReturn ICallHandler.Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
TelemetryConfiguration config = null;
if (string.IsNullOrWhiteSpace(this.InstrumentationKey) == true)
{
config = TelemetryConfiguration.Active;
}
else
{
config = TelemetryConfiguration.CreateDefault();
config.InstrumentationKey = this.InstrumentationKey;
}
var telemetryClient = new TelemetryClient(config);
var watch = Stopwatch.StartNew();
var result = getNext()(input, getNext);
var elapsedMilliseconds = watch.ElapsedMilliseconds;
var exception = result.Exception;
var returnValue = result.ReturnValue;
var properties = new Dictionary<string, string>();
for (var i = 0; i < input.Arguments.Count; ++i)
{
var key = input.Arguments.ParameterName(i);
properties[key] = (input.Arguments[i] ?? string.Empty).ToString();
}
if (returnValue != null)
{
properties["$ReturnValue"] = returnValue.ToString();
}
var metrics = new Dictionary<string, double>();
metrics["ElapsedMilliseconds"] = elapsedMilliseconds;
if (this.Async == false)
{
if (exception != null)
{
properties["Name"] = input.MethodBase.Name;
this.TrackException(telemetryClient, exception, properties, metrics);
}
else
{
this.TrackEvent(telemetryClient, input.MethodBase.Name, properties, metrics);
}
}
else
{
if (exception != null)
{
properties["Name"] = input.MethodBase.Name;
this.TrackExceptionAsync(telemetryClient, exception, properties, metrics);
}
else
{
this.TrackEventAsync(telemetryClient, input.MethodBase.Name, properties, metrics);
}
}
return (result);
}
private void TrackException(TelemetryClient telemetryClient, Exception ex, IDictionary<string, string> properties, IDictionary<string, double> metrics)
{
telemetryClient.TrackException(ex, properties, metrics);
}
private async void TrackExceptionAsync(TelemetryClient telemetryClient, Exception ex, IDictionary<string, string> properties, IDictionary<string, double> metrics)
{
await Task.Run(() => this.TrackException(telemetryClient, ex, properties, metrics));
}
private void TrackEvent(TelemetryClient telemetryClient, string name, IDictionary<string, string> properties, IDictionary<string, double> metrics)
{
telemetryClient.TrackEvent(name, properties, metrics);
}
private async void TrackEventAsync(TelemetryClient telemetryClient, string name, IDictionary<string, string> properties, IDictionary<string, double> metrics)
{
await Task.Run(() => this.TrackEvent(telemetryClient, name, properties, metrics));
}
#endregion
} await Task.Run(() => this.TrackEvent(telemetryClient, name, properties, metrics));
}
#endregion
}