Мониторинг производительности ваших приложений WebRTC может значительно улучшить ваш пользовательский опыт

Мониторинг производительности ваших приложений WebRTC может значительно улучшить ваш пользовательский опыт

17 февраля 2023 г.

Последнее, чего хочет компания, — это прослыть ненадежным и малоэффективным сервисом, особенно если есть аналогичные решения, которые можно найти всего в нескольких кликах. Поэтому необходимо знать производительность приложения WebRTC или любого другого программного решения, чтобы избежать проблем в будущем. Решение может быть разработано опытными людьми и протестировано перед выпуском, но даже в этом случае снижение производительности никогда не произойдет. Своевременное обнаружение проблем и принятие соответствующих мер может значительно улучшить взаимодействие с пользователями.

Представьте, что ваше приложение для видеовызовов имеет проблемы при потере пакетов. происходит. Потеря пакетов может привести к прерывистому звуку, зависанию видео или отсутствию видеокадров, из-за чего пользователям будет сложно понять, о чем идет речь, или увидеть, что происходит во время вызова. Высокая потеря пакетов также может затруднить установление и поддержание соединения приложением, что приводит к сброшенным звонкам или видеочатам. Если вы и ваша команда не сталкивались с потерей пакетов во время разработки приложения, есть один способ узнать о проблеме — разочарованный клиент может сообщить вам о своем неприятном опыте. Конечно, было бы намного лучше узнать о проблеме и устранить ее до того, как с ней столкнутся пользователи.

Вот почему мониторинг является такой полезной практикой: регулярное наблюдение за производительностью и поведением продукта с течением времени позволяет быстро реагировать на любые возникающие проблемы и поддерживать надежный и высокопроизводительный сервис. Это не только улучшает взаимодействие с пользователем, повышая удовлетворенность и лояльность клиентов, но и дает вашему бизнесу конкурентное преимущество на рынке.

Преимущества регулярного мониторинга приложений:

* Получение уведомлений о проблемах заранее. Настроив уведомления о мониторинге и сбоях тестирования, вы будете получать уведомления о проблемах в режиме реального времени и сможете своевременно принять меры, прежде чем у пользователей возникнут проблемы. * Мониторинг предоставляет подробные отчеты, которые могут помочь вам определить основную причину сбоев и определить области вашего приложения, которые нуждаются в улучшении. * Экономит много времени. Мониторинг — это автоматизированный процесс, а это означает, что вы можете создать решение один раз и просто позволить ему работать практически без обслуживания. * Уверенность в том, что ваше решение работает нормально. Когда у вас есть мониторинг, вы можете быть уверены, что ваше приложение регулярно проверяется и работает нормально, если в последнее время вы не получали никаких уведомлений. * Возможность сравнивать производительность с течением времени. Когда ваша система мониторинга регулярно запускает одни и те же тесты и выполняет измерения, вы можете позже агрегировать данные и посмотреть, как производительность менялась с течением времени.

Как мониторинг приложений WebRTC работает с Loadero

Loadero – это инструмент для тестирования нагрузки и производительности, способный имитировать реальное поведение пользователя и взаимодействие с веб-сайтами с помощью технологий веб-автоматизации, таких как "Javascript + Nightwatch", "Java + TestUI" или "Python + Py-TestUI". ». Наряду с этим он предоставляет вам всю необходимую статистику WebRTC и машины, такую ​​как FPS, битрейт, джиттер, время приема-передачи и другие, которые были собраны во время тестового прогона и могут подтвердить их.

Поскольку для мониторинга требуется постоянное наблюдение, например, постоянные тестовые прогоны в нашем случае, нам также потребуется периодически запускать тестовые прогоны. Для этой цели отличным выбором будет конвейер CI/CD, поскольку он гибкий и его несложно настроить для нашей задачи. Помимо периодического запуска тестов, конвейер также можно использовать для автоматизации тестирования после каждого развертывания, чтобы убедиться, что производительность в порядке.

Чтобы начать мониторинг вашего решения WebRTC с помощью Loadero, требуется настройка, состоящая из 3 частей:

  1. Тест Loadero для оценки производительности вашего приложения WebRTC. Вы можете найти пример здесь< /а>.
  2. Сценарий, использующий Loadero API для запуска теста, получения результатов и уведомления о сбое.
  3. Конвейер CI/CD для автоматического запуска скрипта.

Настройка теста для настройки мониторинга

Давайте начнем с настройки теста Loadero для нашего примера настройки мониторинга. Если у вас уже есть тест в Loadero, который можно запустить для проверки некоторых показателей производительности, вы можете пропустить эту часть и перейти к части о запуске тестов через пайплайн. Если вы впервые работаете над тестом в Loadero, полное пошаговое руководство по созданию теста в Loadero можно найти по адресу этот пост в блоге. Если у вас уже есть тест производительности WebRTC в другом сервисе, узнайте, как перенести его в Loadero здесь. В нашем случае у нас будет тест «Javascript + Nightwatch». Сценарий этого будет одноминутным разговором один на один в Jitsi.

В тесте два участника присоединятся к разговору и останутся в нем на минуту, сделав несколько снимков экрана для дополнительной проверки соединения.

Участники будут подключаться из американского штата Орегон, будут использовать последнюю версию Google Chrome (109v на момент написания этого блога) и будут использовать видео и аудио по умолчанию для имитации выходного сигнала.

Мы также будем использовать Loadero post- запускать утверждения. Они позволяют указать критерий «успешно» для WebRTC и/или машинных показателей в вашем тесте, например, «если средний FPS ≥ 10, затем успешно». После завершения выполнения вычисляются результаты утверждений. автоматически для каждого участника, чтобы проверить, соответствуют ли заданные значения критериям прохода. Если утверждение не удалось для участника, статус этого участника в отчете о результатах также будет «Не выполнен».

С помощью утверждений мы будем оценивать входящий и исходящий битрейт и пакеты для аудио и видео, а также FPS.

Конфигурация нашего теста будет примерно такой:

* Тестовый режим: «Тест производительности» * Стратегия увеличения: «Линейный участник» * Интервал запуска: 1 с * Тайм-аут участника: 5 минут

Loadero test configuration

В этом примере у нас есть тестовый скрипт Loadero, написанный на Javascript + Nightwatch, но то же самое можно сделать с помощью Java + TestUI или Python + Py-TestUI.

client => {
    client
      // Open the page
        .url(`https://meet.jit.si/LoaderoTests`)

         // Wait until the username field is visible
      // And enter the username
        .waitForElementVisible('[placeholder]', 30 * 1000)
        .sendKeys('[placeholder]', 'User')

         // Wait until the "Join" button is visible
      // And join the call by pressing the button
        .waitForElementVisible('[aria-label="Join meeting"]', 10 * 1000) 
        .click('[aria-label="Join meeting"]')

      // Another thing you can do is to take screenshots during the test
      // Which could help you to identify the cause of a failure
      // And give visual feeback about the test run
        .takeScreenshot('pre_call_screenshot.png')

         // Stay in the call for half a minute
        .pause(30 * 1000)

      // Take a mid-call screenshot
        .takeScreenshot('mid_call_screenshot.png')

    // Stay in the call for another half a minute
       .pause(30 * 1000)

    // Take a post-call screenshot
    .takeScreenshot('post_call_screenshot.png');
}

Настройка ожидаемой производительности WebRTC

Каждое приложение WebRTC отличается друг от друга и будет иметь разную производительность. Здесь мы стремимся определить пороговые значения, при которых мы хотим быть немедленно уведомлены, если ожидаемая производительность не соответствует ожиданиям, даже если это произойдет ночью. Для этого мы будем использовать набор утверждений Loadero после запуска для метрик WebRTC, что приведет к сбою всего тестового запуска, если значения метрик производительности WebRTC не так хороши, как нам хотелось бы их видеть. Следовательно, целевые значения не должны устанавливаться в узком диапазоне, но мы должны допускать, чтобы тесты иногда были немного хуже, чем нам бы хотелось в идеале, но все же в пределах разумной производительности. Значения, которые мы установили здесь, являются примерами, и вы можете настроить их в зависимости от специфики приложения (например, если вы отдаете предпочтение высокой частоте кадров, а не пропускной способности сети, вы можете увеличить минимальную частоту кадров, которую вы хотите видеть, и уменьшить ограничения по битрейту). В качестве отправной точки вы можете использовать список утверждений ниже:

Post-run assertions setup

Вот список утверждений и их значений, которые мы установили для этого примера теста:

* Утверждайте, что видео имеет не менее 10 кадров в секунду для более чем 75% продолжительности вызова как во входящем, так и в исходящем видеопотоке. Дополнительно проверьте, чтобы колебания частоты кадров были небольшими, не более 2 кадров в секунду, установив утверждение на стандартное отклонение: * webrtc/video/fps/out/25th >= 10 * webrtc/video/fps/in/25th >= 10 * webrtc/video/fps/out/stddev < 2 * webrtc/video/fps/in/stddev < 2


  • Проверка количества пакетов, отправляемых в секунду, важна для обеспечения оптимальной производительности. Отправка слишком большого количества пакетов в секунду приведет к увеличению накладных расходов, но при отправке большего количества пакетов дрожание может быть ниже, поскольку задержка между пакетами меньше. Должен быть найден хороший баланс, и он может отличаться от приложения к приложению. В этом примере мы проверим, находится ли число пакетов, отправленных в секунду, между 40 и 100:
  • webrtc/audio/packets/out/avg > 40/сек
  • webrtc/video/packets/out/avg > 100/сек
  • webrtc/audio/packets/in/avg > 40/сек
  • webrtc/video/packets/in/avg > 100/сек

    * Битрейт указывает количество данных, отправляемых в секунду. Как правило, чем выше качество отправляемого медиа, тем выше битрейт. Однако некоторые приложения будут пытаться минимизировать битрейт, чтобы лучше работать в плохих сетях и потреблять меньше данных. С помощью этих утверждений мы проверяем, что потребление данных не превышает установленных значений 25 кбит/с для входящего и исходящего аудио и 1000 кбит/с для входящего и исходящего видео в течение 95% времени теста: * webrtc/audio/bitrate/out/95th <= 25 кбит/сек * webrtc/video/bitrate/out/95th <= 1000 кбит/сек * webrtc/audio/bitrate/in/95th <= 25 кбит/сек * webrtc/video/bitrate/in/95th <= 1000 кбит/сек

Настройка участников теста и запуск теста

Наконец, нам нужно настроить участников теста. У нас будет 1 группа участников, в которой будет 2 участника с одинаковой конфигурацией, которые присоединятся к вызову. Настройка участников следующая:

  • Название – «Участник»
  • Количество – 2
  • Вычислительные единицы: G2
  • Браузер – «Последняя версия Google Chrome».
  • Местоположение — «Запад США — Орегон».
  • Сеть — «Настройки сети по умолчанию»
  • Аудиопоток – «Аудиопоток по умолчанию»
  • Видеопоток – «Видеопоток по умолчанию»

<цитата>

Совет: если вы хотите иметь много участников с одинаковой конфигурацией, увеличьте в меню конфигурации значение Количество. В целях экономии вашего времени мы предлагаем создавать участников индивидуально только в том случае, если они должны иметь разные конфигурации.

Test participant setup

Для тестовой конфигурации это было бы так. Но поскольку мы намерены регулярно запускать наш тест, прежде чем мы приступим к настройке параметров мониторинга, запустите тест и убедитесь, что сценарий исправен, проверив журналы Selenium и снимки экрана, сделанные участниками во время тестового запуска. Если вы впервые запускаете тест в Loadero или просто не уверены, правильно ли он настроен, используйте этот пост в блоге, чтобы проверить, готов ли ваш тест к запуску.

Selenium log in test run results

Screenshot taken by a test participant

Как упоминалось ранее, участники все равно могут потерпеть неудачу, если утверждения метрики WebRTC не будут выполнены, и вероятность успеха может быть не 100%. Это произошло и с нашим тестом.

Finished test run status

Это не обязательно означает, что тест неисправен, просто приложение не соответствует установленным вами критериям утверждения. Но если ваш тест не прошел по другой причине, а не по установленным утверждениям, эта запись в блоге объясняет некоторые способы отладки теста.

Утверждения, которые мы устанавливаем, являются просто общими базовыми показателями, не адаптированными к тестируемому приложению. Вы можете использовать список и начать с этих значений, но тестируемое приложение может отличаться, и результаты метрик также могут сильно отличаться.

<цитата>

Совет. Один из хороших способов установить свои собственные утверждения — провести 5 тестовых прогонов, посмотреть на показатели участников и оценить разумные цели.

Установка этих утверждений и анализ результатов, чтобы выяснить, почему утверждения не сработали, — сама по себе сложная задача, поэтому мы не будем вдаваться в подробности в этом сообщении блога. Также тот факт, что наш пример теста провалился из-за ошибки утверждения, имитирует именно тот случай, который нам нужен, когда тест провалился и отправляется уведомление о провале, поэтому оставим как есть. Если журналы Selenium показывают, что вы не столкнулись с какими-либо ошибками, а скриншоты подтверждают, что все необходимые действия были предприняты, значит, тест еще готов.

Регулярный запуск тестов из конвейера

Наша команда уже подготовила несколько сообщений в блоге о том, как интегрировать тесты в процесс разработки: с использованием JS и Python-клиент Loadero. Поэтому здесь мы будем полагаться на них. Для нашей настройки мы будем использовать то, что предлагается в сообщении блога, в котором используются Python, GitHub и его реализация CI/CD — рабочие процессы вместе с клиентом Loadero Python.

==Примечание: некоторая информация может быть пропущена. Подробные инструкции см. в оригинальном Запись в блоге Loadero Python.==

Для нашего рабочего процесса нам понадобится:

  • Репозиторий GitHub
  • Файл YAML, определяющий рабочий процесс.
  • Скрипт Python для запуска теста Loadero и отчета о результатах.

Создайте новый репозиторий на GitHub или используйте существующий.

n В вашем репозитории в каталоге .github/workflows создайте файл notify-on-fail.yml. Это файл, который будет содержать инструкции по настройке среды и запуску теста Loadero.

Давайте начнем определять рабочий процесс, указав триггеры в notify-on-fail.yml.

on:
  schedule:
    - cron:  '0 9-18 * * *'
  workflow_dispatch:

schedule позволяет запускать рабочий процесс в запланированное время. Следовательно, это место, где вы определяете частоту тестовых прогонов. В нашем примере мы установили расписание для запуска теста каждый час с 9:00 до 18:00, так как это время, когда команда, скорее всего, сможет отреагировать на неудачу. В случае, если вам может потребоваться запускать тесты в течение всего дневного и ночного цикла, вы можете предпочесть запускать их каждые 4 часа или около того. Таким образом, вы следите за приложением, даже когда никто не спит. Обратите внимание, что schedule использует особый синтаксис, о котором вы можете узнать подробнее здесь.

<цитата>

Совет. При настройке частоты тестов учитывайте, что период между запусками тестов должен быть больше, чем продолжительность теста, так как ваши тесты могут мешать друг другу.

Второй триггер — workflow_dispatch — позволяет запускать конвейер вручную через веб-приложение GitHub, если это необходимо.

В нашем разделе скрипта jobs мы указываем среду и все зависимости, которые будем использовать. Для наших целей конфигурация из Сообщение в блоге Loadero Python подходит идеально, так что не стесняйтесь копировать и вставлять его.

jobs:
  notify-on-fail:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-python@v4
        with:
          python-version: "3.10"
      - run: pip install loadero-python
      - run: python run.py
        env:
          LOADERO_ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }}
          LOADERO_PROJECT_ID: ${{ secrets.PROJECT_ID }}
          LOADERO_TEST_ID: ${{ secrets.TEST_ID }}

<цитата>

Важно: обратите внимание, что в строке - run: python run.py, после python у нас идет путь к вашему run.py относительно корня репозитория. В моем случае файловая структура будет выглядеть так:

Pipeline file structure

Еще одна вещь, на которую следует обратить внимание, — учетные данные. Во-первых, вы можете найти идентификатор теста и проекта в Loadero, но вам также понадобится токен доступа к API проекта — в настоящее время токены доступа к проекту можно получить, запросив их у нашей службы поддержки. Во-вторых, учетные данные используются в качестве секретов GitHub Actions. Это сохранит конфиденциальность вашего токена доступа Loadero. Секреты можно настроить в настройках репозитория -> Безопасность -> Секреты и переменные -> Действия -> Новый секрет репозитория.

Подробные пошаговые инструкции о секретах см. в ранее упомянутом сообщение в блоге.

Таким образом, конфигурация рабочего процесса на данный момент должна выглядеть примерно так:

name: Notify about failing tests in Loadero

on:
  schedule:
    - cron:  '0 9-18 * * *'
  workflow_dispatch:

jobs:
  notify-on-fail:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-python@v4
        with:
          python-version: "3.10"
      - run: pip install loadero-python
       - run: python run.py
        env:
          LOADERO_ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }}
          LOADERO_PROJECT_ID: ${{ secrets.PROJECT_ID }}
          LOADERO_TEST_ID: ${{ secrets.TEST_ID }}

Теперь давайте добавим в нашу настройку скрипт Python для взаимодействия с Loadero. И снова скрипт из Loadero Блог Python — отличная отправная точка, поэтому мы будем использовать его и модифицировать позже для наших нужд.

import os
from loadero_python.api_client import APIClient
from loadero_python.resources.test import Test


project_id = os.environ.get("LOADERO_PROJECT_ID", None)
access_token = os.environ.get("LOADERO_ACCESS_TOKEN", None)
test_id = os.environ.get("LOADERO_TEST_ID", None)


if project_id is None or access_token is None or test_id is None:
    raise Exception(
        "Please set the "
        "LOADERO_PROJECT_ID and LOADERO_ACCESS_TOKEN AND LOADERO_TEST_ID "
        "environment variables."
    )

APIClient(
    project_id=project_id,
    access_token=access_token,
)


run = Test(test_id=test_id).launch().poll()

print(run)

for result in run.results()[0]:
    print(result)

if run.params.success_rate != 1:
    raise Exception("Test failed")

Отправка уведомлений о неудачных тестах

Теперь пришло время изменить наш скрипт Python, чтобы реализовать наши уведомления. В этом примере оповещение будет отправлено на канал Discord. Хотя то, как вы реализуете уведомления, совершенно необязательно, так как это зависит от ваших личных предпочтений.

Давайте обновим наш файл Python, импортировав библиотеку запросов, классы ResultStatus и AssertStatus.

import requests
import os
from loadero_python.api_client import APIClient
from loadero_python.resources.test import Test
from loadero_python.resources.classificator import ResultStatus, AssertStatus

А также обновление нашего файла YAML для установки библиотеки запросов.

- run: pip install loadero-python
- run: pip install requests
- run: python run.py

Если конвейер настроен неправильно и значение любого из учетных данных равно None, мы должны уведомить об этом наш канал Discord, отправив запрос POST с сообщением об ошибке.

missing_credentials_message = (
    "Please set the "
    "LOADERO_PROJECT_ID and LOADERO_ACCESS_TOKEN AND LOADERO_TEST_ID "
    "environment variables."
)


def send_notification(message):
    requests.post(
        "https://discordapp.com/api/webhooks/{id}",
        data={"content": message},
    )


if project_id is None or access_token is None or test_id is None:
    send_notification(missing_credentials_message)
    raise Exception(missing_credentials_message)

Если тест не пройден, мы хотели бы знать причину. Здесь мы добавляем верификацию участника. Если участник терпит неудачу, мы отправляем сообщение об ошибке со следующей структурой:

  • Имена участников
  • Результат селена
  • Статус
  • Неверный путь утверждения
  • Статус выполнения

Кроме того, мы должны избавиться от исключения, которое было в исходном скрипте, так как здесь оно излишне

run_failure_message = ""

for result in run.results()[0]:
        result.params.run_id = run.params.run_id
        result.read()

        if (
            result.params.selenium_result.value != ResultStatus.RS_PASS
            or result.params.status.value != ResultStatus.RS_PASS
        ):
            run_failure_message += (
                f"{result.params.participant_details.participant_name}:n"
                f"-Selenium result: {result.params.selenium_result.value}n"
                f"-Participant status: {result.params.status.value}n"
            )

            if result.params.asserts:

                run_failure_message += "-Failing asserts:n"

                for assertion in result.params.asserts:
                    if assertion.status != AssertStatus.AS_PASS:
                        run_failure_message += f"--{assertion.path.value}n"

        run_failure_message += "n"

run_failure_message += f"Run status: {run.params.status.value}"

if run.params.success_rate != 1:
    send_notification(run_failure_message)

А также отправим сообщение об успешном прогоне теста:

 if run.params.success_rate != 1:
        send_notification(run_failure_message)
else:
        send_notification(f"The {run.params.test_name} test has been finished successfully")

В качестве окончательной проверки мы должны обернуть весь вызов API в try-except на случай, если соединение с API Loadero ошибочно. Окончательный скрипт на Python выглядит примерно так:

import os
import requests
from loadero_python.api_client import APIClient
from loadero_python.resources.test import Test
from loadero_python.resources.classificator import ResultStatus, AssertStatus

project_id = os.environ.get("LOADERO_PROJECT_ID", None)
access_token = os.environ.get("LOADERO_ACCESS_TOKEN", None)
test_id = os.environ.get("LOADERO_TEST_ID", None)

missing_credentials_message = (
    "Please set the "
    "LOADERO_PROJECT_ID and LOADERO_ACCESS_TOKEN AND LOADERO_TEST_ID "
    "environment variables."
)


def send_notification(message):
    requests.post(
        "https://discordapp.com/api/webhooks/{id}",
        data={"content": message},
    )


if project_id is None or access_token is None or test_id is None:
    send_notification(missing_credentials_message)
    raise Exception(missing_credentials_message)

try:
    APIClient(
        project_id=project_id,
        access_token=access_token,
    )

    run = Test(test_id=test_id).launch().poll()
 print(run)

    run_failure_message = ""

    for result in run.results()[0]:
        result.params.run_id = run.params.run_id
        result.read()

        if (
            result.params.selenium_result.value != ResultStatus.RS_PASS
            or result.params.status.value != ResultStatus.RS_PASS
        ):
            run_failure_message += (
                f"{result.params.participant_details.participant_name}:n"
                f"-Selenium result: {result.params.selenium_result.value}n"
                f"-Participant status: {result.params.status.value}n"
            )

            if result.params.asserts:

                run_failure_message += "-Failing asserts:n"

                for assertion in result.params.asserts:
                    if assertion.status != AssertStatus.AS_PASS:
                        run_failure_message += f"--{assertion.path.value}n"

        run_failure_message += "n"

    run_failure_message += f"Run status: {run.params.status.value}"

    if run.params.success_rate != 1:
        send_notification(run_failure_message)
    else:
        send_notification(
            f"The {run.params.test_name} test has been finished successfully"
        )
except Exception as err:
    send_notification(f"Error while running Loadero test: {err}")

Проверка результатов мониторинга WebRTC

Теперь наш тест автоматически запускается каждый час с 9:00 до 18:00 и оценивает, работает ли приложение должным образом.

После завершения выполнения теста в случае сбоя теста вы получите уведомление об ошибке.

В нашем случае тест Jitsi не прошел из-за того, что FPS и пакеты не соответствуют нашим критериям, что можно увидеть на вкладке Asserts результата теста. Результаты утверждения также доступны для каждого участника в отдельности, поэтому вы можете проверить, возникла ли проблема для всех участников или только для их части.

Asserts execution results in the test run results

Приведенные выше значения для утверждений могут служить отправной точкой, и кажется, что в нашем случае они не соответствуют целевой производительности Jitsi. Поэтому не стесняйтесь исследовать, как работает ваше приложение и какие утверждения лучше всего подходят для вашего приложения, чтобы убедиться, что процесс мониторинга оптимален.

Примечание: просто взглянув на утверждения нашего теста, мы можем заметить, что есть целые разделы, которые выводят нули во время выполнения теста, что в конечном итоге влияет на результаты теста.

<цитата>

Совет. Если ваш тест не пройден, вы можете перейти на вкладку статистики WebRTC, где вы можете найти различные графики с данными и получить дополнительную информацию о метрике, вызвавшей сбой.

В этом сообщении блога мы представили пример того, как вы можете контролировать свое приложение WebRTC с помощью рабочих процессов Loadero и GitHub. Используя мониторинг, вы лучше подготовлены к решению любых проблем, которые могут возникнуть в вашем приложении. Также может быть целесообразно создать другие сценарии с другими условиями для более целостного представления о производительности приложения. Настройка такого мониторинга может быть достаточно сложной задачей. Хотели бы вы, чтобы команда Loadero создала для вас аналогичную настройку мониторинга? Не стесняйтесь обращаться к нам по адресу support@loadero.com и давайте обсудим, как мы можем помочь вам регулярно и автоматически отслеживать ваше решение WebRTC.

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

:::


Оригинал