1

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?

Sean
  • 4,365
  • 1
  • 27
  • 31

1 Answers1

7

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
Sean
  • 4,365
  • 1
  • 27
  • 31
  • What does `%p` mean? – Piotr Dobrogost Mar 31 '16 at 14:27
  • `%p` is expanded to the full absolute path to the configuration file. Here's a list of available [magic variables](http://uwsgi-docs.readthedocs.org/en/latest/Configuration.html). – Sean Mar 31 '16 at 18:17
  • 1
    I believe the right usage is `true` for paste-logger. http://uwsgi-docs.readthedocs.io/en/latest/Options.html?highlight=paste-logger#paste-logger. -> `uwsgi_opt_true` – hyperknot Jan 19 '17 at 18:10