Django(1.6)プロジェクトをgunicornとNginxでデプロイしました。
正常に動作しているようですが、HTTP 500エラーが発生していて、エラーの詳細をどこにも見つけることができなかったページが1つあります。
Gunicornでエラーを表示するにはどうすればよいですか?
エラーが発生したページにアクセスしたときに、現在ログファイルに表示されるのは次のとおりです。
>tail gunicorn.errors
2014-02-21 14:41:02 [22676] [INFO] Listening at: unix:/opt/djangoprojects/reports/bin/gunicorn.sock (22676)
2014-02-21 14:41:02 [22676] [INFO] Using worker: sync
2014-02-21 14:41:02 [22689] [INFO] Booting worker with pid: 22689
...
2014-02-21 19:41:10 [22691] [DEBUG] GET /reports/2/
これが私がgunicornを開始するために使用する私のbashスクリプトです:
>cat gunicorn_start
#!/bin/bash
NAME="reports" # Name of the application
DJANGODIR=/opt/djangoprojects/reports # Django project directory
SOCKFILE=/opt/djangoprojects/reports/bin/gunicorn.sock # we will communicte using this unix socket
USER=reportsuser # the user to run as
GROUP=webapps # the group to run as
NUM_WORKERS=4 # how many worker processes should Gunicorn spawn
Django_SETTINGS_MODULE=reports.settings # which settings file should Django use
Django_WSGI_MODULE=reports.wsgi # WSGI module name
#echo "Starting $NAME as `whoami`"
# Activate the virtual environment
cd $DJANGODIR
source pythonenv/bin/activate
export Django_SETTINGS_MODULE=$Django_SETTINGS_MODULE
export PYTHONPATH=$DJANGODIR:$PYTHONPATH
# Create the run directory if it doesn't exist
RUNDIR=$(dirname $SOCKFILE)
test -d $RUNDIR || mkdir -p $RUNDIR
# Start your Django Unicorn
# Programs meant to be run under supervisor should not daemonize themselves (do not use --daemon)
exec gunicorn ${Django_WSGI_MODULE}:application \
--name $NAME \
--workers $NUM_WORKERS \
--user=$USER --group=$GROUP \
--log-level=debug \
--bind=unix:$SOCKFILE \
--error-logfile /opt/djangoprojects/reports/bin/gunicorn.errors \
--log-file /opt/djangoprojects/reports/bin/gunicorn.errors
より詳しい情報:
Sudo service reports start|stop|restart
を使用してコピーおよび変更したこのinit.dスクリプトで、gunicornを開始/停止しています:
>cat /etc/init.d/reports
#!/bin/sh
### BEGIN INIT INFO
# Provides: Django_gunicorn
# Required-Start: $local_fs $network $remote_fs
# Required-Stop: $local_fs $network $remote_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Starts Django_Unicorn reports at boot time.
# Description: Starts Django_Unicorn reports at boot time.
### END INIT INFO
name=`basename $0`
dir="/opt/djangoprojects/reports"
cmd="${dir}/bin/gunicorn_start"
pid_file="/var/run/$name.pid"
log_file="${dir}/bin/reports.log"
get_pid() {
cat "$pid_file"
}
is_running() {
[ -f "$pid_file" ] && ps `get_pid` > /dev/null 2>&1
}
case "$1" in
start)
if is_running; then
echo "Already running"
else
echo -n "Starting ${name}... "
cd "$dir"
#Sudo -u "$user" $cmd &>> "$log_file"
$cmd &>> "$log_file" &
echo $! > "$pid_file"
if ! is_running; then
echo "Unable to start; see $log_file"
exit 1
else
echo "[STARTED]"
fi
fi
;;
stop)
if is_running; then
echo -n "Stopping ${name}... "
kill `get_pid`
for i in {1..10}
do
if ! is_running; then
break
fi
echo -n "."
sleep 1
done
echo
if is_running; then
echo "Not stopped; may still be shutting down or shutdown may have failed"
exit 1
else
echo "[STOPPED]"
if [ -f "$pid_file" ]; then
rm "$pid_file"
fi
fi
else
echo "Not running"
fi
;;
restart)
$0 stop
if is_running; then
echo "Unable to stop, will not attempt to start"
exit 1
fi
$0 start
;;
status)
if is_running; then
echo "[RUNNING]"
else
echo "[STOPPED]"
exit 1
fi
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
exit 1
;;
esac
exit 0
あなたのコメントから、これはあなたのDjangoサイトの設定の問題であり、gunicornログの問題ではないと思います。ログはDjangoに送信した以上のものを表示しません。
Django設定を構成して、ログをファイルに送信する方法の例を次に示します(デフォルトでメールで管理者に送信するのではなく)。
LOGGING = {
'version': 1,
'disable_existing_loggers': True,
'formatters': {
'verbose': {
'format': '%(asctime)s %(levelname)s [%(name)s:%(lineno)s] %(module)s %(process)d %(thread)d %(message)s'
}
},
'handlers': {
'gunicorn': {
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler',
'formatter': 'verbose',
'filename': '/opt/djangoprojects/reports/bin/gunicorn.errors',
'maxBytes': 1024 * 1024 * 100, # 100 mb
}
},
'loggers': {
'gunicorn.errors': {
'level': 'DEBUG',
'handlers': ['gunicorn'],
'propagate': True,
},
}
}
ロギングの設定 の設定 (ログ設定オプションの非常に詳しい説明を提供します)を読み、ファイル を調べます。Django/ utils/log.py を設定して、Djangoロギンをgunicornログでより詳細に表示します。
また、 this answer と this も確認してください。ログエラーを送信するための設定例が提供されていますファイルに直接。また、 Sentry を使用してログエラーを処理することを検討してください recomended by Djangoみんな。
お役に立てれば。
これらは、デフォルトでmail_admins
を使用するloggers
です(Django/utils/log.py
を参照):
'Django.request': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': False,
},
'Django.security': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': False,
},
ハンドラーを変更してconsole
に移動し、mail_admins
でメールを送信するのではなく、gunicornログに表示されるようにする必要があります。 DEBUG=True
のときほどおしゃべりではないことに注意してください。
'loggers': {
'Django': {
'level': 'ERROR',
'handlers': ['console'],
},
}
mail_admins
経由でエラーを送信するまた、ロギングの設定に基づいて、mail_admins
;を呼び出すハンドラーを明示的に作成します。例えばDjango/utils/log.py
に基づく:
'handlers': {
'mail_admins': {
'level': 'ERROR',
'class': 'Django.utils.log.AdminEmailHandler'
},
},
'loggers': {
'Django': {
'handlers': ['mail_admins'],
},
}
これには、メール関連のsettings
を設定する必要があります。
ソリューション#1を探していなかった場合、質問は次の重複です: Djangoサイト)でサーバーエラーをログに記録する方法
以下のロギング構成では、DEBUGがFalseの場合でも、Gunicorn出力(非デーモン化)またはrunserverにエラーが表示され始めます。とにかく、DEBUGがTrueの場合に表示されます。
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'filters': {
'require_debug_false': {
'()': 'Django.utils.log.RequireDebugFalse',
},
'require_debug_true': {
'()': 'Django.utils.log.RequireDebugTrue',
},
},
'formatters': {
'Django.server': {
'()': 'Django.utils.log.ServerFormatter',
'format': '[%(server_time)s] %(message)s',
}
},
'handlers': {
'console': {
'level': 'INFO',
'filters': ['require_debug_true'],
'class': 'logging.StreamHandler',
},
# Custom handler which we will use with logger 'Django'.
# We want errors/warnings to be logged when DEBUG=False
'console_on_not_debug': {
'level': 'WARNING',
'filters': ['require_debug_false'],
'class': 'logging.StreamHandler',
},
'Django.server': {
'level': 'INFO',
'class': 'logging.StreamHandler',
'formatter': 'Django.server',
},
'mail_admins': {
'level': 'ERROR',
'filters': ['require_debug_false'],
'class': 'Django.utils.log.AdminEmailHandler'
}
},
'loggers': {
'Django': {
'handlers': ['console', 'mail_admins', 'console_on_not_debug'],
'level': 'INFO',
},
'Django.server': {
'handlers': ['Django.server'],
'level': 'INFO',
'propagate': False,
},
}
}
Djangoエラーをgunicornエラーログで確認するには、-capture-outputを指定してgunicornを実行します。
http://docs.gunicorn.org/en/stable/settings.html#capture-output
ログを記録する際には、2つの混乱があります。
runserver
がgunicorn
よりも優れたログを提供するかどうかsettings.DEBUG=True
はsettings.DEBUG=False
よりも優れたログを提供しますかrunserverで表示されるすべてのログレコードは、適切なログ設定がある限り、Gunicornでも表示できます。
DEBUG = Trueで表示されるすべてのログレコードは、適切なログ設定があればDEBUG = Falseでも表示できます。
デフォルトのDjangoロギング構成は次の場所にあります。
https://github.com/Django/django/blob/1.10.8/Django/utils/log.py#L18
それは次のようになります:(私はこの回答に関係のない部分を削除しました)
DEFAULT_LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'filters': {
'require_debug_false': {
'()': 'Django.utils.log.RequireDebugFalse',
},
'require_debug_true': {
'()': 'Django.utils.log.RequireDebugTrue',
},
},
'handlers': {
'console': {
'level': 'INFO',
'filters': ['require_debug_true'],
'class': 'logging.StreamHandler',
},
'mail_admins': {
'level': 'ERROR',
'filters': ['require_debug_false'],
'class': 'Django.utils.log.AdminEmailHandler'
}
},
'loggers': {
'Django': {
'handlers': ['console', 'mail_admins'],
'level': 'INFO',
},
}
}
これが言うことは:
Django
ロガーログレコードをハンドラーconsole
およびmail_admins
に送信します。
ハンドラーconsole
にはフィルターrequire_debug_true
があります。 settings.DEBUGがTrueの場合、ハンドラconsole
はストリームにログを送信/印刷します(logging.StreamHandler
のため)。
Settings.DEBUGがFalseの場合、ハンドラconsole
は、ロガーDjango
によってハンドラに送信されたログメッセージを無視します。
DEBUG = Falseでもログを印刷したい場合は、handler
を追加して、ロガーにDjango
を使用させます。
ハンドラーは次のようになります。
'console_on_not_debug': {
'level': 'WARNING',
'filters': ['require_debug_false'],
'class': 'logging.StreamHandler',
},
そして、このハンドラをロガーDjango
で使用します。
'Django': {
'handlers': ['console', 'mail_admins', 'console_on_not_debug'],
'level': 'INFO',
},
スニペット全体を短い回答で見ることができます。
これにより、runserverまたはgunicornを使用しているかどうかに関係なく、ログがストリームに出力されます。
ログをgunicornエラーログに表示する場合は、-capture-outputを指定してgunicornを実行する必要があります。
この構成でうまくいきました。追加 --capture-output --enable-stdio-inheritance
以下のようなgunicornコマンドを使用します。
/home/ubuntu/inside-env/bin/gunicorn --access-logfile /var/log/access_file_g.log --error-logfile /var/log/error_file_g.log --capture-output --enable-stdio-inheritance --workers 3 --bind unix:/home/ubuntu/path-to-project/webapp.sock project.wsgi:application
このセットアップでは、この方法でロギングを有効にします
import logging
logging.basicConfig(level='DEBUG')
logging.info('hello world')
このようにして、アプリ内のエラーも確認できます。
最も簡単な解決策は、変数[〜#〜] admins [〜#〜]を設定することです。エラー通知を受け取る必要があります。 DEBUG = Falseでビューが例外を発生させると、Djangoはこれらのユーザーに完全な例外情報をメールで送信します。
settings.py
ADMINS = (('John', '[email protected]'), ('Mary', '[email protected]'))
# or only ADMINS = (('John', '[email protected]'),)
正しいSMTPサーバーがポート25
でlocalhost
でない場合は、EMAIL_HostとEMAIL_PORTも必要になる可能性があります。この単純なソリューションは、試作運用には十分ですが、それ以外の場合、突然大量のメールを生成する可能性があります。