Перейти к основному содержимому

Sampling Profiler: эффективное профилирование с Tracer SDK

Подключение зависимостей к проекту

В вашем <project>/<app-module>/build.gradle.

dependencies {
implementation "ru.ok.tracer:tracer-profiler-sampling:0.2.7"
}

Более подробное описание зависимостей на странице Быстрый старт.

Описание SamplingProfilerConfiguration

В вашем Application.kt.

class MyApplication : Application(), HasTracerConfiguration {
override val tracerConfiguration: List<TracerConfiguration>
get() = listOf(
SamplingProfilerConfiguration.build {
// ваши опции
},
)
}

Ниже представлены опции SamplingProfilerConfiguration.Builder.

  • setEnabled — включает/выключает профилирование. По умолчанию включён.

Устаревшие или опасные опции SamplingProfilerConfiguration.Builder.

  • setBufferSizeMb — смотрите описание android.os.Debug.startMethodTracingSampling;
  • setSamplingIntervalUs — смотрите описание android.os.Debug.startMethodTracingSampling. По умолчанию 5000.
  • setDurationMs — время работы профайлера в миллисекундах.
  • addCondition — добавляет Condition для начала профилирования.

Описание Condition.Deprecated.

Конструкция Condition используется для управления запуском и отправкой результатов профилирования. Ниже представлен пример использования.

Condition.appStart(10_000, 7_000)

Включить профайлер при старте приложения с вероятностью 100% и отправить результат его работы на сервер, если время запуска приложения превысило 7000 мс.

Создание собственного события.

val condition = Condition.build { // ваши опции }

Ниже представлены опции Condition.Builder.

  • setTag("my_tag") — тег, с которым результат будет загружен в Tracer.
  • setTagLimit(n) — максимальное количество отчетов в день для данного тега которое примет сервер.
  • setProbability(n) — вероятность(1/n) с которой будет запущен профайлер при наступлении события из startEvent.
  • setStartEvent("my_event") — при наступлении этого события с указанной выше вероятностью будет запущен профайлер.
  • setInterestingEvent("my_other_event") — необязательно. Если присутствует, то результат профилирования будет отправлен на бэкенд, только если данное событие встретилось за время работы профайлера.
  • setInterestingDuration(n) — если время между стартовым и интересующим событием превысит это число, результат профилирования будет отправлен на бэкенд.
к сведению

Если интересующее событие будет иметь свой счётчик, сравнение будет происходить с ним. К примеру, app_freeze имеет счетчик — время которое UI-поток «висел». Следовательно, если interestingEvent == "app_freeze" и interestingDuration == 700, то отправка произойдет, если во время работы профайлера случился фриз на 700+ мс.

Ручное профилирование

Также есть возможность размечать в коде начало и конец профилирования.

  • SamplingProfiler.start() — запускает профайлер. Принимает параметры:
    • context: ContextApp context приложения;
    • tag: String — тег, с которым результат будет загружен в трейсер;
    • duration: Long — время работы профайлера в миллисекундах.
  • SamplingProfiler.abort() — прекращает работу профайлера и очищает результат.
  • SamplingProfiler.commit() — прекращает работу профайлера и отправляет результат на бэкенд. Если на момент вызова профайлер ещё не закончил работу, то результирующий тег будет равен <tag>_<tagSuffix>.
  • tagSuffix: String — суффикс, который будет добавлен к тегу в случае досрочной остановки профайлера (необязательно).

См. пример ниже.

С вероятностью 1/100000 профайлер начнёт свою работу.

if (Random.nextInt(100 _ 0 0 0) == 0) {
SamplingProfiler.start(
context = appContext,
tag = "stream_request" ,
duration = 10 _ 0 0 0 ,
)
}
// ... Код. Например, загрузка ленты
SamplingProfiler.commit( "loaded" )

Описание «системных» событий

«Системные» события используются в классе Condition и ручном профилировании:

  • TracerEvents.EVENT_APP_START_BEGIN"app_start_begin": начало работы приложения.
  • TracerEvents.EVENT_APP_START_END"app_start_end": окончание работы метода Application.onCreate().
  • TracerEvents.EVENT_FIRST_ACTIVITY_CREATED"app_first_activity_created": создана первая активити.
  • TracerEvents.EVENT_ACTIVITY_CREATED"activity_created" — любая активити перешла в состояние created.
  • TracerEvents.EVENT_FREEZE"app_freeze" — UI поток завис на N мс. Если это событие используется как interesting event, тогда interesting duration будет сравниваться с N. К примеру, если N == 500, тогда результат профайлинга будет отправлен, если UI поток за время работы профайлера зависал на более чем 500 мс.
  • EVENT_ANR"app_anr": UI-поток завис и не продолжил свою работу на момент окончания профайлера. Прошло N мс с момента обнаружения зависания до окончания работы профайлера. Если это событие используется как interesting event, тогда interesting duration будет сравниваться с N. К примеру, если N == 5000, результат профайлинга будет отправлен, если UI-поток за время работы профайлера завис на более чем 5000 мс.

Добавление пользовательского события (см. ниже).

TracerEvents.addEvent(eventName, duration)
  • eventName — имя события. Используется в классе Condition в методах startEvent и interestingEvent.
  • duration — время ассоциированное с этим событием. Если задано, то interestingDuration будет вычисляться не как разница между startEvent и interestingEvent, а сравниваться с duration этого события.