Мониторинг производительности веб-запросов для iOS
Мониторинг производительности веб-запросов
ЕдиныйАгент для iOS предоставляет комплексные возможности мониторинга веб-запросов:
- Автоматическая инструментация — автоматически фиксирует все веб-запросы, отправленные через URLSession.
- W3C Trace Context — активирует связь между фронтендом и бэкендом путем распространения заголовков контекста трассировки.
- Создание отчетов вручную — формирование отчетов о веб-запросах из пользовательских сетевых конфигураций.
- Обогащение событий — добавление пользовательских свойств к событиям веб-запросов.
Автоматизированная инструментация веб-запросов
ЕдиныйАгент для iOS автоматически отслеживает веб-запросы, выполняемые с использованием API URLSession от Apple, и сохраняет их в виде событий в Хранилище данных.
Каждое событие состоит из четко определенных полей типа «ключ-значение», как указано в Семантическом словаре для пользовательских событий.
Эти данные можно запрашивать напрямую в Хранилище данных с помощью DQL.
Кроме того, измеряются временные параметры, полученные с мобильного устройства.
Что фиксируется автоматически
Для каждого веб-запроса SDK фиксирует:
- URL запроса
- Метод HTTP (GET, POST, PUT, DELETE и т. д.)
- Код состояния ответа
- Размер запроса и ответа (отправлено/получено в байтах)
- Продолжительность запроса
- Ошибки (в случае неудачи запроса)
Собранные данные будут структурированы и представлены в соответствии с полями, указанными в request.*.
Поддерживаемые API
Автоматизированные измерительные приборы работают со следующими компонентами:
URLSession.dataTask(with:completionHandler:)URLSession.downloadTask(with:completionHandler:)URLSession.uploadTask(with:from:completionHandler:)- Варианты асинхронного выполнения с использованием
async/await(URLSession.data(from:)и т. д.) NSURLRequest,NSURLConnection,NSURLProtocol- Запросы
WKWebView - Удобные методы
NSData
Ограничения
Автоматизированные измерительные приборы имеют следующие ограничения:
- Протоколы, отличные от HTTP(S), не поддерживаются.
- Запросы стороннего фреймворка могут не поддерживаться инструментами мониторинга.
- Мы не рекомендуем использовать несколько инструментов мониторинга одновременно с включенной функцией отслеживания сбоев или инструментирования веб-запросов. Это может привести к проблемам совместимости, отображению неверной или некорректной информации, а также к потере данных мониторинга и сбоев. Тем не менее, если вы все же решите это сделать, проверьте совместимость этих инструментов с помощью ручного тестирования.
Чтобы использовать Ключ-АСТРОМ и Firebase одновременно, выполните одно из следующих действий.
- Полностью отключите мониторинг производительности Firebase.
- Отключите автоматическую проверку веб-запросов в ЕдиномАгенте для iOS.
- Следуйте только одному из описанных выше подходов; не выполняйте оба действия одновременно.
Для одновременного использования Ключ-АСТРОМ и mPaaS выполните одно из следующих действий.
- Отключите автоматическую проверку веб-запросов в ЕдиномАгенте для iOS.
- Не используйте фреймворк MPNebulaAdapter.
- Следуйте только одному из описанных выше подходов; не выполняйте оба действия одновременно.
Отключить автоматическую настройку измерительных приборов
Чтобы отключить автоматическую проверку веб-запросов, установите ключ конфигурации DTXInstrumentWebRequestTiming в значение false в файле Info.plist вашего приложения:
<key>DTXInstrumentWebRequestTiming</key> <false/>
Возможно, вам потребуется отключить автоматическую инструментацию в следующих случаях:
- Вам необходим полный контроль над тем, какие запросы будут зарегистрированы.
- Вы используете исключительно собственную реализацию сетевой инфраструктуры.
Какой тип измерительного оборудования использовать?
| Тип запроса | Тип измерительного прибора | DTXInstrumentWebRequestTiming |
|---|---|---|
| HTTP(S) | Вариант А: Авто | true |
| HTTP(S) | Вариант B: Ручной | false |
Нельзя комбинировать автоматическую и ручную инструментацию для одного и того же HTTP(S) запроса.
Контекст трассировки W3C для связи между фронтендом и бэкендом
SDK поддерживает добавление контекста трассировки W3C, который позволяет связывать мобильные запросы с серверными службами. Подробнее см. раздел «Связывание фронтенда и бэкенда с использованием контекста трассировки W3C».
Автоматическое распространение заголовка контекста трассировки
В большинстве случаев вам не нужно самостоятельно устанавливать заголовки контекста трассировки W3C. Когда включена автоматическая инструментация веб-запросов, ЕдиныйАгент проверяет каждый исходящий запрос и решает, следует ли генерировать, сохранять или оставлять заголовки контекста трассировки без изменений, основываясь на обнаруженных данных.
Отсутствуют заголовки (типичный случай)
Если запрос не содержит заголовков трассировки, ЕдиныйАгент генерирует новый действительный traceparent и добавляет соответствующую запись tracestate с контекстом, специфичным для Ключ-АСТРОМ.
Это позволяет установить корреляцию между мобильным запросом и трассировкой на стороне сервиса. См. раздел «Связь между фронтендом и бэкендом».
Существующий действительный traceparent заголовок
Если запрос уже содержит действительный идентификатор поставщика traceparent, ЕдиныйАгент сохраняет его и обновляет tracestate, добавляя информацию, специфичную для Ключ-АСТРОМ, без перезаписи существующих записей о поставщике.
Если общий размер данных tracestate станет слишком большим, ЕдиныйАгент может сократить количество записей, чтобы они оставались в пределах ограничений W3C. Данные Ключ-АСТРОМ сохраняются, когда это возможно.
Отключить автоматическое распространение контекста трассировки
Если вы не хотите, чтобы заголовки контекста трассировки W3C автоматически добавлялись к исходящим запросам, вы можете отключить эту функцию.
- Перейдите в раздел Ключевые показатели опыта > Обзор.
- Выберите Мобильные устройства, чтобы просмотреть все мобильные версии сайта.
- Выберите интерфейс, который хотите настроить.
- На вкладке Настройки выберите Связь между фронтендом и бэкендом.
- Отключите функцию Включить связь между фронтендом и бэкендом через контекст трассировки W3C.
Передача заголовков контекста трассировки вручную
Если вы используете собственный сетевой стек, вы можете самостоятельно передавать заголовки W3C Trace Context и при этом сопоставлять запрос с распределенными трассировками Ключ-АСТРОМ.
Используйте Astromkey.generateTraceContext(traceparent:tracestate:) (Swift) / generateTraceContext:tracestate: (Objective-C) для создания или обогащения контекста трассировки в соответствии с официальной спецификацией W3C Trace Context:
- Если значение
traceparentравноnil, ЕдиныйАгент генерирует новыйtraceparentи соответствующийtracestate(включая информацию, специфичную для поставщика Ключ-АСТРОМ). - Если
traceparentприсутствует и действителен, ЕдиныйАгент сохраняет его и дополняетtracestateинформацией, специфичной для поставщика Ключ-АСТРОМ (без перезаписи существующих записей о поставщике). - Если контекст трассировки создать не удаётся (например, из-за недопустимости
traceparentили запрета на захват/тегирование), API возвращает значениеnil, и изменять заголовки запроса не следует.
Затем вы можете повторно использовать полученные данные traceparent для сопоставления событий веб-запроса, зарегистрированных вручную.
Swift
import Astromkey
var request = URLRequest(url: URL(string: "https://api.example.com/data")!)
// Считываем существующие заголовки (если таковые имеются)
let existingTraceparent = request.value(forHTTPHeaderField: "traceparent")
let existingTracestate = request.value(forHTTPHeaderField: "tracestate")
// Генерация/обогащение контекста трассировки
var traceparentForReporting: String?
if let ctx = Astromkey.generateTraceContext(existingTraceparent, tracestate: existingTracestate) {
request.setValue(ctx.traceparent, forHTTPHeaderField: "traceparent")
request.setValue(ctx.tracestate, forHTTPHeaderField: "tracestate")
traceparentForReporting = ctx.traceparent
} else {
// Изменения не должны применяться, если контекст не может быть создан (например, недопустимый traceparent)
}
// ...здесь выполните свой HTTP-запрос...
let requestData = DTXHttpRequestEventData(url: request.url!.absoluteString, method: request.httpMethod ?? "GET")
.withDuration(duration)
.withStatusCode(statusCode)
if let traceparent = traceparentForReporting {
requestData.withTraceparentHeader(traceparent)
}
Astromkey.sendHttpRequestEvent(requestData)
Objective-C
@import Astromkey;
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://api.example.com/data"]];
// Считываем существующие заголовки (если таковые имеются)
NSString *existingTraceparent = [request valueForHTTPHeaderField:@"traceparent"];
NSString *existingTracestate = [request valueForHTTPHeaderField:@"tracestate"];
// Генерация/обогащение контекста трассировки
NSString *traceparentForReporting = nil;
DTXTraceContext *ctx = [Astromkey generateTraceContext:existingTraceparent tracestate:existingTracestate];
if (ctx) {
[request setValue:ctx.traceparent forHTTPHeaderField:@"traceparent"];
[request setValue:ctx.tracestate forHTTPHeaderField:@"tracestate"];
traceparentForReporting = ctx.traceparent;
} else {
// Изменения не должны применяться, если контекст не может быть создан (например, недопустимый traceparent)
}
// ...здесь выполните свой HTTP-запрос...
DTXHttpRequestEventData *requestData = [[[[DTXHttpRequestEventData alloc]
initWithURL:request.URL.absoluteString method:request.HTTPMethod]
withDuration:@(duration)]
withStatusCode:@(statusCode)];
if (traceparentForReporting) {
[requestData withTraceparentHeader:traceparentForReporting];
}
[Astromkey sendHttpRequestEvent:requestData];
Сообщайте о веб-запросах вручную
Для сетевых библиотек, не охваченных автоматической инструментацией, вы можете вручную сообщать о веб-запросах, используя DTXHttpRequestEventData.
Основное использование
Swift
import Astromkey
// Создание данных запроса с указанием URL-адреса и метода HTTP
let requestData = DTXHttpRequestEventData(url: "https://api.example.com/data", method: "GET")
.withDuration(250) // Длительность в миллисекундах
.withStatusCode(200) // Код состояния HTTP
.withBytesSent(128) // Отправлено байтов
.withBytesReceived(4096) // Получено байтов
// Отправка события веб-запроса
Astromkey.sendHttpRequestEvent(requestData)
Objective-C
@import Astromkey;
// Создание данных запроса с указанием URL-адреса и метода HTTP
DTXHttpRequestEventData *requestData = [[[[[[DTXHttpRequestEventData alloc]
initWithURL:@"https://api.example.com/data" method:@"GET"]
withDuration:@250] // Длительность в миллисекундах
withStatusCode:@200] // Код состояния HTTP
withBytesSent:@128] // Отправлено байтов
withBytesReceived:@4096]; // Получено байтов
// Отправка события веб-запроса
[Astromkey sendHttpRequestEvent:requestData];
Сообщить об ошибках
В случае неудачной попытки выполнения запроса, укажите информацию об ошибке:
Swift
let requestData = DTXHttpRequestEventData(url: "https://api.example.com/data", method: "POST")
.withDuration(1500)
.withError(error as NSError)
Astromkey.sendHttpRequestEvent(requestData)
Objective-C
DTXHttpRequestEventData *requestData = [[[[DTXHttpRequestEventData alloc]
initWithURL:@"https://api.example.com/data" method:@"POST"]
withDuration:@1500]
withError:error];
[Astromkey sendHttpRequestEvent:requestData];
Включить контекст трассировки
Для сопоставления запросов, сообщенных вручную, с распределенными трассировками, добавьте заголовок traceparent:
Совмещение ручной и автоматической передачи контекста трассировки для одного и того же запроса не поддерживается. Не устанавливайте заголовок traceparent или tracestate самостоятельно, пока активна автоматическая инструментация веб-запросов. Чтобы установить заголовки вручную, сначала отключите автоматическую передачу контекста трассировки.
Swift
// Сообщить о событии с помощью трассировки (traceparent)
let requestData = DTXHttpRequestEventData(url: url, method: "GET")
.withDuration(duration)
.withStatusCode(statusCode)
.withTraceparentHeader(traceparent)
Astromkey.sendHttpRequestEvent(requestData)
Objective-C
// Сообщить о событии с помощью трассировки (traceparent)
DTXHttpRequestEventData *requestData = [[[[[DTXHttpRequestEventData alloc]
initWithURL:url method:@"GET"]
withDuration:duration]
withStatusCode:statusCode]
withTraceparentHeader:traceparent];
[Astromkey sendHttpRequestEvent:requestData];
Добавить пользовательские свойства
Добавьте пользовательские свойства события для получения дополнительного контекста:
Swift
let requestData = DTXHttpRequestEventData(url: url, method: "POST")
.withDuration(300)
.withStatusCode(201)
.addEventProperty("event_properties.api_version", value: "v2")
.addEventProperty("event_properties.endpoint", value: "users")
Astromkey.sendHttpRequestEvent(requestData)
Objective-C
DTXHttpRequestEventData *requestData = [[[[[[DTXHttpRequestEventData alloc]
initWithURL:url method:@"POST"]
withDuration:@300]
withStatusCode:@201]
addEventProperty:@"event_properties.api_version" value:@"v2"]
addEventProperty:@"event_properties.endpoint" value:@"users"];
[Astromkey sendHttpRequestEvent:requestData];
Ключи пользовательских свойств должны иметь префикс event_properties. — свойства без этого префикса будут отброшены.
Обогащение событий (модификаторы)
Модификаторы событий позволяют обогащать события веб-запросов дополнительными данными перед их отправкой. Это полезно для добавления контекста из запроса/ответа, который не захватывается автоматически.
Добавить модификатор веб-запроса
Swift
let subscriber = Astromkey.addHttpEventModifier { event, context in
// Получение сведений о запросе из контекста
if let request = context?.request {
// Добавьте пользовательские заголовки или информацию запроса в качестве свойств
if let customHeader = request.value(forHTTPHeaderField: "X-Custom-Header") {
event.fields["event_properties.custom_header"] = customHeader
}
}
// Доступ к подробностям ответа
if let httpResponse = context?.response as? HTTPURLResponse {
if let serverTiming = httpResponse.value(forHTTPHeaderField: "Server-Timing") {
event.fields["event_properties.server_timing"] = serverTiming
}
}
// Возвращает событие изменения (или nil, чтобы его отбросить)
return event
}
Objective-C
DTXModifyEventSubscriber *subscriber = [Astromkey addHttpEventModifier:^DTXModifyableEvent *(DTXModifyableEvent *event, DTXHttpRequestEventContext *context) {
// Получение сведений о запросе из контекста
if (context.request) {
// Добавьте пользовательские заголовки или информацию запроса в качестве свойств
NSString *customHeader = [context.request valueForHTTPHeaderField:@"X-Custom-Header"];
if (customHeader) {
event.fields[@"event_properties.custom_header"] = customHeader;
}
}
// Доступ к подробностям ответа
if ([context.response isKindOfClass:[NSHTTPURLResponse class]]) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)context.response;
NSString *serverTiming = httpResponse.allHeaderFields[@"Server-Timing"];
if (serverTiming) {
event.fields[@"event_properties.server_timing"] = serverTiming;
}
}
// Возвращает событие изменения (или nil, чтобы его отбросить)
return event;
}];
Доступные свойства контекста
Предоставляет DTXHttpRequestEventContext доступ к:
| Свойство | Тип | Описание |
|---|---|---|
request |
URLRequest | Первоначальный запрос |
response |
URLResponse? | Ответ сервера (если имеется) |
responseBody |
Data? | Данные ответа (если получены) |
error |
NSError? | Сообщение об ошибке (если запрос не удался) |
Удалить модификатор
Когда модификатор больше не нужен, удалите его, используя ссылку на подписчика:
Swift
Astromkey.removeEventModifier(subscriber)
Objective-C
[Astromkey removeEventModifier:subscriber];
Фильтрация запросов
Верните значение nil из модификатора, чтобы предотвратить отправку события:
Swift
let subscriber = Astromkey.addHttpEventModifier { event, context in
// Не сообщать о запросах к точкам аналитики
if let url = context?.request.url?.absoluteString,
url.contains("analytics.example.com") {
return nil
}
return event
}
Objective-C
DTXModifyEventSubscriber *subscriber = [Astromkey addHttpEventModifier:^DTXModifyableEvent *(DTXModifyableEvent *event, DTXHttpRequestEventContext *context) {
// Не сообщать о запросах к точкам аналитики
NSString *url = context.request.URL.absoluteString;
if (url && [url containsString:@"analytics.example.com"]) {
return nil;
}
return event;
}];