Django x gunicorn x supervisor 環境で New Relic を利用する

※ この内容は2013年7月にメモしてほったらかしていたものです。なのでちょっと内容が古いかもしれません

AWSで利用している場合は Standard が無料で使えるらしいので、使ってみる。

ちゃんと Python アプリケーション用のライブラリも用意してあるし、 ドキュメントの量も結構多いので、よさげな感はある。

New Relic アカウントを取得する

/aws/ と そうじゃないところがあるけど、違いがよくわからない。 どっちでとっても同じなんじゃないかと思う。

Python ライブラリを設定する

https://newrelic.com/docs/python/python-agent-quick-start

ほぼここのとおり

pip install

pip install newrelic

iniファイルの生成

supervisor で管理しているプロセスは、 gunicorn と celery の2つなので、2つ分作成してみる

newrelic-admin generate-config LICENSE_KEY PROJECT_DIR/newrelic-celeryd.ini
newrelic-admin generate-config LICENSE_KEY PROJECT_DIR/newrelic-gunicon.ini

iniファイルを編集

app_nameを任意のものに変更する。 「;」で区切るとグループとして扱える(?)らしいので、 celeryd と gunicorn で2つの app_name を設定してみることに

celery

vim PROJECT_DIR/newrelic-celeryd.ini
...
app_name = Awesome App (Celeryd); Awesome App
...

gunicorn用

vim PROJECT_DIR/newrelic-gunicorn.ini
...
app_name = Awesome App (Django); Awesome App
...

テスト

いちおうやっておく

newrelic-admin validate-config PROJECT_DIR/newrelic-celeryd.ini
newrelic-admin validate-config PROJECT_DIR/newrelic-gunicorn.ini

supervisord.confを設定する

supervisorを利用しているので、設定ファイルをいじる

vim PROJECT_DIR/supervisord.conf

command にまんま起動コマンドを記述したら spawnerr: can't find command とかで怒られるので 環境変数部分は environment で設定するようにする

newrelic-admin コマンドもフルパスじゃないとうまく起動できなかったので、 環境変数に設定して environ 経由で渡すようにする

具体的には /etc/profile.d/<PROJECT_NAME>.sh を設置して、 NEW_RELIC_ADMIN_COMMAND 変数を設定するようにした

/etc/profile.d/<PROJECT_NAME>.sh

export NEW_RELIC_ADMIN_COMMAND=/home/

<PROJECT_DIR>/PROJECT_DIR/supervisord.conf

[program:gunicorn]
command={{ environ.NEW_RELIC_ADMIN_COMMAND }} run-program {{ PYTHON }} {{ PROJECT_DIR }}/manage.py run_gunicorn --bind='unix:{{PROJECT_DIR}}/PROJECT_DIR/tmp/sockets/gunicorn-PROJECT_NAME.sock' --pid={{PROJECT_DIR}}/PROJECT_DIR/tmp/pids/gunicorn-PROJECT_NAME.pid
autostart=true
autorestart=true
redirect_stderr=true
environment=NEW_RELIC_CONFIG_FILE={{PROJECT_DIR}}/PROJECT_NAME/newrelic.ini

[program:celeryd]
command={{ environ.NEW_RELIC_ADMIN_COMMAND }} run-program {{ PYTHON }} {{ PROJECT_DIR }}/manage.py celery worker --pid={{PROJECT_DIR}}/PROJECT_DIR/tmp/pids/celeryd-PROJECT_NAME.pid --logfile={{ PROJECT_DIR }}/PROJECT_DIR/logs/celeryd.log
autostart=true
autorestart=true
redirect_stderr=true
environment=NEW_RELIC_CONFIG_FILE={{PROJECT_DIR}}/PROJECT_DIR/newrelic.ini

[program:autoreload]
exclude=true

[supervisord]
logfile={{ PROJECT_DIR }}/PROJECT_DIR/logs/supervisord.log
pidfile={{PROJECT_DIR}}/PROJECT_DIR/tmp/pids/supervisord-PROJECT_NAME.pid

起動

python manage.py supervisor --config-file=PROJECT_DIR/supervisord.conf -d

その他

環境毎に設定を上書きする

https://newrelic.com/docs/python/python-agent-configuration#agent-configuration-file

素直に設定したままだとステージング環境とかのデータまで混入してしまう。

それを避けるために 環境毎の section で上書き設定を定義して、 環境変数 NEW_RELIC_ENVICONMENT をセットするようにするといろいろ捗る

例えば、ステージング環境だけ、別の app_name で記録したい場合、 前述の newrelic-gunicorn.ini に以下のように追記する

[newrelic:staging]
app_name = Awesome App(Staging) (Django); Awesome App(Staging)

.bash_profile とかに以下を追記

export NEW_RELIC_ENVICONMENT=staging

これでステージング環境で実行される gunicorn プロセスは 「Awesome App(Staging) (Django)」として記録されるようになる。