namespace IronTelemetry.Client;
///
/// Static API for IronTelemetry.
/// Level 0: Drop-in error capture (Init + CaptureException)
/// Level 1: Ambient journey correlation (StartJourney + StartStep)
///
public static class IronTelemetry
{
private static TelemetryClient? _client;
private static readonly object _lock = new();
///
/// Initialize IronTelemetry with a DSN.
///
public static void Init(string dsn)
{
Init(new TelemetryOptions { Dsn = dsn });
}
///
/// Initialize IronTelemetry with options.
///
public static void Init(TelemetryOptions options)
{
lock (_lock)
{
_client = new TelemetryClient(options);
}
}
#region Level 0 - Exception Capture
///
/// Capture an exception and send it to IronTelemetry.
/// Automatically correlates with current journey if one exists.
///
public static void CaptureException(Exception ex)
{
EnsureInitialized();
_client!.CaptureException(ex);
}
///
/// Capture an exception with additional context.
///
public static void CaptureException(Exception ex, Action configure)
{
EnsureInitialized();
var context = new ExceptionContext();
configure(context);
_client!.CaptureException(ex, context);
}
///
/// Capture a message.
///
public static void CaptureMessage(string message, TelemetryLevel level = TelemetryLevel.Info)
{
EnsureInitialized();
_client!.CaptureMessage(message, level);
}
///
/// Add a breadcrumb to the current context.
///
public static void AddBreadcrumb(string message, string? category = null)
{
EnsureInitialized();
_client!.AddBreadcrumb(new Breadcrumb
{
Message = message,
Category = category ?? "default",
Level = BreadcrumbLevel.Info,
Timestamp = DateTime.UtcNow
});
}
///
/// Add a breadcrumb to the current context.
///
public static void AddBreadcrumb(Breadcrumb breadcrumb)
{
EnsureInitialized();
_client!.AddBreadcrumb(breadcrumb);
}
///
/// Set the current user context.
///
public static void SetUser(string? id, string? email = null, string? username = null)
{
EnsureInitialized();
_client!.SetUser(id, email, username);
}
///
/// Set a global tag that will be sent with all events.
///
public static void SetTag(string key, string value)
{
EnsureInitialized();
_client!.SetTag(key, value);
}
///
/// Set extra data that will be sent with all events.
///
public static void SetExtra(string key, object value)
{
EnsureInitialized();
_client!.SetExtra(key, value);
}
#endregion
#region Level 1 - Journey Correlation
///
/// Start a new journey. All telemetry within this scope will be correlated.
///
/// The journey name (e.g., "Checkout Flow", "User Onboarding")
/// A disposable scope - dispose to end the journey
///
/// using (IronTelemetry.StartJourney("Checkout Flow"))
/// {
/// IronTelemetry.SetUser(currentUser.Id);
///
/// using (IronTelemetry.StartStep("Validate Cart", "business"))
/// {
/// ValidateCart();
/// }
///
/// using (IronTelemetry.StartStep("Process Payment", "business"))
/// {
/// ProcessPayment();
/// }
/// }
///
public static JourneyScope StartJourney(string name)
{
EnsureInitialized();
return JourneyContext.StartJourney(name);
}
///
/// Start a step within the current journey.
/// If no journey exists, one is created automatically.
///
/// The step name (e.g., "Validate Cart", "Process Payment")
/// Optional category (e.g., "business", "technical", "navigation")
/// A disposable scope - dispose to end the step
public static StepScope StartStep(string name, string? category = null)
{
EnsureInitialized();
return JourneyContext.StartStep(name, category);
}
///
/// Gets the current journey, if any.
///
public static JourneyScope? CurrentJourney => JourneyContext.Current;
///
/// Gets the current step, if any.
///
public static StepScope? CurrentStep => JourneyContext.CurrentStep;
///
/// Gets the current journey ID, if any.
///
public static string? CurrentJourneyId => JourneyContext.CurrentJourneyId;
///
/// Set metadata on the current journey.
///
public static void SetJourneyMetadata(string key, object value)
{
JourneyContext.SetMetadata(key, value);
}
///
/// Mark the current step as failed.
///
public static void FailCurrentStep(string? reason = null)
{
JourneyContext.FailCurrentStep(reason);
}
#endregion
#region Flush
///
/// Flush any pending events synchronously.
///
public static void Flush(TimeSpan? timeout = null)
{
_client?.Flush(timeout ?? TimeSpan.FromSeconds(5));
}
///
/// Flush any pending events asynchronously.
///
public static Task FlushAsync(TimeSpan? timeout = null)
{
return _client?.FlushAsync(timeout ?? TimeSpan.FromSeconds(5)) ?? Task.CompletedTask;
}
#endregion
///
/// Get whether the SDK is initialized.
///
public static bool IsInitialized => _client != null;
///
/// Get the underlying TelemetryClient instance.
/// Returns null if not initialized.
///
public static TelemetryClient? Client => _client;
private static void EnsureInitialized()
{
if (_client == null)
{
throw new InvalidOperationException(
"IronTelemetry has not been initialized. Call IronTelemetry.Init() first.");
}
}
}