using System.Diagnostics;
namespace IronTelemetry.Client;
///
/// Extension methods for IronTelemetry integration.
///
public static class TelemetryExtensions
{
///
/// Configure global unhandled exception handling for console applications.
///
public static void UseUnhandledExceptionHandler()
{
AppDomain.CurrentDomain.UnhandledException += (sender, args) =>
{
if (args.ExceptionObject is Exception ex)
{
IronTelemetry.CaptureException(ex, ctx =>
ctx.WithExtra("isTerminating", args.IsTerminating)
.WithExtra("source", "UnhandledException"));
// Flush synchronously since the app may be terminating
IronTelemetry.Flush(TimeSpan.FromSeconds(2));
}
};
TaskScheduler.UnobservedTaskException += (sender, args) =>
{
IronTelemetry.CaptureException(args.Exception, ctx =>
ctx.WithExtra("source", "UnobservedTaskException"));
// Mark as observed to prevent app crash
args.SetObserved();
};
}
///
/// Capture an exception and return it (for throw expressions).
///
public static Exception Capture(this Exception ex)
{
IronTelemetry.CaptureException(ex);
return ex;
}
///
/// Capture an exception with context and return it.
///
public static Exception Capture(this Exception ex, Action configure)
{
IronTelemetry.CaptureException(ex, configure);
return ex;
}
///
/// Create a step scope that automatically tracks duration.
///
public static StepScope TimeStep(this TelemetryClient client, string name, string? category = null)
{
return JourneyContext.StartStep(name, category);
}
///
/// Execute an action within a tracked step.
///
public static void TrackStep(string name, Action action, string? category = null)
{
using var step = IronTelemetry.StartStep(name, category);
try
{
action();
}
catch (Exception ex)
{
step.Fail(ex.Message);
throw;
}
}
///
/// Execute an async action within a tracked step.
///
public static async Task TrackStepAsync(string name, Func action, string? category = null)
{
using var step = IronTelemetry.StartStep(name, category);
try
{
await action();
}
catch (Exception ex)
{
step.Fail(ex.Message);
throw;
}
}
///
/// Execute a function within a tracked step and return the result.
///
public static T TrackStep(string name, Func func, string? category = null)
{
using var step = IronTelemetry.StartStep(name, category);
try
{
return func();
}
catch (Exception ex)
{
step.Fail(ex.Message);
throw;
}
}
///
/// Execute an async function within a tracked step and return the result.
///
public static async Task TrackStepAsync(string name, Func> func, string? category = null)
{
using var step = IronTelemetry.StartStep(name, category);
try
{
return await func();
}
catch (Exception ex)
{
step.Fail(ex.Message);
throw;
}
}
///
/// Add Activity trace context to the current telemetry.
///
public static ExceptionContext WithActivity(this ExceptionContext context, Activity? activity = null)
{
activity ??= Activity.Current;
if (activity != null)
{
context.TraceId = activity.TraceId.ToString();
context.SpanId = activity.SpanId.ToString();
}
return context;
}
///
/// Execute a journey and return the result.
///
public static T RunJourney(string name, Func action)
{
using var journey = IronTelemetry.StartJourney(name);
try
{
var result = action();
journey.Complete();
return result;
}
catch (Exception ex)
{
journey.Fail(ex.Message);
IronTelemetry.CaptureException(ex);
throw;
}
}
///
/// Execute an async journey and return the result.
///
public static async Task RunJourneyAsync(string name, Func> action)
{
using var journey = IronTelemetry.StartJourney(name);
try
{
var result = await action();
journey.Complete();
return result;
}
catch (Exception ex)
{
journey.Fail(ex.Message);
IronTelemetry.CaptureException(ex);
throw;
}
}
}