djangonginxgunicornsupervisord

Gunicorn doesn't log real ip from nginx


I run a django app via gunicorn, supervisor and nginx as reverse proxy and struggle to make my gunicorn access log show the actual ip instead of 127.0.0.1:

Log entries look like this at the moment:

127.0.0.1 - - [09/Sep/2014:15:46:52] "GET /admin/ HTTP/1.0" ...

supervisord.conf

[program:gunicorn]
command=/opt/middleware/bin/gunicorn --chdir /opt/middleware -c /opt/middleware/gunicorn_conf.py middleware.wsgi:application 
stdout_logfile=/var/log/middleware/gunicorn.log

gunicorn_conf.py

#!python
from os import environ
from gevent import monkey
import multiprocessing
monkey.patch_all()

bind = "0.0.0.0:9000"
x_forwarded_for_header = "X-Real-IP"
policy_server = False
worker_class = "socketio.sgunicorn.GeventSocketIOWorker"   
accesslog = '-'

my nginx module conf

server {
    listen 80;
    root /opt/middleware;
    index index.html index.htm;
    client_max_body_size 200M;
    server_name _;

    location / {
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_redirect off;
        real_ip_header X-Real-IP;

      }
    }

I tried all sorts of combinations in the location {} block, but can't see that it makes any difference. Any hint appreciated.


Solution

  • The problem is that you need to configure gunicorn's logging, because it will (by default) not display any custom headers.

    From the documentation, we find out that the default access log format is controlled by access_log_format and is set to the following:

    "%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"
    

    where:

    You can also customize it with the following extra variables that are not used by default:

    To gunicorn, all requests are coming from nginx so it will display that as the remote IP. To get it to log any custom headers (what you are sending from nginx) you'll need to adjust this parameter and add the appropriate variables, in your case you would set it to the following:

    %(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s" "%({X-Real-IP}i)s"