First, a little background. I'm running an app under uWSGI in emperor mode. The uWSGI command line:
uwsgi --master --emperor /etc/uwsgi --die-on-term --uid uwsgi --gid uwsgi
The INI file for my app is in /etc/uwsgi and it is successfully found when uWSGI starts. My app's uwsgi and logging configuration sections:
[uwsgi]
socket = /tmp/uwsgi.sock
master = true
processes = 8
threads = 4
harakiri = 60
harakiri-verbose = true
limit-post = 52428800
post-buffering = 8192
listen = 256
max-requests = 1000
buffer-size = 32768
no-orphans = true
logto = /var/log/uwsgi/my_app.log
log-slow = 1000
virtualenv = /usr/local/python/my_app
paste = config:%p
[loggers]
keys = root, my_app
[handlers]
keys = console
[formatters]
keys = generic
[logger_root]
level = WARN
handlers = console
[logger_my_app]
level = DEBUG
handlers =
qualname = my_app
[handler_console]
class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = generic
[formatter_generic]
format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s
Nginx is configured to proxy the site, and does so successfully. The app starts and runs fine. I have no problem getting to it from a web browser. The problem starts when I try to log something from my app like so:
import logging
log = logging.getLogger(__name__)
log.info('hello world')
In my log, instead of "hello world", I see the following:
No handlers could be found for logger "my_app.my_module"
It appears that uWSGI is not picking up the logging configuration from my INI file. I've seen people suggest using the "--ini-paste-logged my.ini" option on the uWSGI command line, but this won't work in my case since I'm using emperor mode.
Others have suggested calling pyramid.paster.setup_logging from within the app, but this seems like a non-ideal solution. Firstly, during development, I run the app locally with pserve which calls setup_logging automatically, so I'd have to call it conditionally depending on which environment the app is running in. Secondly, setup_logging requires the path to the config file as an argument, and I need to be able to use different configs for staging and production environments, so it seems I'd have to do something like add a setting in the config file that specifies the path to itself. A convoluted solution at best.
Any idea how I can get uWSGI to pick up my logging configuration without jumping through a bunch of hoops?
Figured it out and might as well leave it here for posterity since there seems to be precious little content on the web about emperor mode. I added "paste-logger = %p" to the uwsgi section of my INI file, and logging appears to work now. Full uwsgi section for context:
[uwsgi]
socket = /tmp/uwsgi.sock
master = true
processes = 8
threads = 4
harakiri = 60
harakiri-verbose = true
limit-post = 52428800
post-buffering = 8192
listen = 256
max-requests = 1000
buffer-size = 32768
no-orphans = true
logto = /var/log/uwsgi/my_app.log
log-slow = 1000
virtualenv = /usr/local/python/my_app
paste = config:%p
paste-logger = %p