using System.Diagnostics; 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(); private static bool _enableDebugLogging; /// /// Enable verbose debug output during development. /// When enabled, all events are written to System.Diagnostics.Debug.WriteLine. /// /// /// IronTelemetry.EnableDebugLogging = true; // Enable during development /// public static bool EnableDebugLogging { get => _enableDebugLogging; set => _enableDebugLogging = value; } /// /// Writes a debug message if EnableDebugLogging is true. /// internal static void DebugLog(string message) { if (_enableDebugLogging) { Debug.WriteLine($"[IronTelemetry] {message}"); } } /// /// 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); } /// /// Log a message with a title, message, and optional metadata. /// This is useful for debugging and informational logging without exceptions. /// /// Log level: "info", "warning", "error", "debug" /// Short title for the log entry /// Detailed message (optional) /// Optional additional data public static void LogMessage(string level, string title, string? message = null, Dictionary? data = null) { EnsureInitialized(); _client!.LogMessage(level, title, message, data); } /// /// Get all current breadcrumbs. Useful for viewing breadcrumbs in a debug UI. /// public static IReadOnlyList GetBreadcrumbs() { EnsureInitialized(); return _client!.GetBreadcrumbs(); } /// /// 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."); } } }