Вы когда-нибудь сталкивались с серьезной ошибкой в производстве, которая не появляется на вашей машине даже после того, как у вас есть паритет практически со всем? Или, может быть, у вас нет особого выбора, кроме как работать непосредственно на сервере? Вы в конечном итоге используете печать или регистратор и просто случайно бросаете их в разные места, надеясь увидеть, что происходит?
Я представлю вам удаленную отладку. Удаленная отладка позволяет вам интерактивно отлаживать код, которого нет на вашем компьютере, построчно. Это то, что другие описывали как “Божий посыл” для отладки сложных проблем. С его помощью вы гораздо быстрее доберетесь до корня проблемы, и это чрезвычайно полезно, когда вам нужно перепроектировать проект.
Мы будем использовать пакет python, чтобы иметь общий API для работы.
- Код Visual Studio или Pycharm Professional
- Установлена зависимость ptsd или pydev_pycharm
pip установить git+ssh://git@github.com/2upmedia/debugger_helper
Есть пять частей для удаленной отладки с помощью Python:
- сервер может взаимодействовать с вашей рабочей станцией
- на сервере установлен соответствующий пакет IDE
- ваша среда IDE правильно настроена для удаленной отладки
- вы запускаете конфигурацию удаленной отладки в своей среде IDE в нужное время
- у вас есть тот же код, который находится на сервере на вашей рабочей станции
Для каждой 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
Теперь, когда вы научились выполнять удаленную отладку, идите и запачкайте руки. Как только вы его используете, вы будете спрашивать себя, почему вы не использовали его раньше.
Счастливой отладки!