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.
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:
h
is the remote addressl
is -
(not used)u
is -
(not used, reserved)t
is the time stampr
is the status lines
is the status of the requestb
is length of responsef
is referrera
is user agentYou can also customize it with the following extra variables that are not used by default:
T
- request time (in seconds)D
- request time (in microseconds)p
- the process id{Header}i
- request header (custom){Response}o
- response header (custom)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"