Skip to content

Observability & Crash Reporting

The SDK provides hooks for integrating with your existing observability stack — Sentry, Crashlytics, Datadog, or any custom provider.

Crash Reporting

Sentry

import * as Sentry from '@sentry/react-native';
import { Logger, AnalyticsTracker } from '@squad-sports/core';

// Forward SDK errors to Sentry
Logger.shared.configure({
  sink: (level, message, context) => {
    if (level === 'error') {
      Sentry.captureMessage(message, { level: 'error', extra: context });
    } else {
      Sentry.addBreadcrumb({ message, level, data: context });
    }
  },
});

// Forward analytics to Sentry performance
AnalyticsTracker.shared.configure({
  customAdapter: (event) => {
    Sentry.addBreadcrumb({
      category: 'squad',
      message: event.name,
      data: event.properties,
    });
  },
});

Also wire the onError prop:

<SquadExperience
  partnerId="your-id"
  apiKey="your-key"
  onError={(error) => Sentry.captureException(error)}
/>
import Sentry

SquadLogger.shared.sink = SentryLogSink()

class SentryLogSink: SquadLogSink {
    func log(level: SquadLogLevel, message: String, context: [String: Any]) {
        let breadcrumb = Breadcrumb(level: level == .error ? .error : .info, category: "squad")
        breadcrumb.message = message
        breadcrumb.data = context
        SentrySDK.addBreadcrumb(breadcrumb)

        if level == .error {
            SentrySDK.capture(message: message)
        }
    }
}
import io.sentry.Sentry
import io.sentry.Breadcrumb
import io.sentry.SentryLevel

SquadLogger.handler = { level, tag, message ->
    val breadcrumb = Breadcrumb().apply {
        this.category = "squad"
        this.message = "[$tag] $message"
        this.level = when (level) {
            SquadLogLevel.ERROR -> SentryLevel.ERROR
            SquadLogLevel.WARN -> SentryLevel.WARNING
            else -> SentryLevel.INFO
        }
    }
    Sentry.addBreadcrumb(breadcrumb)

    if (level == SquadLogLevel.ERROR) {
        Sentry.captureMessage("[$tag] $message", SentryLevel.ERROR)
    }
}

Firebase Crashlytics

import crashlytics from '@react-native-firebase/crashlytics';
import { Logger } from '@squad-sports/core';

Logger.shared.configure({
  sink: (level, message, context) => {
    crashlytics().log(`[Squad:${level}] ${message}`);
    if (level === 'error') {
      crashlytics().recordError(new Error(message));
    }
  },
});
import FirebaseCrashlytics

SquadLogger.shared.sink = CrashlyticsLogSink()

class CrashlyticsLogSink: SquadLogSink {
    func log(level: SquadLogLevel, message: String, context: [String: Any]) {
        Crashlytics.crashlytics().log("[Squad:\(level)] \(message)")
        if level == .error {
            Crashlytics.crashlytics().record(error: NSError(
                domain: "SquadSDK", code: -1,
                userInfo: [NSLocalizedDescriptionKey: message]
            ))
        }
    }
}
import com.google.firebase.crashlytics.FirebaseCrashlytics

SquadLogger.handler = { level, tag, message ->
    FirebaseCrashlytics.getInstance().log("[$tag:$level] $message")
    if (level == SquadLogLevel.ERROR) {
        FirebaseCrashlytics.getInstance().recordException(RuntimeException("[$tag] $message"))
    }
}

Datadog / Custom APM

import { Logger, AnalyticsTracker } from '@squad-sports/core';

Logger.shared.configure({
  sink: (level, message, context) => {
    datadogRum.addAction('squad_log', { level, message, ...context });
  },
});

AnalyticsTracker.shared.configure({
  customAdapter: (event) => {
    datadogRum.addAction(event.name, event.properties);
  },
});

Request Tracing

Every API response includes an X-Request-ID header. When reporting issues to Squad support, include this value along with:

  • SDK version (X-Squad-SDK-Version header value)
  • Timestamp of the issue
  • Platform and OS version
  • Steps to reproduce

This allows us to correlate your report with our server logs within seconds.

Debug Mode

Enable verbose logging during development:

Logger.shared.configure({ minLevel: 'debug' });
SquadLogger.shared.minLevel = .debug
SquadLogger.minLevel = SquadLogLevel.DEBUG

Debug mode logs all API requests/responses, SSE events, auth state changes, and analytics events. Disable in production builds.