Реализация Session Replay (запись сессии пользователя) для мобильного приложения
Session Replay на мобильных устройствах — технически сложнее, чем в вебе. Браузер всегда рендерит DOM, который можно сериализовать. Мобильное приложение рендерит нативный UI через UIKit, Jetpack Compose или Flutter engine, и «снимок» этого состояния требует либо скриншотов, либо захвата wire-frame представления View-иерархии.
Плохая реализация Session Replay потребляет 10–20% дополнительного CPU и 100–200KB сетевого трафика в минуту. Хорошая — незаметна для пользователя.
Два подхода к записи
Screenshot-based (UXCam, Smartlook, некоторые режимы Datadog): делает снимки экрана с заданным интервалом (обычно 1–5 fps), маскирует чувствительные области, отправляет на сервер. Точно передаёт визуальное состояние, включая кастомные View и WebView. Недостаток: большой объём данных, сложность маскировки динамического контента.
Wire-frame / View-tree based (Sentry, некоторые режимы Datadog): сериализует иерархию View с позициями, цветами и текстом, воспроизводит UI на сервере через шаблоны. Легче по трафику и CPU, но WebView и кастомная графика не воспроизводятся точно.
Реализация через Sentry Session Replay
Sentry Session Replay для мобильных доступен с SDK 8.x. Использует wire-frame подход:
// iOS
import Sentry
SentrySDK.start { options in
options.dsn = "https://[email protected]/project"
options.experimental.sessionReplay = SentryReplayOptions(
sessionSampleRate: 0.1, // 10% случайных сессий
onErrorSampleRate: 1.0 // 100% сессий, где произошёл крэш/ошибка
)
}
// Android
SentryAndroid.init(this) { options ->
options.dsn = "https://[email protected]/project"
options.experimental.sessionReplay.apply {
sessionSampleRate = 0.1
onErrorSampleRate = 1.0
}
}
onErrorSampleRate = 1.0 — ключевой параметр. Это значит: записывать replay для всех сессий, где произошла ошибка. SDK буферизует последние N секунд replay в памяти и отправляет их вместе с error report. Так вы видите, что именно делал пользователь до крэша.
Маскировка чувствительных данных
По умолчанию Sentry маскирует UITextField и поля с isSecureTextEntry = true. Этого недостаточно — нужно также скрывать карточные данные, персональные данные и OTP-поля.
// iOS — маркировка View для маскировки
class PaymentCardView: UIView {
override func didMoveToWindow() {
super.didMoveToWindow()
// Sentry распознаёт это через SentryReplayMask
SentrySDK.replay.maskView(self)
}
}
// Android — маскировка через тег или аннотацию
val cardNumberField = findViewById<EditText>(R.id.cardNumber)
cardNumberField.setTag(io.sentry.android.replay.Recorder.MASK_TAG, true)
Для SwiftUI и Jetpack Compose:
// SwiftUI
Text(userEmail)
.sentryReplayMask()
// Маскировать целый экран
struct PaymentScreen: View {
var body: some View {
// ...
}
}
// В конфигурации: маскировать все View с именем "PaymentScreen"
// Compose
Text(
text = cardNumber,
modifier = Modifier.sentryReplayMask()
)
Интеграция с crash reports
Самая ценная функция Session Replay — ссылка из крэш-репорта на запись сессии. В Sentry это работает автоматически: если в момент ошибки был активный replay-буфер, в Issue появляется кнопка «Watch Session Replay».
Это меняет процесс дебаггинга: вместо воспроизведения по шагам из описания пользователя — смотришь запись и видишь точно, что произошло.
Настройка Datadog Session Replay
Datadog поддерживает два режима: wire-frame (по умолчанию) и screenshot. Screenshot включается явно:
import DatadogSessionReplay
SessionReplay.enable(
with: SessionReplay.Configuration(
replaySampleRate: 20, // 20% сессий
defaultPrivacyLevel: .maskUserInput // маскируем ввод
)
)
Datadog Session Replay связывается с RUM View — в интерфейсе можно открыть конкретный View и посмотреть replay именно этого экрана, с метриками (latency, FPS) на таймлайне.
Производительность и overhead
Тестирование Sentry wire-frame режима на production устройствах показывает:
| Показатель | Overhead |
|---|---|
| CPU (background sampling) | < 1% |
| Memory (буфер 60 сек) | ~8–15 MB |
| Сетевой трафик (при отправке) | ~50–150 KB/мин |
| Время на сериализацию View-tree | < 2ms per frame |
Screenshot-based режимы дороже: CPU 3–8%, трафик 200–500 KB/мин при 2 fps.
Что делаем
- Выбираем инструмент и режим записи под требования безопасности и производительности
- Подключаем SDK с
onErrorSampleRate = 1.0для записи сессий с ошибками - Настраиваем маскировку всех экранов и элементов с персональными данными
- Верифицируем маскировку через Privacy Audit в Sentry/Datadog UI
- Настраиваем связку replay → crash report для быстрой диагностики
Сроки
Базовое подключение с маскировкой: 2–3 дня. Полная интеграция с аудитом приватности: 4–5 дней. Стоимость рассчитывается индивидуально.







