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

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

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

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

  • Visual Studio Code или Pycharm Professional
  • Установлена ​​либо зависимость ptvsd, либо pydevd_pycharm

pip install git+ssh://git@github.com/2upmedia/debugger_helper

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

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

отладчик-diagram.png

Для каждой 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 для ИП и
те же номера портов, например,
ssh -L 9000:127.0.0.1:9000 user@host. Переадресация локального порта означает, что
сокет выделяется и прослушивается на вашей локальной машине и вперед
TCP-соединение с указанным удаленным портом на сервере. Реверс
переадресация порта означает, что сокет выделен и прослушивает ваш
удаленный компьютер и перенаправляет TCP-соединение на указанный локальный
порт на вашей машине. Visual Studio Code использует локальную переадресацию портов.
в то время как 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 для опенссл. Для телнета, если он
не выходит из telnet и через некоторое время не выдает ошибку, то это
значит подключено.

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

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

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

  • START_DEBUGGER
  • DEBUGGER_HOST (дефолт 127.0.0.1)
  • DEBUGGER_PORT (дефолт 9000)

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

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

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

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

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

Итак, давайте пройдем через это.

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

import subprocess


def main():
    subprocess.call(['python', 'app.py']) 
  • Запустите скрипт Python с помощью watchgod $ START_DEBUGGER=1 watchgod debug.main
  • Теперь в вашей среде IDE загрузите файл

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

Вот пример того, как это сделать в Flask. К сожалению, пакеты 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

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

Удачной отладки!

Похожие записи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *