Рубрики
Без рубрики

Руководство по удаленной отладке для Python

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

Автор оригинала: Jorge Colon.

Вы когда-нибудь сталкивались с серьезной ошибкой в производстве, которая не появляется на вашей машине даже после того, как у вас есть паритет практически со всем? Или, может быть, у вас нет особого выбора, кроме как работать непосредственно на сервере? Вы в конечном итоге используете печать или регистратор и просто случайно бросаете их в разные места, надеясь увидеть, что происходит?

Я представлю вам удаленную отладку. Удаленная отладка позволяет вам интерактивно отлаживать код, которого нет на вашем компьютере, построчно. Это то, что другие описывали как “Божий посыл” для отладки сложных проблем. С его помощью вы гораздо быстрее доберетесь до корня проблемы, и это чрезвычайно полезно, когда вам нужно перепроектировать проект.

Мы будем использовать пакет python, чтобы иметь общий API для работы.

  • Код Visual Studio или Pycharm Professional
  • Установлена зависимость ptsd или pydev_pycharm

pip установить git+ssh://git@github.com/2upmedia/debugger_helper

Есть пять частей для удаленной отладки с помощью Python:

  1. сервер может взаимодействовать с вашей рабочей станцией
  2. на сервере установлен соответствующий пакет IDE
  3. ваша среда IDE правильно настроена для удаленной отладки
  4. вы запускаете конфигурацию удаленной отладки в своей среде IDE в нужное время
  5. у вас есть тот же код, который находится на сервере на вашей рабочей станции
у вас есть тот же код, который находится на сервере на вашей рабочей станции

Для каждой IDE существует отладочный пакет, который служит отладчиком на сервере. Он обменивается данными между сервером и идеей.

Вам нужно убедиться, что сервер может взаимодействовать с вашей рабочей станцией. Это существенная часть удаленной отладки, потому что между сервером и IDE отправляются пакеты TCP туда и обратно. Эти пакеты передают такие вещи, как место установки точек останова и информацию о текущем стеке и переменных. По сути, так работают все удаленные отладчики.

Самый простой способ разрешить линию связи TCP, которая обходит любые проблемы с брандмауэром,-это перенаправление портов. Это возможно с помощью ssh или шпатлевки.

С ssh просто выдайте ssh -R LOCAL_PORT:IP:REMOTE_PORT user@host для обратного порта вперед и ssh-L LOCAL_PORT:IP:REMOTE_PORT user@host для локального порта вперед. Как правило, вы бы использовали 127.0.0.1 для IP и тех же номеров портов, например, ssh-L 9000:127.0.0.1:9000 user@host . Перенаправление локального порта означает, что сокет выделяется и прослушивается на вашем локальном компьютере и перенаправляет TCP-соединение на указанный удаленный порт на сервере. Обратная переадресация порта означает, что сокет выделяется и прослушивается на вашей удаленной машине и перенаправляет TCP-соединение на указанный локальный порт на вашей машине. Код Visual Studio использует локальную переадресацию портов , в то время как PyCharm нуждается в обратной переадресации портов.

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

$ openssl s_client -connect 127.0.0.1:9000
connect_to 127.0.0.1 port 9000: failed.
CONNECTED(00000004)

Если у вас установлен telnet, вы также можете попробовать…

$ telnet 127.0.0.1 9000
Trying 127.0.0.1...
Connected to localhost.

То, что вы ищете, – это CONNECTED для openssl. Для telnet, если он не выходит из telnet и не получает ошибку через некоторое время, это означает, что он подключен.

С точки зрения настройки это означает, что для PyCharm вам нужно сначала запустить удаленную конфигурацию IDE перед запуском скрипта python, а для кода Visual Studio вы запускаете его после вашего скрипта python.

Параметры IDE удаленного отладчика определяют сопоставления хоста, порта и пути. Сопоставление путей отображает путь к папке с сервера на путь к папке на локальном компьютере, чтобы отладчик мог выбрать правильный файл.

Модуль debugger_helper использует три переменные среды:

  • START_DEBUGGER
  • DEBUGGER_HOST (по умолчанию 127.0.0.1 )
  • DEBUGGER_PORT (по умолчанию 9000 )

Переменная окружения START_DEBUGGER должна иметь любое непустое значение, например 1 прямо перед запуском скрипта python, который вы хотели бы отладить.

Если все настроено правильно, отладчик должен немедленно остановиться в точке останова. Если это не так, дважды проверьте каждый шаг.

  • установите ptvs на сервер
  • убедитесь, что pydev-pycharm не установлен, так как он конфликтует с ptsd
  • добавьте локальный порт вперед с вашего компьютера на сервер через ssh (или putty)
  • добавьте следующее где-нибудь в верхней части вашего проекта python . Например, если это приложение для колбы с app.py файл вы можете поместить его прямо в верхней части после импорта.
import ptvsd
debugger_helper.attach_vscode(lambda host, port: ptvsd.enable_attach(address=(host, port), redirect_output=True))
  • перейдите на панель отладки, добавьте конфигурацию, нажмите на Python, затем Remote Attach, установите хост в 127.0.0.1 , порт на 9000 (или порт , чтобы соответствовать переадресации портов и переменной среды DEBUGGER_PORT ). Вы должны увидеть эти значения в launch.json .
  • для remote Root установите абсолютный путь к папке , содержащей ваш скрипт python на сервере. Например, возможно, он находится в /www/python app/|/. Вы бы использовали это для удаленного корня . установите точку останова, в которой вы хотите, чтобы отладчик остановился
  • Запустите скрипт python
  • $ python app.py и ждать , пока он не скажет, что готов подключиться к отладчику Запустите конфигурацию удаленного подключения в коде Visual Studio.
  • установите pydev_pycharm на сервере
  • добавьте обратный порт вперед с сервера на вашу машину через ssh (или putty)
  • добавьте конфигурацию запуска для удаленной отладки Python. Установите хост в 127.0.0.1 и порт 9000 . Сохраните его.
  • в поле конфигурация и сопоставление путей добавьте сопоставление для абсолютного пути корня проекта с абсолютным путем того же корня проекта, но на сервере
  • добавьте следующее где-нибудь в верхней части вашего проекта python . Например, если это приложение для колбы с app.py файл вы можете поместить его прямо в верхней части после импорта.
import pydevd_pycharm
debugger_helper.attach_pycharm(lambda host, port: pydevd_pycharm.settrace(host, port=port, stdoutToServer=True, stderrToServer=True))
  • установите точку останова, в которой вы хотите, чтобы отладчик остановился. Вы можете установить pydev_pycharm.settrace (...,) , если хотите, чтобы отладчик не останавливался на строке, на которой settrace включен.
  • Запустите конфигурацию удаленной отладки в PyCharm.
  • Запустите скрипт python $ python app.py

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

Что вам нужно сделать, так это перезапустить процесс python при обновлении файла python. Мы можем сделать это автоматически с помощью watchdog .

Так что давайте пройдемся по этому вопросу.

  • установить сторожевой пес
  • создайте второй скрипт, который вызовет ваш основной скрипт python, который включает отладчик. Это должно выглядеть примерно так:
# debug.py
import subprocess


def main():
    subprocess.call(['python', 'app.py']) # that's the same as the shell command ``$ python app.py``
  • Запустите скрипт python с помощью watchdog $ watchdog debug.main
  • Теперь в вашей IDE загрузите файл

Может быть, вы хотите включать отладчик только тогда, когда вам этого хочется?

Вот пример того, как это сделать в колбе. К сожалению, пакеты IDE не позволяют отключить отладчик после его включения, поэтому нам придется применить грубую силу, убив процесс python. Это означает, что вам нужно будет вручную запустить его снова, или вы можете использовать что-то вроде gunicorn, которое породит новый процесс после того, как он увидит, что старый процесс будет убит.

Следуйте за мной.

  • создайте функцию, которая проверит параметр запроса, а затем запустит отладчик для запуска
  • обратите внимание на аргумент call_immediately=True в attach_pycharm . Это позволяет запускать отладчик на основе вашего набора правил.
  • вызовите эту функцию в теле маршрута
from flask import Flask, request

is_debugger_enabled = False


def attach_debugger():
    global is_debugger_enabled
    if request.args.get('START_DEBUGGER', ''):
        debugger_helper.attach_pycharm(lambda host, port: pydevd_pycharm.settrace(host, port=port, stdoutToServer=True, stderrToServer=True, suspend=False), call_immediately=True)
        is_debugger_enabled = True
    elif is_debugger_enabled:
        print('Trying to disable debugger that was enabled. Killing process to start a fresh one.')
        sys.exit(1)


@app.route("/")
def hello():
    attach_debugger()
    message = "Hello Worlddd!"
    return message
  • следуйте инструкциям по Настройке Pycharm выше
  • вызовите URL-адрес в браузере с добавленным к нему параметром запроса START_DEBUGGER . http://IP:5000/?START_DEBUGGER=1

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

Счастливой отладки!