Как настроить uWSGI для отладки с помощью pdb (проблема конфигурации --honour-stdin) - PullRequest
0 голосов
/ 03 ноября 2018

Я хочу иметь возможность отлаживать приложение Python (Django) с pdb под uWSGI, и у меня в основном та же проблема, что и описанная здесь получение:

  ...
  File "/usr/lib/python2.7/bdb.py", line 49, in trace_dispatch
    return self.dispatch_line(frame)
  File "/usr/lib/python2.7/bdb.py", line 68, in dispatch_line
    if self.quitting: raise BdbQuit
BdbQuit

Разница в том, что у меня другая настройка uWSGI, и кажется, что я не могу сделать от uWSGI до honour-stdin, как это предлагается в принятом ответе на вопрос выше.

Моя настройка следующая:

1) У меня системный процесс для запуска uWSGI в режиме Emperor

[Unit]
Description=uWSGI Emperor service

[Service]
ExecStart=/usr/local/bin/uwsgi --ini /etc/uwsgi/emperor.ini
Restart=always
KillSignal=SIGQUIT
Type=notify
NotifyAccess=all

[Install]
WantedBy=multi-user.target

2) /etc/uwsgi/emperor.ini выглядит так:

[uwsgi]
emperor = /etc/uwsgi/sites
uid = www-data
gid = www-data
limit-as = 1024
logto = /tmp/uwsgi-emperor.log
# I've tried adding both honour-stdin 
# and daemons-honour-stdin here
honour-stdin = true
daemons-honour-stdin = true

3) Пример конфигурации одного из сайтов uwsgi выглядит следующим образом:

#/etc/uwsgi/sites/testproject.ini
[uwsgi]
module = wsgi
chdir = /home/myuser/projects/testproject
home = /home/myuser/.virtualenvs/testproject
env = DJANGO_SETTINGS_MODULE=testproject.settings.dev
daemonize = /tmp/uwsgi-testproject.log
master = true
processes = 1

socket = /tmp/testproject-dev.sock
chmod-socket = 664
vacuum = true

# I've also tried adding both honour-stdin 
# and daemons-honour-stdin here
honour-stdin = true
daemons-honour-stdin = true

4) Я не уверен, связано ли это с проблемой, но у меня также есть конфигурация nginx для обслуживания сайта, это выглядит так:

upstream app-testproject-dev {
    server unix:///tmp/testproject-dev.sock;
}

server {

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    listen 80;
    server_name dev.testproject.com;

    location / {
        uwsgi_pass app-testproject-dev;
        include /etc/nginx/uwsgi_params;
    }
}

В настоящее время временным решением является использование remote-pdb в качестве альтернативы моему подходу, но мне интересно понять, в чем проблема в моей текущей конфигурации и как ее исправить.

ОБНОВЛЕНИЕ : Я только что понял, что даже если это сработает, возможно, я неправильно открываю свои файлы журналов, так что pdb может ждать моего ввода. Сейчас я использую tail, чтобы увидеть, что происходит с журналами, но не знаю, работает ли это с pdb?

UPDATE2 : провел еще какое-то тестирование, попытался пропустить режим systemd + uwsgi emperor из уравнения, запустив самого демона с помощью:

sudo /usr/local/bin/uwsgi --ini /etc/uwsgi/sites/testproject.ini

я замечаю, что без daemonize = /tmp/uwsgi-testproject.log в файле .ini все работает нормально, но как только я его демонизирую, stdin начинает указывать на /dev/null (у меня есть honor-stdin и daemons-honor-stdin установлен в true). Я проверяю это с помощью

ls -l /proc/<proc_id>/fd/0

1 Ответ

0 голосов
/ 10 декабря 2018

Я не знаю, это может помочь вам решить вашу проблему. Но попробуйте настроить ваш uWSGI с помощью приведенного ниже кода.

В /etc/systemd/system/emperor.uwsgi.service положить

[Unit]
Description=uWSGI Emperor
After=syslog.target

[Service]
ExecStart=/usr/bin/uwsgi --ini /etc/uwsgi/emperor.ini
Restart=always
KillSignal=SIGQUIT
Type=notify
StandardError=syslog
NotifyAccess=all

[Install]
WantedBy=multi-user.target

В /etc/uwsgi/emperor.ini положить:

[uwsgi]
master = true
procname-master = Emperor

; Look for vassal configs using this pattern
emperor = /srv/apps/*/uwsgi.ini
; Don't resolve symlinks when considering reload-on-touch
emperor-nofollow = true

; Lowest privs
uid = www-data
gid = www-data

; Clean up our workers when we die.
no-orphans = true

Конфигурация для каждого из сайтов (называемых "вассалами" в терминах uWSGI).

В /etc/uwsgi/vassal.ini положить:

[uwsgi]
master = true
procname-master = %c

; Run with lower privs
uid = www-data
gid = www-data

; :0 lets the OS assign a port
socket = 127.0.0.1:0
; Register with the FastRouter the list of hostnames
subscribe-to = 127.0.0.1:9001:@hostnames.txt

; Paths are referenced relative to where the INI file is found
chdir = %d

# Task management
; Max 4 processes
processes = 4
; Each running 4 threads
threads = 4
; Reduce to 1 process when quiet
cheaper = 1
; Save some memory per thread
thread-stack-size = 512

# Logging
plugin = logfile
req-logger = file:logs/request.log
logger = file:logs/error.log
log-x-forwarded-for = true

# Python app
plugin = python
virtualenv = venv/
pythonpath = code/
module = %c.wsgi
enable-threads = true

# Don't load the app in the Master.
app-lazy = true

Наконец, Fastrouter. Это похоже на интеллектуальный балансировщик нагрузки, но он будет распределять запросы в соответствии с их именами хостов.

В /etc/uwsgi/router.ini положить

[uwsgi]
master = true
procname-master = FastRouter

uid = www-data
gid = www-data

plugin = fastrouter
fastrouter = %d/server.sock
; run as lower privs
fastrouter-uid = www-data
fastrouter-gid = www-data
; handle the scale
fastrouter-processes = 2
; but scale down when quiet
fastrouter-cheap = true
; let others vassals subscribe to us
fastrouter-subscription-server = 127.0.0.1:9001

# Logging
plugin = logfile
req-logger = file:logs/request.log
logger = file:logs/error.log

С помощью сервера подписки вассалы могут зарегистрироваться в FastRouter, сообщая ему, с какими именами хостов они могут работать и с каким портом они могут связаться.

Затем запустите его, используя:

# systemctl start emperor.uwsgi

Если это работает без проблем, включите его при загрузке:

# systemctl enable emperor.uwsgi
...