I want to be able to debug a Python (Django) application with pdb
under uWSGI, and I'm basically having the same issue as described here getting:
...
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
The difference is that I have a different uWSGI
setup, and seems like I cannot make uWSGI
to honour-stdin
as suggested in the accepted answer from the question above.
My setup is as follows:
1) I have a systemd process to start uWSGI in Emperor mode
[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) The /etc/uwsgi/emperor.ini
looks like this:
[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) A sample configuration of one of the uwsgi sites look like this:
#/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) I'm not sure if its related to the issue, but I also have an nginx configuration to serve the site, it look like this:
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;
}
}
A temporary solution for now is to use remote-pdb
as an alternative to my approach, but I'm interested to understand whats the issue in my current configuration setup and how to fix it.
UPDATE: I just realized that even if this work, maybe I'm not properly opening my log files, so that pdb
can wait for my input. Right now I'm using tail
to see whats going on with the logs, but no idea if this works with pdb
?
UPDATE2: Did some more testing, tried to skip the systemd
+ the uwsgi emperor mode from of the equation by starting the daemon myself via:
sudo /usr/local/bin/uwsgi --ini /etc/uwsgi/sites/testproject.ini
what I'm noticing is that w/o daemonize = /tmp/uwsgi-testproject.log
in the .ini
file everything works fine, but as soon I daemonize it, stdin
starts pointing to /dev/null
(I have both honour-stdin and daemons-honour-stdin set to true). I'm checking this with
ls -l /proc/<proc_id>/fd/0
uwsgi (all lowercase) is the native binary protocol that uWSGI uses to communicate with other servers. uWSGI is often used for serving Python web applications in conjunction with web servers such as Cherokee and Nginx, which offer direct support for uWSGI's native uwsgi protocol.
Can I then ditch NGINX? uWSGI could be used as a standalone web server in production, but that is not it's intentional use. It may sound odd, but uWSGI was always supposed to be a go-between a full-featured web server like NGINX and your Python files.
If you need threads, remember to enable them with enable-threads. Running uWSGI in multithreading mode (with the threads options) will automatically enable threading support. This “strange” default behaviour is for performance reasons, no shame in that. This is another option that might be the right choice for you.
I don't know this could help you solve your problem. But, give it a try to configure your uWSGI with the below code.
Into /etc/systemd/system/emperor.uwsgi.service
put
[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
Into /etc/uwsgi/emperor.ini
put:
[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
A config for each of the sites (called "vassals" in uWSGI terms).
Into /etc/uwsgi/vassal.ini
put:
[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
Finally, the Fastrouter. This is like a smart load balancer, but will distribute requests according to their hostnames.
Into /etc/uwsgi/router.ini
put
[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
With the subscription server, The vassals can register with the FastRouter, telling it which hostnames they can handle, and what port they can be contacted on.
Then start it up using:
# systemctl start emperor.uwsgi
If this works without issue, enable it to start on boot:
# systemctl enable emperor.uwsgi
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With