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

Обзор

Для новичков в Python вы можете использовать print или pprint для устранения неполадок и отладки. По мере того, как вы получаете больше знаний, вы начинаете использовать регистрацию, обратную связь, pdb, ipdb или использовать редакторы кода, которые помогают вам в отладке ваших приложений. Этого должно быть достаточно в большинстве случаев. Однако что, если приложение работает на удаленном сервере, и вам не разрешено вносить какие-либо изменения в код, но вам все же необходимо устранить неполадки, или если приложение работает в среде Docker?

В моей предыдущей статье Обслуживание моделей машинного обучения (DCGAN, PGAN, ResNext) с использованием FastAPI и Streamlit я описал, как автоматически перезагружать изменения кода, а также выполнять отладку для докеризированных фронтенд и бэкенд приложений с помощью расширения Remote — Containers. . В этой статье я подробно расскажу, как отлаживать работающее или Dockerized приложение Python.

Предпосылки

Я собираюсь использовать библиотеку debugpy, которую можно установить через pip.

# pip install debugpy

Отладка работающего приложения Python

Давайте начнем с запуска простого приложения Python, которое непрерывно выводит переменную и приостанавливается на 1 секунду, чтобы имитировать длительное выполнение серверного приложения.

Запустите это приложение, и вы должны увидеть результат, аналогичный приведенному ниже.

# python loop.py

Теперь, когда debugpy установлен, я собираюсь внедрить отладчик в этот запущенный процесс.

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

# ps -ef| grep loop.py

В моем случае идентификатор процесса 41890.

С идентификатором процесса я использую следующую команду для внедрения отладчика. Я использую 0.0.0.0, чтобы он мог удаленно принимать сетевое подключение.

# python -m debugpy --listen 0.0.0.0:5678 --pid 41890

Теперь, используя Visual Studio Code, я могу подключиться к работающему приложению Python. VS Code можно запускать на том же компьютере или на другом компьютере.

В VS Code откройте папку, содержащую файл loop.py.

Создайте файл конфигурации запуска launch.json в папке .vscode.

Поскольку я занимаюсь отладкой локально, мой хост localhost. Для удаленной отладки измените его на имя удаленного хоста или IP-адрес.

Я устанавливаю точку останова в loop.py и запускаю конфигурацию для подключения к приложению Python.

Теперь я подключен к приложению Python и могу начать отладку.

Отладка запущенного приложения Python с подпроцессом

Вы можете подумать, что приведенный выше пример слишком упрощен. Рабочее приложение может порождать несколько потоков или даже процессов при запуске, и описанный выше метод в этом случае не работает.

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

Запустите это приложение, и результат будет таким же.

# python loop_subprocess.py

Откройте другой терминал и проверьте запущенные процессы Python.

# ps -ef | grep python

Есть 2 процесса Python 74087 и 74088, и последний я хочу отлаживать.

В VS Code замените launch.json новым содержимым ниже. В качестве альтернативы вы можете просто добавить новую конфигурацию к существующей.

Приведенная выше конфигурация запуска позволяет нам подключиться к работающему процессу Python, выбрав идентификатор процесса.

Открыв loop_subprocess.py file, запустите конфигурацию, и вам будет предложено выбрать идентификатор процесса. В моем случае идентификатор процесса 74088

И теперь вы можете отлаживать подпроцесс Python.

Удаленная отладка

Однако это работает только тогда, когда VS Code и процесс Python выполняются на одном компьютере. Что делать, если я хочу удаленно отлаживать приложение?

Это оказывается довольно просто. Просто введите отладчик в порожденный процесс.

Останавливаю loop_subprocess.py, снова запускаю и проверяю процессы.

# python loop_subprocess.py

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

# ps -ef | grep python

# python -m debugpy --listen 0.0.0.0:5678 --pid 5623 --configure-subProcess true

В моем случае, как вы можете видеть на экране, идентификатор созданного процесса — 5623.

И с приведенной ниже конфигурацией запуска я могу подключиться к приложению Python для отладки.

Фрагменты кода, которые я использовал, можно найти здесь.

Отладка запущенного Dockerized приложения

Я собираюсь повторно использовать исходный код Приложения Streamlit и FastAPI из моей предыдущей статьи.

Ниже docker-compose.yml

Из кода VS Command Palette выберите Remote-Containers: Attach to Running Container…

Я выбираю приложение /backend и открываю папку /fastapi внутри контейнера. VS Code определяет, что это приложение Python, и попросит меня установить несколько расширений Python внутри контейнера.

Поскольку я использую образ Docker python-slim, в нем отсутствуют некоторые команды и пакеты Linux, такие как ps и gdb отладчик, поэтому мне нужно выполнить следующую команду, открыв оболочку bash в контейнере.

# apt-get update && apt-get install -y procps gdb

Теперь я могу проверить запущенные процессы Python внутри контейнера.

И процесс, который я хочу отладить, это 9534.

Создайте конфигурацию запуска для подключения к процессу id9534, аналогично тому, что мы делали раньше.

Запустите конфигурацию и прикрепите к идентификатору процесса.

Я устанавливаю точку останова в /pgan API, а затем использую конечную точку API, предоставленную FastAPI, для ее запуска.

И теперь я могу отлаживать свое серверное приложение.

Вышеупомянутый метод работает только тогда, когда VS Code и контейнер Docker находятся на одном компьютере. Для удаленной отладки контейнера ознакомьтесь с подробностями в разделе Подключение к удаленному докеру через SSH. Я оставлю это для вас, чтобы исследовать.