<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>https://doc.ruscomtech.ru/index.php?action=history&amp;feed=atom&amp;title=%D0%9C%D0%BE%D0%BD%D0%B8%D1%82%D0%BE%D1%80%D0%B8%D0%BD%D0%B3_%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%B4%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D0%B2%D0%B5%D0%B1-%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D0%BE%D0%B2</id>
	<title>Мониторинг производительности веб-запросов - История изменений</title>
	<link rel="self" type="application/atom+xml" href="https://doc.ruscomtech.ru/index.php?action=history&amp;feed=atom&amp;title=%D0%9C%D0%BE%D0%BD%D0%B8%D1%82%D0%BE%D1%80%D0%B8%D0%BD%D0%B3_%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%B4%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D0%B2%D0%B5%D0%B1-%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D0%BE%D0%B2"/>
	<link rel="alternate" type="text/html" href="https://doc.ruscomtech.ru/index.php?title=%D0%9C%D0%BE%D0%BD%D0%B8%D1%82%D0%BE%D1%80%D0%B8%D0%BD%D0%B3_%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%B4%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D0%B2%D0%B5%D0%B1-%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D0%BE%D0%B2&amp;action=history"/>
	<updated>2026-09-16T14:05:19Z</updated>
	<subtitle>История изменений этой страницы в вики</subtitle>
	<generator>MediaWiki 1.43.9</generator>
	<entry>
		<id>https://doc.ruscomtech.ru/index.php?title=%D0%9C%D0%BE%D0%BD%D0%B8%D1%82%D0%BE%D1%80%D0%B8%D0%BD%D0%B3_%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%B4%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D0%B2%D0%B5%D0%B1-%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D0%BE%D0%B2&amp;diff=6584&amp;oldid=prev</id>
		<title>IKuznetsov: Новая страница: «= Мониторинг производительности веб-запросов =  ЕдиныйАгент для &#039;&#039;&#039;Android&#039;&#039;&#039; предоставляет комплексные возможности мониторинга веб-запросов.  * Автоматическая инструментация — автоматически фиксирует все веб-запросы, отправленные через &lt;code&gt;HttpUrlConnection&lt;/code&gt; и...»</title>
		<link rel="alternate" type="text/html" href="https://doc.ruscomtech.ru/index.php?title=%D0%9C%D0%BE%D0%BD%D0%B8%D1%82%D0%BE%D1%80%D0%B8%D0%BD%D0%B3_%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%B4%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D0%B2%D0%B5%D0%B1-%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D0%BE%D0%B2&amp;diff=6584&amp;oldid=prev"/>
		<updated>2026-08-19T16:43:41Z</updated>

		<summary type="html">&lt;p&gt;Новая страница: «= Мониторинг производительности веб-запросов =  ЕдиныйАгент для &amp;#039;&amp;#039;&amp;#039;Android&amp;#039;&amp;#039;&amp;#039; предоставляет комплексные возможности мониторинга веб-запросов.  * Автоматическая инструментация — автоматически фиксирует все веб-запросы, отправленные через &amp;lt;code&amp;gt;HttpUrlConnection&amp;lt;/code&amp;gt; и...»&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая страница&lt;/b&gt;&lt;/p&gt;&lt;div&gt;= Мониторинг производительности веб-запросов =&lt;br /&gt;
&lt;br /&gt;
ЕдиныйАгент для &amp;#039;&amp;#039;&amp;#039;Android&amp;#039;&amp;#039;&amp;#039; предоставляет комплексные возможности мониторинга веб-запросов.&lt;br /&gt;
&lt;br /&gt;
* Автоматическая инструментация — автоматически фиксирует все веб-запросы, отправленные через &amp;lt;code&amp;gt;HttpUrlConnection&amp;lt;/code&amp;gt; или &amp;lt;code&amp;gt;OkHttp&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;W3C Trace Context&amp;#039;&amp;#039;&amp;#039; — активирует связь между фронтендом и бэкендом путем распространения заголовков контекста трассировки.&lt;br /&gt;
* Создание отчетов вручную — формирование отчетов о веб-запросах из пользовательских сетевых конфигураций.&lt;br /&gt;
* Обогащение событий — добавление пользовательских свойств к событиям веб-запросов.&lt;br /&gt;
&lt;br /&gt;
== Автоматизированная инструментация веб-запросов ==&lt;br /&gt;
&lt;br /&gt;
ЕдиныйАгент для &amp;#039;&amp;#039;&amp;#039;Android&amp;#039;&amp;#039;&amp;#039; автоматически отслеживает веб-запросы, выполняемые с использованием встроенного API &amp;lt;code&amp;gt;HttpUrlConnection&amp;lt;/code&amp;gt; &amp;#039;&amp;#039;&amp;#039;Android&amp;#039;&amp;#039;&amp;#039;, и сохраняет их в виде событий в Хранилище данных. То же самое относится и к запросам, выполняемым с помощью широко используемой библиотеки &amp;lt;code&amp;gt;OkHttp&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Каждое событие состоит из четко определенных полей типа «ключ-значение», как указано в Семантическом словаре для пользовательских событий.&lt;br /&gt;
&lt;br /&gt;
Эти данные можно запрашивать напрямую в Хранилище данных с помощью &amp;#039;&amp;#039;&amp;#039;DQL&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
=== Что фиксируется автоматически ===&lt;br /&gt;
&lt;br /&gt;
Подробный обзор сообщаемых данных и их структуры можно найти в Семантическом словаре. Следующий список содержит обзор данных, которые автоматически отслеживаются ЕдинымАгентом:&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;URL&amp;#039;&amp;#039;&amp;#039; запроса.&lt;br /&gt;
* Метод &amp;#039;&amp;#039;&amp;#039;HTTP&amp;#039;&amp;#039;&amp;#039; (&amp;#039;&amp;#039;&amp;#039;GET&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;POST&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;PUT&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;DELETE&amp;#039;&amp;#039;&amp;#039; и т. д.).&lt;br /&gt;
* Код состояния ответа.&lt;br /&gt;
* Продолжительность запроса.&lt;br /&gt;
* Исключение (в случае неудачи запроса).&lt;br /&gt;
&lt;br /&gt;
=== Поддерживаемые HTTP-фреймворки ===&lt;br /&gt;
&lt;br /&gt;
Автоматизированные измерительные приборы работают со следующими системами:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;HttpURLConnection&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;OkHttp&amp;lt;/code&amp;gt;: только версии 3, 4 и 5.&lt;br /&gt;
&lt;br /&gt;
Если ваша библиотека для обработки веб-запросов основана на одном из поддерживаемых фреймворков, внутренние классы библиотеки автоматически инструментируются. Например, &amp;#039;&amp;#039;&amp;#039;Retrofit&amp;#039;&amp;#039;&amp;#039; версии 2 основан на &amp;#039;&amp;#039;&amp;#039;OkHttp&amp;#039;&amp;#039;&amp;#039;, поэтому все веб-запросы &amp;#039;&amp;#039;&amp;#039;Retrofit&amp;#039;&amp;#039;&amp;#039; автоматически инструментируются.&lt;br /&gt;
&lt;br /&gt;
=== Ограничения ===&lt;br /&gt;
&lt;br /&gt;
* Протоколы, отличные от &amp;#039;&amp;#039;&amp;#039;HTTP&amp;#039;&amp;#039;&amp;#039;, не поддерживаются.&lt;br /&gt;
* Запросы от неподдерживаемых фреймворков необходимо обрабатывать вручную.&lt;br /&gt;
* Не рекомендуется использовать несколько инструментов мониторинга одновременно с включенной функцией инструментирования веб-запросов. Это может привести к проблемам совместимости, некорректным или недействительным отчетам о данных и потере информации мониторинга. Если вы все же решите это сделать, тщательно протестируйте инструменты, чтобы убедиться в их корректной совместной работе.&lt;br /&gt;
&lt;br /&gt;
=== Отключить автоматическую настройку измерительных приборов ===&lt;br /&gt;
&lt;br /&gt;
Чтобы отключить автоматическую инструментацию веб-запросов, установите флаг &amp;lt;code&amp;gt;webRequests.enabled&amp;lt;/code&amp;gt; в значение &amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt; в блоке &amp;lt;code&amp;gt;astromkey&amp;lt;/code&amp;gt; файла &amp;lt;code&amp;gt;configurations&amp;lt;/code&amp;gt; вашего приложения &amp;lt;code&amp;gt;build.gradle&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Groovy&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
astromkey {&lt;br /&gt;
    configurations {&lt;br /&gt;
        sampleConfig {&lt;br /&gt;
            webRequests.enabled false&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Kotlin&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
configure&amp;lt;com.astromkey.tools.android.dsl.AstromkeyExtension&amp;gt; {&lt;br /&gt;
    configurations {&lt;br /&gt;
        create(&amp;quot;sampleConfig&amp;quot;) {&lt;br /&gt;
            webRequests.enabled(false)&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Фильтрация веб-запросов по URL ===&lt;br /&gt;
&lt;br /&gt;
Используйте свойство &amp;lt;code&amp;gt;urlFilters&amp;lt;/code&amp;gt; внутри блока &amp;lt;code&amp;gt;webRequests&amp;lt;/code&amp;gt;, чтобы предотвратить автоматическую инструментацию запросов, &amp;#039;&amp;#039;&amp;#039;URL&amp;#039;&amp;#039;&amp;#039;-адреса которых соответствуют одному или нескольким шаблонам регулярных выражений. Любой запрос, соответствующий хотя бы одному шаблону, исключается из автоматической инструментации и не будет отслеживаться.&lt;br /&gt;
&lt;br /&gt;
Значение по умолчанию — пустой список, то есть по умолчанию никакие &amp;#039;&amp;#039;&amp;#039;URL&amp;#039;&amp;#039;&amp;#039;-адреса не отфильтровываются.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Groovy&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
astromkey {&lt;br /&gt;
    configurations {&lt;br /&gt;
        sampleConfig {&lt;br /&gt;
            webRequests {&lt;br /&gt;
                urlFilters &amp;quot;example.com&amp;quot;, &amp;quot;^http://&amp;quot;, &amp;quot;\.test\.&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Kotlin&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
configure&amp;lt;com.astromkey.tools.android.dsl.AstromkeyExtension&amp;gt; {&lt;br /&gt;
    configurations {&lt;br /&gt;
        create(&amp;quot;sampleConfig&amp;quot;) {&lt;br /&gt;
            webRequests {&lt;br /&gt;
                urlFilters(&amp;quot;example.com&amp;quot;, &amp;quot;^http://&amp;quot;, &amp;quot;\.test\.&amp;quot;)&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Каждый шаблон представляет собой регулярное выражение, сопоставляемое со всем &amp;#039;&amp;#039;&amp;#039;URL&amp;#039;&amp;#039;&amp;#039;-адресом.&lt;br /&gt;
&lt;br /&gt;
== Контекст трассировки W3C для связи между фронтендом и бэкендом ==&lt;br /&gt;
&lt;br /&gt;
SDK поддерживает добавление контекста трассировки &amp;#039;&amp;#039;&amp;#039;W3C&amp;#039;&amp;#039;&amp;#039;, который позволяет связывать мобильные запросы с серверными службами. Подробнее см. раздел «Связывание фронтенда и бэкенда с использованием контекста трассировки W3C».&lt;br /&gt;
&lt;br /&gt;
=== Автоматическое распространение заголовка контекста трассировки ===&lt;br /&gt;
&lt;br /&gt;
В большинстве случаев вам не нужно самостоятельно устанавливать заголовки контекста трассировки &amp;#039;&amp;#039;&amp;#039;W3C&amp;#039;&amp;#039;&amp;#039;. Когда активна автоматическая инструментация веб-запросов, ЕдиныйАгент проверяет каждый исходящий запрос и решает, следует ли генерировать, сохранять или оставлять заголовки контекста трассировки без изменений, основываясь на обнаруженных данных.&lt;br /&gt;
&lt;br /&gt;
==== Отсутствуют заголовки (типичный случай) ====&lt;br /&gt;
&lt;br /&gt;
Если запрос не содержит заголовков трассировки, ЕдиныйАгент генерирует новый действительный запрос &amp;lt;code&amp;gt;traceparent&amp;lt;/code&amp;gt; и добавляет соответствующую запись &amp;lt;code&amp;gt;tracestate&amp;lt;/code&amp;gt; с контекстом, специфичным для Ключ-АСТРОМ.&lt;br /&gt;
&lt;br /&gt;
Это позволяет установить корреляцию между мобильным запросом и трассировкой на стороне сервиса. См. раздел «Связь между фронтендом и бэкендом».&lt;br /&gt;
&lt;br /&gt;
==== Существующий действительный &amp;lt;code&amp;gt;traceparent&amp;lt;/code&amp;gt; заголовок ====&lt;br /&gt;
&lt;br /&gt;
Если запрос уже содержит действительный идентификатор поставщика &amp;lt;code&amp;gt;traceparent&amp;lt;/code&amp;gt;, ЕдиныйАгент сохраняет его и обновляет &amp;lt;code&amp;gt;tracestate&amp;lt;/code&amp;gt;, добавляя информацию, специфичную для Ключ-АСТРОМ, без перезаписи существующих записей о поставщике.&lt;br /&gt;
&lt;br /&gt;
Если общий размер данных &amp;lt;code&amp;gt;tracestate&amp;lt;/code&amp;gt; станет слишком большим, ЕдиныйАгент может сократить количество записей, чтобы они оставались в пределах ограничений &amp;#039;&amp;#039;&amp;#039;W3C&amp;#039;&amp;#039;&amp;#039;. Данные Ключ-АСТРОМ сохраняются, когда это возможно.&lt;br /&gt;
&lt;br /&gt;
=== Отключить автоматическое распространение контекста трассировки ===&lt;br /&gt;
&lt;br /&gt;
Если вы не хотите, чтобы заголовки контекста трассировки &amp;#039;&amp;#039;&amp;#039;W3C&amp;#039;&amp;#039;&amp;#039; автоматически добавлялись к исходящим запросам, вы можете отключить эту функцию.&lt;br /&gt;
&lt;br /&gt;
# Перейдите в раздел &amp;#039;&amp;#039;&amp;#039;Ключевые показатели опыта&amp;#039;&amp;#039;&amp;#039; &amp;gt; &amp;#039;&amp;#039;&amp;#039;Обзор&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
# Выберите &amp;#039;&amp;#039;&amp;#039;Мобильные устройства&amp;#039;&amp;#039;&amp;#039;, чтобы просмотреть все мобильные версии сайта.&lt;br /&gt;
# Выберите интерфейс, который хотите настроить.&lt;br /&gt;
# На вкладке &amp;#039;&amp;#039;&amp;#039;Настройки&amp;#039;&amp;#039;&amp;#039; выберите &amp;#039;&amp;#039;&amp;#039;Связь между фронтендом и бэкендом&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
# Отключите функцию &amp;#039;&amp;#039;&amp;#039;Включить связь между фронтендом и бэкендом через контекст трассировки W3C&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
=== Передача заголовков контекста трассировки вручную ===&lt;br /&gt;
&lt;br /&gt;
Если вы используете собственный сетевой стек, вы можете самостоятельно передавать заголовки &amp;#039;&amp;#039;&amp;#039;W3C Trace Context&amp;#039;&amp;#039;&amp;#039; и при этом сопоставлять запрос с распределенными трассировками Ключ-АСТРОМ.&lt;br /&gt;
&lt;br /&gt;
Используйте &amp;lt;code&amp;gt;Astromkey.generateTraceContext(traceparent, tracestate)&amp;lt;/code&amp;gt; для создания или обогащения контекста трассировки в соответствии с официальной спецификацией &amp;#039;&amp;#039;&amp;#039;W3C Trace Context&amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
* Если значение &amp;lt;code&amp;gt;traceparent&amp;lt;/code&amp;gt; равно &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt;, ЕдиныйАгент генерирует новый &amp;lt;code&amp;gt;traceparent&amp;lt;/code&amp;gt; и соответствующий &amp;lt;code&amp;gt;tracestate&amp;lt;/code&amp;gt; (включая информацию, специфичную для поставщика Ключ-АСТРОМ).&lt;br /&gt;
* Если &amp;lt;code&amp;gt;traceparent&amp;lt;/code&amp;gt; присутствует и действителен, ЕдиныйАгент сохраняет его и дополняет &amp;lt;code&amp;gt;tracestate&amp;lt;/code&amp;gt; информацией, специфичной для поставщика Ключ-АСТРОМ (без перезаписи существующих записей о поставщике).&lt;br /&gt;
* Если контекст трассировки создать не удаётся (например, из-за недопустимости &amp;lt;code&amp;gt;traceparent&amp;lt;/code&amp;gt; или запрета на захват/тегирование), API возвращает значение &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt;, и изменять заголовки запроса не следует.&lt;br /&gt;
&lt;br /&gt;
Затем вы можете повторно использовать полученные данные &amp;lt;code&amp;gt;traceparent&amp;lt;/code&amp;gt; для сопоставления событий веб-запроса, зарегистрированных вручную.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Kotlin&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
val request = Request.Builder()&lt;br /&gt;
    .url(&amp;quot;https://api.example.com/data&amp;quot;)&lt;br /&gt;
    .build()&lt;br /&gt;
&lt;br /&gt;
// Считываем существующие заголовки (если таковые имеются)&lt;br /&gt;
val existingTraceparent = request.header(&amp;quot;traceparent&amp;quot;)&lt;br /&gt;
val existingTracestate = request.header(&amp;quot;tracestate&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
// Генерация/обогащение контекста трассировки&lt;br /&gt;
val traceContext = Astromkey.generateTraceContext(existingTraceparent, existingTracestate)&lt;br /&gt;
val traceparentForReporting: String? = traceContext?.traceparent&lt;br /&gt;
&lt;br /&gt;
if (traceContext != null) {&lt;br /&gt;
    request = request.newBuilder()&lt;br /&gt;
        .header(&amp;quot;traceparent&amp;quot;, traceContext.traceparent)&lt;br /&gt;
        .header(&amp;quot;tracestate&amp;quot;, traceContext.tracestate)&lt;br /&gt;
        .build()&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ...здесь выполните свой HTTP-запрос...&lt;br /&gt;
val requestData = HttpRequestEventData(request.url.toString(), request.method)&lt;br /&gt;
    .withDuration(duration)&lt;br /&gt;
    .withStatusCode(statusCode)&lt;br /&gt;
&lt;br /&gt;
if (traceparentForReporting != null) {&lt;br /&gt;
    requestData.withTraceparentHeader(traceparentForReporting)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Astromkey.sendHttpRequestEvent(requestData)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Java&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Request request = new Request.Builder()&lt;br /&gt;
    .url(&amp;quot;https://api.example.com/data&amp;quot;)&lt;br /&gt;
    .build();&lt;br /&gt;
&lt;br /&gt;
// Считываем существующие заголовки (если таковые имеются)&lt;br /&gt;
String existingTraceparent = request.header(&amp;quot;traceparent&amp;quot;);&lt;br /&gt;
String existingTracestate = request.header(&amp;quot;tracestate&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
// Генерация/обогащение контекста трассировки&lt;br /&gt;
TraceContext traceContext = Astromkey.generateTraceContext(existingTraceparent, existingTracestate);&lt;br /&gt;
String traceparentForReporting = traceContext != null ? traceContext.getTraceparent() : null;&lt;br /&gt;
if (traceContext != null) {&lt;br /&gt;
    request = request.newBuilder()&lt;br /&gt;
        .header(&amp;quot;traceparent&amp;quot;, traceContext.getTraceparent())&lt;br /&gt;
        .header(&amp;quot;tracestate&amp;quot;, traceContext.getTracestate())&lt;br /&gt;
        .build();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ...здесь выполните свой HTTP-запрос...&lt;br /&gt;
HttpRequestEventData requestData = new HttpRequestEventData(request.url().toString(), request.method())&lt;br /&gt;
        .withDuration(duration)&lt;br /&gt;
        .withStatusCode(statusCode);&lt;br /&gt;
&lt;br /&gt;
if (traceparentForReporting != null) {&lt;br /&gt;
    requestData.withTraceparentHeader(traceparentForReporting);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Astromkey.sendHttpRequestEvent(requestData);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Сообщайте о веб-запросах вручную ==&lt;br /&gt;
&lt;br /&gt;
Для сетевых библиотек, не охваченных автоматической инструментацией, вы можете вручную сообщать о веб-запросах, используя &amp;lt;code&amp;gt;HttpRequestEventData&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Основное использование ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Kotlin&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Создание данных запроса с указанием URL-адреса и метода HTTP&lt;br /&gt;
val requestData = HttpRequestEventData(&amp;quot;https://api.example.com/data&amp;quot;, &amp;quot;GET&amp;quot;)&lt;br /&gt;
    .withDuration(250) // Длительность в миллисекундах&lt;br /&gt;
    .withStatusCode(200) // Код состояния HTTP&lt;br /&gt;
    .withBytesSent(128) // Отправлено байтов&lt;br /&gt;
    .withBytesReceived(4096) // Получено байтов&lt;br /&gt;
&lt;br /&gt;
// Отправка события веб-запроса&lt;br /&gt;
Astromkey.sendHttpRequestEvent(requestData)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Java&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Создание данных запроса с указанием URL-адреса и метода HTTP&lt;br /&gt;
HttpRequestEventData requestData = new HttpRequestEventData(&amp;quot;https://api.example.com/data&amp;quot;, &amp;quot;GET&amp;quot;)&lt;br /&gt;
    .withDuration(250) // Длительность в миллисекундах&lt;br /&gt;
    .withStatusCode(200) // Код состояния HTTP&lt;br /&gt;
    .withBytesSent(128) // Отправлено байтов&lt;br /&gt;
    .withBytesReceived(4096); // Получено байтов&lt;br /&gt;
&lt;br /&gt;
// Отправка события веб-запроса&lt;br /&gt;
Astromkey.sendHttpRequestEvent(requestData);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Неудачный запрос ===&lt;br /&gt;
&lt;br /&gt;
В случае неудачной попытки выполнения запроса, укажите информацию об ошибке:&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Kotlin&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
val requestData = HttpRequestEventData(&amp;quot;https://api.example.com/data&amp;quot;, &amp;quot;POST&amp;quot;)&lt;br /&gt;
    .withDuration(1500)&lt;br /&gt;
    .withThrowable(exception)&lt;br /&gt;
&lt;br /&gt;
Astromkey.sendHttpRequestEvent(requestData)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Java&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
HttpRequestEventData requestData = new HttpRequestEventData(&amp;quot;https://api.example.com/data&amp;quot;, &amp;quot;POST&amp;quot;)&lt;br /&gt;
    .withDuration(1500)&lt;br /&gt;
    .withThrowable(exception);&lt;br /&gt;
&lt;br /&gt;
Astromkey.sendHttpRequestEvent(requestData);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Добавить пользовательские свойства ===&lt;br /&gt;
&lt;br /&gt;
Добавьте пользовательские свойства события для получения дополнительного контекста:&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Kotlin&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
val requestData = HttpRequestEventData(url, &amp;quot;POST&amp;quot;)&lt;br /&gt;
    .withDuration(300)&lt;br /&gt;
    .withStatusCode(201)&lt;br /&gt;
    .addEventProperty(&amp;quot;event_properties.api_version&amp;quot;, &amp;quot;v2&amp;quot;)&lt;br /&gt;
    .addEventProperty(&amp;quot;event_properties.endpoint&amp;quot;, &amp;quot;users&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Astromkey.sendHttpRequestEvent(requestData)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Java&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
HttpRequestEventData requestData = new HttpRequestEventData(url, &amp;quot;POST&amp;quot;)&lt;br /&gt;
    .withDuration(300)&lt;br /&gt;
    .withStatusCode(201)&lt;br /&gt;
    .addEventProperty(&amp;quot;event_properties.api_version&amp;quot;, &amp;quot;v2&amp;quot;)&lt;br /&gt;
    .addEventProperty(&amp;quot;event_properties.endpoint&amp;quot;, &amp;quot;users&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
Astromkey.sendHttpRequestEvent(requestData);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ключи пользовательских свойств должны иметь префикс &amp;lt;code&amp;gt;event_properties.&amp;lt;/code&amp;gt; — свойства без этого префикса будут отброшены.&lt;br /&gt;
&lt;br /&gt;
== Обогащение событий (модификаторы) ==&lt;br /&gt;
&lt;br /&gt;
Модификаторы событий позволяют обогащать события веб-запросов дополнительными данными перед их отправкой. Это полезно для добавления контекста из запроса или ответа, который не захватывается автоматически. ЕдиныйАгент для &amp;#039;&amp;#039;&amp;#039;Android&amp;#039;&amp;#039;&amp;#039; в настоящее время предоставляет эту функцию только для запросов, выполняемых с помощью фреймворка &amp;#039;&amp;#039;&amp;#039;OkHttp&amp;#039;&amp;#039;&amp;#039;. Кроме того, вы также можете добавить другие свойства события через &amp;lt;code&amp;gt;EventModifier&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
При одновременном использовании обоих подходов сначала выполняется первый шаг, &amp;lt;code&amp;gt;OkHttpEventModifier&amp;lt;/code&amp;gt;, а затем второй &amp;lt;code&amp;gt;EventModifier&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Добавить модификатор веб-запроса ===&lt;br /&gt;
&lt;br /&gt;
Чтобы добавить модификатор веб-запроса, реализуйте интерфейс &amp;lt;code&amp;gt;OkHttpEventModifier&amp;lt;/code&amp;gt; и передайте его методу &amp;lt;code&amp;gt;Astromkey.addHttpEventModifier&amp;lt;/code&amp;gt;. Модификатор может получить доступ к объектам запроса и ответа для извлечения дополнительных данных и добавления их к событию. В случае исключения модификатор может получить доступ к объектам запроса и исключения для извлечения дополнительных данных и добавления их к событию.&lt;br /&gt;
&lt;br /&gt;
Из-за особенностей обработки тела ответа &amp;#039;&amp;#039;&amp;#039;OkHttp&amp;#039;&amp;#039;&amp;#039;, вам необходимо использовать &amp;lt;code&amp;gt;peekBody()&amp;lt;/code&amp;gt; вместо &amp;lt;code&amp;gt;body()&amp;lt;/code&amp;gt;, чтобы избежать потребления потока ответа. Таким образом, тело ответа останется доступным для последующего использования в вашей обычной системе обработки ответов.&lt;br /&gt;
&lt;br /&gt;
Если вы используете &amp;lt;code&amp;gt;body()&amp;lt;/code&amp;gt; модификатор для доступа к телу ответа, при последующей попытке повторного его обработки вы получите исключение.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Kotlin&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
val modifier: OkHttpEventModifier = object : OkHttpEventModifier {&lt;br /&gt;
    override fun modifyEvent(request: Request, response: Response): JSONObject {&lt;br /&gt;
        val event = JSONObject()&lt;br /&gt;
&lt;br /&gt;
        // Доступ к подробностям ответа&lt;br /&gt;
        val serverTiming = response.header(&amp;quot;Server-Timing&amp;quot;)&lt;br /&gt;
        if (serverTiming != null) {&lt;br /&gt;
            event.put(&amp;quot;event_properties.server_timing&amp;quot;, serverTiming)&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Просматривайте только тело ответа, не обрабатывайте его.&lt;br /&gt;
        val body = response.peekBody(1000)&lt;br /&gt;
        event.put(&amp;quot;event_properties.body&amp;quot;, body.toString())&lt;br /&gt;
&lt;br /&gt;
        return event&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    override fun modifyEvent(request: Request, throwable: Throwable): JSONObject {&lt;br /&gt;
        val event = JSONObject()&lt;br /&gt;
&lt;br /&gt;
        // Добавьте пользовательские заголовки или информацию запроса в качестве свойств&lt;br /&gt;
        val customHeader = request.header(&amp;quot;X-Custom-Header&amp;quot;)&lt;br /&gt;
        if (customHeader != null) {&lt;br /&gt;
            event.put(&amp;quot;event_properties.custom_header&amp;quot;, customHeader)&lt;br /&gt;
        }&lt;br /&gt;
        return event&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Astromkey.addHttpEventModifier(modifier)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Java&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
OkHttpEventModifier modifier = new OkHttpEventModifier() {&lt;br /&gt;
    @Override&lt;br /&gt;
    public JSONObject modifyEvent(Request request, Response response) {&lt;br /&gt;
        JSONObject event = new JSONObject();&lt;br /&gt;
&lt;br /&gt;
        // Доступ к подробностям ответа&lt;br /&gt;
        String serverTiming = response.header(&amp;quot;Server-Timing&amp;quot;);&lt;br /&gt;
        if (serverTiming != null) {&lt;br /&gt;
            event.put(&amp;quot;event_properties.server_timing&amp;quot;, serverTiming);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Просматривайте только тело ответа, не обрабатывайте его.&lt;br /&gt;
        ResponseBody body = response.peekBody(1000);&lt;br /&gt;
        event.put(&amp;quot;event_properties.body&amp;quot;, body.toString());&lt;br /&gt;
&lt;br /&gt;
        return event;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    @Override&lt;br /&gt;
    public JSONObject modifyEvent(Request request, Throwable throwable) {&lt;br /&gt;
        JSONObject event = new JSONObject();&lt;br /&gt;
&lt;br /&gt;
        // Добавьте пользовательские заголовки или информацию запроса в качестве свойств&lt;br /&gt;
        String customHeader = request.header(&amp;quot;X-Custom-Header&amp;quot;);&lt;br /&gt;
        if (customHeader != null) {&lt;br /&gt;
            event.put(&amp;quot;event_properties.custom_header&amp;quot;, customHeader);&lt;br /&gt;
        }&lt;br /&gt;
        return event;&lt;br /&gt;
    }&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
Astromkey.addHttpEventModifier(modifier);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Доступные свойства контекста ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;OkHttpEventModifier&amp;lt;/code&amp;gt; предоставляет методы обратного вызова для двух сценариев:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;modifyEvent(Request request, Response response)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;modifyEvent(Request request, Throwable throwable)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Первый метод вызывается после завершения запроса и получения ответа. Обратите внимание, что ответ может быть неуспешным, например, если сервер возвращает код состояния 4xx или 5xx.&lt;br /&gt;
&lt;br /&gt;
Второй метод вызывается в случае, если запрос завершился с исключением.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Метод обратного вызова !! Параметр !! Тип !! Описание&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;modifyEvent(request, response)&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;request&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;okhttp3.Request&amp;lt;/code&amp;gt; || Исходный объект запроса &amp;#039;&amp;#039;&amp;#039;OkHttp&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|-&lt;br /&gt;
| || &amp;lt;code&amp;gt;response&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;okhttp3.Response&amp;lt;/code&amp;gt; || Объект ответа &amp;#039;&amp;#039;&amp;#039;OkHttp&amp;#039;&amp;#039;&amp;#039; (используйте &amp;lt;code&amp;gt;peekBody()&amp;lt;/code&amp;gt; для чтения тела ответа)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;modifyEvent(request, throwable)&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;request&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;okhttp3.Request&amp;lt;/code&amp;gt; || Исходный объект запроса &amp;#039;&amp;#039;&amp;#039;OkHttp&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|-&lt;br /&gt;
| || &amp;lt;code&amp;gt;throwable&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;Throwable&amp;lt;/code&amp;gt; || Исключение, которое привело к сбою запроса.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Удалить модификатор ===&lt;br /&gt;
&lt;br /&gt;
Когда модификатор больше не нужен, удалите его, используя ссылку на модификатор:&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Kotlin&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Astromkey.removeEventModifier(modifier)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Java&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Astromkey.removeEventModifier(modifier);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Фильтрация запросов ===&lt;br /&gt;
&lt;br /&gt;
Верните значение &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt; из модификатора, чтобы предотвратить отправку события:&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Kotlin&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
val filterModifier: OkHttpEventModifier = object : OkHttpEventModifier {&lt;br /&gt;
    override fun modifyEvent(request: Request, response: Response?): JSONObject? {&lt;br /&gt;
        if (request.url.toString().contains(&amp;quot;analytics.example.com&amp;quot;)) {&lt;br /&gt;
            return null // вернуть null для события drop&lt;br /&gt;
        } else {&lt;br /&gt;
            return JSONObject()&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    override fun modifyEvent(request: Request?, throwable: Throwable?): JSONObject? {&lt;br /&gt;
        if (throwable is IOException) {&lt;br /&gt;
            val event = JSONObject()&lt;br /&gt;
            // Информация о выбросах добавляется автоматически&lt;br /&gt;
            return event&lt;br /&gt;
        } else {&lt;br /&gt;
            // Возвращает null, чтобы отменить событие&lt;br /&gt;
            return null&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Astromkey.addHttpEventModifier(filterModifier)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Java&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
OkHttpEventModifier filterModifier = new OkHttpEventModifier() {&lt;br /&gt;
    @Override&lt;br /&gt;
    public JSONObject modifyEvent(Request request, Response response) {&lt;br /&gt;
        if (request.url().toString().contains(&amp;quot;analytics.example.com&amp;quot;)) {&lt;br /&gt;
            return null; // вернуть null для события drop&lt;br /&gt;
        } else {&lt;br /&gt;
            return new JSONObject();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    @Override&lt;br /&gt;
    public JSONObject modifyEvent(Request request, Throwable throwable) {&lt;br /&gt;
        if (throwable instanceof IOException) {&lt;br /&gt;
            JSONObject event = new JSONObject();&lt;br /&gt;
            // Информация о выбросах добавляется автоматически&lt;br /&gt;
            return event;&lt;br /&gt;
        } else {&lt;br /&gt;
            // Возвращает null, чтобы отменить событие&lt;br /&gt;
            return null;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
Astromkey.addHttpEventModifier(filterModifier);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>IKuznetsov</name></author>
	</entry>
</feed>