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