<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Документация Proto Observability Platform – flutter</title><link>/docs/tags/flutter/</link><description>Recent content in flutter on Документация Proto Observability Platform</description><generator>Hugo -- gohugo.io</generator><language>ru</language><atom:link href="/docs/tags/flutter/index.xml" rel="self" type="application/rss+xml"/><item><title>Instrumentation: EUM мониторинг Flutter-приложений</title><link>/docs/instrumentation/eum/flutter/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/docs/instrumentation/eum/flutter/</guid><description>
&lt;p>На этой странице:&lt;/p>
&lt;ul>
&lt;li>&lt;a href="#%d0%b2%d0%b2%d0%b5%d0%b4%d0%b5%d0%bd%d0%b8%d0%b5">Введение&lt;/a>&lt;/li>
&lt;li>&lt;a href="#%d1%81%d0%be%d1%81%d1%82%d0%b0%d0%b2-%d0%b8%d0%bd%d1%82%d0%b5%d0%b3%d1%80%d0%b0%d1%86%d0%b8%d0%b8">Состав интеграции&lt;/a>&lt;/li>
&lt;li>&lt;a href="#%d0%b0%d0%b4%d1%80%d0%b5%d1%81-%d0%bf%d1%80%d0%b8%d1%91%d0%bc%d0%b0-%d0%b4%d0%b0%d0%bd%d0%bd%d1%8b%d1%85">Адрес приёма данных&lt;/a>&lt;/li>
&lt;li>&lt;a href="#%d1%83%d1%81%d1%82%d0%b0%d0%bd%d0%be%d0%b2%d0%ba%d0%b0-%d0%bf%d0%b0%d0%ba%d0%b5%d1%82%d0%be%d0%b2">Установка пакетов&lt;/a>&lt;/li>
&lt;li>&lt;a href="#%d0%b8%d0%bd%d0%b8%d1%86%d0%b8%d0%b0%d0%bb%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f">Инициализация&lt;/a>&lt;/li>
&lt;li>&lt;a href="#%d0%be%d1%82%d1%81%d0%bb%d0%b5%d0%b6%d0%b8%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%8d%d0%ba%d1%80%d0%b0%d0%bd%d0%be%d0%b2">Отслеживание экранов&lt;/a>&lt;/li>
&lt;li>&lt;a href="#%d1%81%d0%b5%d1%82%d0%b5%d0%b2%d1%8b%d0%b5-%d0%b7%d0%b0%d0%bf%d1%80%d0%be%d1%81%d1%8b-%d0%b8-%d1%81%d0%ba%d0%b2%d0%be%d0%b7%d0%bd%d0%b0%d1%8f-%d1%82%d1%80%d0%b0%d1%81%d1%81%d0%b8%d1%80%d0%be%d0%b2%d0%ba%d0%b0">Сетевые запросы и сквозная трассировка&lt;/a>&lt;/li>
&lt;li>&lt;a href="#%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d0%be%d0%b2%d0%b0%d1%82%d0%b5%d0%bb%d1%8c%d1%81%d0%ba%d0%b8%d0%b5-%d1%81%d0%be%d0%b1%d1%8b%d1%82%d0%b8%d1%8f-%d0%b0%d1%82%d1%80%d0%b8%d0%b1%d1%83%d1%82%d1%8b-%d0%b8-%d0%be%d1%88%d0%b8%d0%b1%d0%ba%d0%b8">Пользовательские события, атрибуты и ошибки&lt;/a>
&lt;ul>
&lt;li>&lt;a href="#%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d0%be%d0%b2%d0%b0%d1%82%d0%b5%d0%bb%d1%8c%d1%81%d0%ba%d0%b8%d0%b5-%d0%b4%d0%b5%d0%b9%d1%81%d1%82%d0%b2%d0%b8%d1%8f">Пользовательские действия&lt;/a>&lt;/li>
&lt;li>&lt;a href="#%d0%b0%d1%82%d1%80%d0%b8%d0%b1%d1%83%d1%82%d1%8b">Атрибуты&lt;/a>&lt;/li>
&lt;li>&lt;a href="#%d0%be%d1%88%d0%b8%d0%b1%d0%ba%d0%b8-%d0%b8-%d1%81%d1%82%d0%b5%d0%ba%d1%82%d1%80%d0%b5%d0%b9%d1%81%d1%8b">Ошибки и стектрейсы&lt;/a>&lt;/li>
&lt;li>&lt;a href="#%d1%87%d1%82%d0%be-%d1%81-%d1%8d%d1%82%d0%b8%d0%bc%d0%b8-%d0%b4%d0%b0%d0%bd%d0%bd%d1%8b%d0%bc%d0%b8-%d0%bc%d0%be%d0%b6%d0%bd%d0%be-%d0%b4%d0%b5%d0%bb%d0%b0%d1%82%d1%8c-%d0%b2-%d0%bf%d0%bb%d0%b0%d1%82%d1%84%d0%be%d1%80%d0%bc%d0%b5">Что с этими данными можно делать в платформе&lt;/a>&lt;/li>
&lt;li>&lt;a href="#%d0%be%d0%b1%d1%84%d1%83%d1%81%d1%86%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%bd%d1%8b%d0%b5-%d1%81%d1%82%d0%b5%d0%ba%d1%82%d1%80%d0%b5%d0%b9%d1%81%d1%8b">Обфусцированные стектрейсы&lt;/a>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;a href="#%d1%81%d0%b5%d1%82%d0%b5%d0%b2%d1%8b%d0%b5-%d0%b4%d0%be%d1%81%d1%82%d1%83%d0%bf%d1%8b">Сетевые доступы&lt;/a>&lt;/li>
&lt;li>&lt;a href="#%d0%bf%d1%80%d0%be%d0%b2%d0%b5%d1%80%d0%ba%d0%b0-%d0%bf%d0%be%d0%b4%d0%ba%d0%bb%d1%8e%d1%87%d0%b5%d0%bd%d0%b8%d1%8f">Проверка подключения&lt;/a>&lt;/li>
&lt;li>&lt;a href="#%d0%be%d0%b1%d0%bb%d0%b0%d1%81%d1%82%d1%8c-%d0%bf%d1%80%d0%b8%d0%bc%d0%b5%d0%bd%d0%b5%d0%bd%d0%b8%d1%8f-%d0%b8%d0%bd%d1%81%d1%82%d1%80%d1%83%d0%ba%d1%86%d0%b8%d0%b8">Область применения инструкции&lt;/a>&lt;/li>
&lt;li>&lt;a href="#%d0%b4%d0%b8%d0%b0%d0%b3%d0%bd%d0%be%d1%81%d1%82%d0%b8%d0%ba%d0%b0-%d0%bd%d0%b5%d0%bf%d0%be%d0%bb%d0%b0%d0%b4%d0%be%d0%ba">Диагностика неполадок&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="введение">Введение&lt;/h2>
&lt;p>Пакет &lt;code>datadog_flutter_plugin&lt;/code> передаёт данные RUM в формате, который Proto Observability Platform принимает и обрабатывает штатно. Чтобы данные приходили в платформу, достаточно указать в конфигурации пакета адрес приёма ProtoOBP.&lt;/p>
&lt;p>Что при этом важно знать:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Учётная запись Datadog не требуется.&lt;/strong> Токен клиента (&lt;code>clientToken&lt;/code>) и идентификатор приложения (&lt;code>applicationId&lt;/code>) передаются в запросах как есть; платформа их не проверяет и не обращается к внешним сервисам для их валидации. Задайте любые непустые значения — они удобны как метки, но на приём данных не влияют.&lt;/li>
&lt;li>&lt;strong>Адрес приёма подставляется целиком.&lt;/strong> Пакет не дописывает путь к значению &lt;code>customEndpoint&lt;/code>, поэтому указывать нужно полный URL вместе с путём. Это самая частая причина, по которой данные не появляются.&lt;/li>
&lt;li>&lt;strong>Параметр &lt;code>site&lt;/code> обязателен по контракту пакета,&lt;/strong> но при заданном &lt;code>customEndpoint&lt;/code> в отправке данных не участвует. Оставьте любое значение.&lt;/li>
&lt;/ul>
&lt;p>Для нативных мобильных приложений используются агенты Proto Observability: &lt;a href="android">Android&lt;/a> и &lt;a href="ios">iOS&lt;/a>.&lt;/p>
&lt;p>Состав атрибутов, которые собираются и становятся доступны в интерфейсе, приведён на странице &lt;a href="data-collected">Собираемые данные RUM и Mobile&lt;/a> — Flutter-приложения используют ту же схему событий, что Android и iOS.&lt;/p>
&lt;h2 id="состав-интеграции">Состав интеграции&lt;/h2>
&lt;p>Подключается &lt;strong>один пакет&lt;/strong> — &lt;code>datadog_flutter_plugin&lt;/code>. Он покрывает обе мобильные платформы: приведённая ниже настройка работает и на Android, и на iOS, платформенно-зависимый код писать не нужно.&lt;/p>
&lt;p>Отдельно подключать библиотеки для Android и iOS не требуется. Пакет представляет собой обвязку над платформенными библиотеками, и они подтягиваются как транзитивные зависимости при обычной сборке проекта:&lt;/p>
&lt;ul>
&lt;li>на Android — &lt;code>dd-sdk-android-rum&lt;/code>, &lt;code>dd-sdk-android-logs&lt;/code>, &lt;code>dd-sdk-android-ndk&lt;/code> версии 3.11.0 через Gradle;&lt;/li>
&lt;li>на iOS — &lt;code>DatadogCore&lt;/code>, &lt;code>DatadogRUM&lt;/code>, &lt;code>DatadogLogs&lt;/code>, &lt;code>DatadogCrashReporting&lt;/code>, &lt;code>DatadogInternal&lt;/code> версии 3.13.0 через CocoaPods.&lt;/li>
&lt;/ul>
&lt;p>Версии платформенных библиотек зафиксированы в самом пакете. Ручные правки в &lt;code>build.gradle&lt;/code> и &lt;code>Podfile&lt;/code> не нужны, код инициализации на Kotlin и Swift писать не нужно — вся настройка выполняется на Dart.&lt;/p>
&lt;p>Требования к среде для &lt;code>datadog_flutter_plugin&lt;/code> 3.4.1: Flutter 3.27 и новее, Dart 3.6 и новее, Android &lt;code>minSdkVersion&lt;/code> 23, iOS 12.0 и новее.&lt;/p>
&lt;p>Пакет поддерживает и Flutter Web — в этом случае под капотом используется браузерная библиотека. Подключение веб-приложений, написанных не на Flutter, описано на странице &lt;a href="browser">Browser&lt;/a>.&lt;/p>
&lt;h2 id="адрес-приёма-данных">Адрес приёма данных&lt;/h2>
&lt;p>Данные RUM принимаются по адресу:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">https://&amp;lt;адрес ProtoOBP&amp;gt;/api/v2/rum
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Равнозначные адреса, если на вашем периметре уже настроена маршрутизация по одному из этих префиксов:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">https://&amp;lt;адрес ProtoOBP&amp;gt;/eum/api/v2/rum
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">https://&amp;lt;адрес ProtoOBP&amp;gt;/mobile/api/v2/rum
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Перед подключением уточните у администратора платформы:&lt;/p>
&lt;ul>
&lt;li>полный адрес приёма для вашего контура;&lt;/li>
&lt;li>что лицензия платформы включает модуль мониторинга цифрового опыта (DEM) — без него запросы отклоняются с кодом 403;&lt;/li>
&lt;li>что приём RUM включён в конфигурации компонента приёма данных.&lt;/li>
&lt;/ul>
&lt;h2 id="установка-пакетов">Установка пакетов&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">flutter pub add datadog_flutter_plugin datadog_tracking_http_client
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="инициализация">Инициализация&lt;/h2>
&lt;p>В &lt;code>lib/main.dart&lt;/code>:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-dart" data-lang="dart">&lt;span class="line">&lt;span class="cl">&lt;span class="k">import&lt;/span> &lt;span class="s1">&amp;#39;package:datadog_flutter_plugin/datadog_flutter_plugin.dart&amp;#39;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">import&lt;/span> &lt;span class="s1">&amp;#39;package:datadog_tracking_http_client/datadog_tracking_http_client.dart&amp;#39;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">import&lt;/span> &lt;span class="s1">&amp;#39;package:flutter/material.dart&amp;#39;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Адрес приёма ProtoOBP. Указывается ПОЛНОСТЬЮ, вместе с путём:
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// пакет не дописывает /api/v2/rum к этому значению.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="kd">const&lt;/span> &lt;span class="n">protoObpRumEndpoint&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s1">&amp;#39;https://protoobp.example.ru/api/v2/rum&amp;#39;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">Future&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">void&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">main&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="kd">async&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">WidgetsFlutterBinding&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">ensureInitialized&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">final&lt;/span> &lt;span class="n">configuration&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">DatadogConfiguration&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Произвольная непустая строка: платформа токен не проверяет.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nl">clientToken:&lt;/span> &lt;span class="s1">&amp;#39;protoobp&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Окружение — попадает в данные как тег и доступно для фильтрации.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nl">env:&lt;/span> &lt;span class="s1">&amp;#39;prod&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Обязателен по контракту пакета; при заданном customEndpoint не используется.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nl">site:&lt;/span> &lt;span class="n">DatadogSite&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">eu1&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Название приложения в интерфейсе платформы.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nl">service:&lt;/span> &lt;span class="s1">&amp;#39;my-mobile-app&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nl">nativeCrashReportEnabled:&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Домены вашего бэкенда — к запросам к ним добавляются заголовки трассировки.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nl">firstPartyHosts:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;api.example.ru&amp;#39;&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nl">rumConfiguration:&lt;/span> &lt;span class="n">DatadogRumConfiguration&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Произвольный идентификатор приложения.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nl">applicationId:&lt;/span> &lt;span class="s1">&amp;#39;my-mobile-app&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 100 — собирать все сессии, 10 — 10 % сессий.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nl">sessionSamplingRate:&lt;/span> &lt;span class="m">100&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Внутренняя телеметрия пакета платформой не используется — отключаем.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nl">telemetrySampleRate:&lt;/span> &lt;span class="m">0&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nl">detectLongTasks:&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// Метрики отрисовки кадров Flutter.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nl">reportFlutterPerformance:&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nl">customEndpoint:&lt;/span> &lt;span class="n">protoObpRumEndpoint&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">)..&lt;/span>&lt;span class="n">enableHttpTracking&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">await&lt;/span> &lt;span class="n">DatadogSdk&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">runApp&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">configuration&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">TrackingConsent&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">granted&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">()&lt;/span> &lt;span class="kd">async&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">runApp&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kd">const&lt;/span> &lt;span class="n">MyApp&lt;/span>&lt;span class="p">());&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Данные о текущем пользователе задаются отдельно и не обязательны:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-dart" data-lang="dart">&lt;span class="line">&lt;span class="cl">&lt;span class="n">DatadogSdk&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">instance&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">setUserInfo&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nl">id:&lt;/span> &lt;span class="s1">&amp;#39;1234&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nl">name:&lt;/span> &lt;span class="s1">&amp;#39;Василий Пупкин&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nl">email:&lt;/span> &lt;span class="s1">&amp;#39;vass@pupkine.com&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="отслеживание-экранов">Отслеживание экранов&lt;/h2>
&lt;p>Чтобы переходы между экранами становились отдельными просмотрами, добавьте наблюдатель навигации:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-dart" data-lang="dart">&lt;span class="line">&lt;span class="cl">&lt;span class="kd">class&lt;/span> &lt;span class="nc">MyApp&lt;/span> &lt;span class="kd">extends&lt;/span> &lt;span class="n">StatelessWidget&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">const&lt;/span> &lt;span class="n">MyApp&lt;/span>&lt;span class="p">({&lt;/span>&lt;span class="k">super&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">key&lt;/span>&lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="err">@&lt;/span>&lt;span class="n">override&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">Widget&lt;/span> &lt;span class="n">build&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">BuildContext&lt;/span> &lt;span class="n">context&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">MaterialApp&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nl">navigatorObservers:&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">DatadogNavigationObserver&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nl">datadogSdk:&lt;/span> &lt;span class="n">DatadogSdk&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">instance&lt;/span>&lt;span class="p">),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nl">routes:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;/&amp;#39;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">_&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">=&amp;gt;&lt;/span> &lt;span class="kd">const&lt;/span> &lt;span class="n">HomeScreen&lt;/span>&lt;span class="p">(),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;/details&amp;#39;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">_&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">=&amp;gt;&lt;/span> &lt;span class="kd">const&lt;/span> &lt;span class="n">DetailsScreen&lt;/span>&lt;span class="p">(),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Имя маршрута становится именем экрана в интерфейсе платформы, поэтому маршруты стоит называть осмысленно.&lt;/p>
&lt;h2 id="сетевые-запросы-и-сквозная-трассировка">Сетевые запросы и сквозная трассировка&lt;/h2>
&lt;p>Вызов &lt;code>..enableHttpTracking()&lt;/code> в примере выше подменяет &lt;code>HttpOverrides.global&lt;/code>, после чего сетевые запросы приложения собираются как события ресурсов. Если в приложении используются собственные &lt;code>HttpOverrides&lt;/code>, установите их до инициализации.&lt;/p>
&lt;p>К запросам на домены из &lt;code>firstPartyHosts&lt;/code> добавляются заголовки трассировки. Если на этих серверах установлены агенты Proto Observability, вызовы с мобильного устройства и обработка на бэкенде объединяются в единую цепочку — трейс распределённой транзакции, начавшейся на устройстве пользователя.&lt;/p>
&lt;h2 id="пользовательские-события-атрибуты-и-ошибки">Пользовательские события, атрибуты и ошибки&lt;/h2>
&lt;p>Кроме автоматически собираемых данных (экраны, нажатия, сетевые запросы, падения) приложение может отправлять собственные события — продуктовые и бизнесовые. Отдельный SDK для этого не требуется: используются штатные методы уже подключённого пакета, а платформа принимает такие события тем же потоком, что и остальные данные RUM.&lt;/p>
&lt;h3 id="пользовательские-действия">Пользовательские действия&lt;/h3>
&lt;p>Событие с типом &lt;code>custom&lt;/code> — основной способ передать продуктовое событие вместе с произвольным набором полей.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-dart" data-lang="dart">&lt;span class="line">&lt;span class="cl">&lt;span class="n">DatadogSdk&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">instance&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">rum&lt;/span>&lt;span class="o">?&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">addAction&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">RumActionType&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">custom&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;payment_confirmed&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;payment_type&amp;#39;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;p2p&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;amount&amp;#39;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="m">12500&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;currency&amp;#39;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;KGS&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;channel&amp;#39;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;mobile&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Для действий с длительностью используются парные вызовы &lt;code>startAction&lt;/code> и &lt;code>stopAction&lt;/code> — платформа получит длительность действия.&lt;/p>
&lt;p>Имя события (&lt;code>payment_confirmed&lt;/code>) становится значением поля цели действия, тип — значением &lt;code>custom&lt;/code>. Оба поля доступны как измерения в дашбордах и выборках.&lt;/p>
&lt;h3 id="атрибуты">Атрибуты&lt;/h3>
&lt;p>Атрибуты бывают двух видов.&lt;/p>
&lt;p>&lt;strong>Разовые&lt;/strong> — передаются вместе с конкретным событием, как в примере выше.&lt;/p>
&lt;p>&lt;strong>Постоянные&lt;/strong> — задаются один раз и добавляются ко всем последующим событиям сессии. Удобны для сегментации: тип клиента, тарифный план, роль, признак участия в эксперименте.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-dart" data-lang="dart">&lt;span class="line">&lt;span class="cl">&lt;span class="n">DatadogSdk&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">instance&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">rum&lt;/span>&lt;span class="o">?&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">addAttribute&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;client_segment&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;corporate&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">DatadogSdk&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">instance&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">rum&lt;/span>&lt;span class="o">?&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">addAttribute&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;tariff&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;business_pro&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Атрибуты попадают в поле &lt;code>context&lt;/code> события. В платформе они доступны под ключами вида &lt;code>context.client_segment&lt;/code>, &lt;code>context.amount&lt;/code> — включая вложенные структуры, которые разворачиваются в ключи через точку.&lt;/p>
&lt;p>Персональные данные в атрибуты помещать не следует: события хранятся в аналитическом контуре платформы и доступны всем, у кого есть права на просмотр данных приложения.&lt;/p>
&lt;h3 id="ошибки-и-стектрейсы">Ошибки и стектрейсы&lt;/h3>
&lt;p>Механизм фиксирования стектрейсов включён в пакет и дополнительной разработки не требует. Собираются три категории:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Падения приложения&lt;/strong> — при &lt;code>nativeCrashReportEnabled: true&lt;/code>. Отправляются при следующем запуске приложения.&lt;/li>
&lt;li>&lt;strong>Необработанные исключения&lt;/strong> — перехватываются автоматически после инициализации.&lt;/li>
&lt;li>&lt;strong>Ошибки, переданные явно&lt;/strong> — там, где приложение обрабатывает исключение само, но событие нужно зафиксировать.&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-dart" data-lang="dart">&lt;span class="line">&lt;span class="cl">&lt;span class="k">try&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">await&lt;/span> &lt;span class="n">transferService&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">send&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">request&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span> &lt;span class="k">catch&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">error&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">stackTrace&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">DatadogSdk&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">instance&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">rum&lt;/span>&lt;span class="o">?&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">addError&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">error&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">RumErrorSource&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="k">source&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nl">stackTrace:&lt;/span> &lt;span class="n">stackTrace&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nl">errorType:&lt;/span> &lt;span class="s1">&amp;#39;TransferFailed&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nl">attributes:&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="s1">&amp;#39;payment_type&amp;#39;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;p2p&amp;#39;&lt;/span>&lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">rethrow&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Если исключения как объекта нет, а есть только сообщение, используется &lt;code>addErrorInfo(message, source, stackTrace: …)&lt;/code>.&lt;/p>
&lt;p>Платформа сохраняет по каждой ошибке сообщение, тип, источник, полный стектрейс, признак падения приложения и отпечаток ошибки для группировки, а также экран, сессию, пользователя и версию приложения, в контексте которых ошибка произошла.&lt;/p>
&lt;h3 id="что-с-этими-данными-можно-делать-в-платформе">Что с этими данными можно делать в платформе&lt;/h3>
&lt;p>Пользовательские события и ошибки сохраняются двумя способами: как события RUM в исходном виде — со всеми переданными полями без потерь — и как элементы трейсов, где каждое поле события становится отдельным атрибутом для поиска и фильтрации.&lt;/p>
&lt;p>Отсюда следует, что доступно:&lt;/p>
&lt;ul>
&lt;li>разрезы по типу и названию действия, по экрану, версии приложения, операционной системе, географии — на дашбордах мобильных приложений;&lt;/li>
&lt;li>построение собственных дашбордов и выборок по любому переданному атрибуту через семантический слой платформы;&lt;/li>
&lt;li>поиск конкретных событий и ошибок с переходом к сессии пользователя и предшествующим действиям, см. &lt;a href="session-traces">Трейсы сессий&lt;/a>;&lt;/li>
&lt;li>воронки по последовательности пользовательских действий.&lt;/li>
&lt;/ul>
&lt;h3 id="обфусцированные-стектрейсы">Обфусцированные стектрейсы&lt;/h3>
&lt;p>Восстановление обфусцированных стектрейсов на стороне платформы не выполняется — загрузка mapping-файлов R8/ProGuard и файлов dSYM не предусмотрена. Стектрейс сохраняется в том виде, в каком его сформировало приложение.&lt;/p>
&lt;p>Практические варианты:&lt;/p>
&lt;ul>
&lt;li>отключить обфускацию для пакетов, ошибки в которых важно читать напрямую;&lt;/li>
&lt;li>восстанавливать стектрейсы своим mapping-файлом от соответствующей сборки вне платформы — для этого версия приложения фиксируется в каждом событии;&lt;/li>
&lt;li>передавать в атрибутах ошибки заранее подготовленное читаемое описание в дополнение к стектрейсу.&lt;/li>
&lt;/ul>
&lt;h2 id="сетевые-доступы">Сетевые доступы&lt;/h2>
&lt;p>Приложению для передачи данных достаточно доступа к адресу приёма ProtoOBP по HTTPS.&lt;/p>
&lt;p>Дополнительно платформенные библиотеки при запуске выполняют синхронизацию времени по NTP с публичным пулом серверов. В контурах без доступа к внешним NTP-серверам синхронизация не выполняется, и используются системные часы устройства; на передачу данных это не влияет. Адреса NTP-серверов заданы в библиотеках и не выносятся в конфигурацию приложения — при жёстких требованиях к исходящему трафику это учитывается на уровне сетевой политики.&lt;/p>
&lt;h2 id="проверка-подключения">Проверка подключения&lt;/h2>
&lt;ol>
&lt;li>Соберите и запустите приложение, пройдите по нескольким экранам, выполните сетевые запросы.&lt;/li>
&lt;li>Подождите 1–2 минуты: данные передаются пачками, а не по каждому событию.&lt;/li>
&lt;li>В интерфейсе платформы откройте раздел с мобильными приложениями. В списке появится приложение с названием, заданным в параметре &lt;code>service&lt;/code>.&lt;/li>
&lt;li>Перейдите на дашборд приложения. Заполняются запуски, просмотры экранов, сессии и пользователи, ошибки, сетевые запросы, разрезы по версиям приложения и операционным системам.&lt;/li>
&lt;/ol>
&lt;p>Проверку следует выполнить на обеих платформах: сборки для Android и iOS используют разные платформенные библиотеки, хотя настраиваются одинаково.&lt;/p>
&lt;h2 id="область-применения-инструкции">Область применения инструкции&lt;/h2>
&lt;p>Инструкция описывает передачу данных RUM: просмотры экранов, действия пользователя, сетевые запросы, ошибки и падения со стектрейсами, метрики отрисовки, а также пользовательские события и атрибуты.&lt;/p>
&lt;p>Передача логов приложения настраивается отдельно — обратитесь к команде Proto Observability за параметрами для вашего контура.&lt;/p>
&lt;p>Запись сессий (Session Replay) в этой схеме подключения не передаётся.&lt;/p>
&lt;h2 id="диагностика-неполадок">Диагностика неполадок&lt;/h2>
&lt;p>&lt;strong>Данные не появляются, в логах приложения нет ошибок отправки.&lt;/strong>
Проверьте, что в &lt;code>customEndpoint&lt;/code> указан полный адрес вместе с путём &lt;code>/api/v2/rum&lt;/code>. Если задан только адрес сервера, запросы уходят в корень сайта и до компонента приёма не доходят.&lt;/p>
&lt;p>&lt;strong>Данные приходят с Android, но не с iOS (или наоборот).&lt;/strong>
Настройка общая, но сборки разные. Проверьте, что на iOS выполнен &lt;code>pod install&lt;/code> после установки пакета, а на Android значение &lt;code>minSdkVersion&lt;/code> не ниже 23.&lt;/p>
&lt;p>&lt;strong>Ответ 403, тело &lt;code>Module not licensed&lt;/code>.&lt;/strong>
Лицензия платформы не включает модуль мониторинга цифрового опыта (DEM). Обратитесь к администратору платформы.&lt;/p>
&lt;p>&lt;strong>Ответ 402, тело &lt;code>License expired&lt;/code>.&lt;/strong>
Срок действия лицензии платформы истёк. Обратитесь к администратору платформы.&lt;/p>
&lt;p>&lt;strong>Ответ 415.&lt;/strong>
Запрос отправлен с типом содержимого, который компонент приёма не разбирает. Такое возможно при отправке через промежуточный прокси, изменяющий заголовки. Убедитесь, что прокси передаёт заголовки &lt;code>Content-Type&lt;/code> и &lt;code>Content-Encoding&lt;/code> без изменений.&lt;/p>
&lt;p>&lt;strong>Ответ 200, но данных в интерфейсе нет.&lt;/strong>
Приём RUM может быть выключен в конфигурации компонента приёма данных. Обратитесь к администратору платформы — для диагностики на стороне платформы включается подробное протоколирование принимаемых пакетов.&lt;/p>
&lt;p>&lt;strong>Приложение в списке называется не так, как ожидалось.&lt;/strong>
Название берётся из параметра &lt;code>service&lt;/code> конфигурации пакета.&lt;/p></description></item></channel></rss>