uWSGIを使ってNginxのアクセスログを収集してみる

Nginxはデフォルトで`/var/log/nginx/access.log`にアクセスログを作っているが、POSTで送信された内容は取得していないので、uWSGI & Python3.6を使ってデータをcsvに書き出してみる。

今回はNginxでリクエストボディを取得するところがメインなので、その他の準備はさらっと適当にやります。

環境
AmazonLinux2
Python3.6.4 ([Pythonの準備はコチラ](https://qiita.com/KosukeJin/items/9d5c4b6cb800e4d8c3ec))
※ポート80番使います



## この記事でやること
1. Nginx、uWSGIインストール
2. 適当なhtml作成
3. NginxとuWSGI連携(ここでPOST送れるようにする)
4. Pythonでcsv形式にして出力



## Nginxインストール
[この記事](https://dev.classmethod.jp/cloud/aws/install-nginx-on-amazon-linux2-from-extras-repository/)を参考にインストール。
AmazonLinux2はちょっと特殊みたい(ややハマり)

```
# インストール
sudo amazon-linux-extras install nginx1.12

# 起動
sudo systemctl start nginx.service

# 再起動時自動オン設定
sudo systemctl enable nginx.service
```
yum -> init.d -> chkconfigの時代は終わったのだろうか、、、
ブラウザからアクセスしてみる。OK
<img width="526" alt="スクリーンショット 2018-02-10 21.35.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/237293/ec211dc6-9bb5-e241-94e4-17e79d247cdc.png">



## uWSGIインストール
```
# 各自Python3になってる場所で置き換えてください
cd /home/ec2-user/py364_nginx_uwsgi

# uWSGI入れる
pip install uwsgi

pip freeze
# uWSGI==2.0.16 がいればOK 
```



## 適当なhtml作成
```
# ディレクトリとhtml作成
sudo mkdir -p /var/www/html
sudo chmod 777 /var/www/html
vim /var/www/html/index.html
```
```html:/var/www/html/index.html
<form action="http://サーバのIP/post/" method="POST">
    Name   : <input type="text" name="name" value="">
    Age    : <input type="text" name="age" value="">
    Comment: <input type="text" name="comment" value="">
    <input type="submit" value="Push!">
</form>
```



## Nginxの設定
```
# uWSGIへのパラメータにPOSTデータを追加
sudo vim /etc/nginx/uwsgi_params
```
```nginx:/etc/nginx/uwsgi_params
# 一番下に追記
uwsgi_param  REQUEST_BODY       $request_body;
```
```
# uWSGI用のホスト作成
sudo vim /etc/nginx/conf.d/html_test.conf
```
```nginx:/etc/nginx/conf.d/html_test.conf
server {
    server_name サーバのIP;
    listen      80;

    location / {
       root     /var/www/html/;
    }

    location /post/ {
        include    uwsgi_params;
        uwsgi_pass 127.0.0.1:8931;
    }
}
```
```
# 再起動(これを忘れて30分無駄にハマりました)
sudo systemctl restart nginx.service
```



# Pythonアプリ作成
```
# さっきuWSGIを入れたディレクトリ以下に作成
vim /home/ec2-user/py364_nginx_uwsgi/app.py
```
```python3:/home/ec2-user/py364_nginx_uwsgi/app.py
# uWSGIは'application'の名前で呼び出すっぽい
def application(env, start_response):

    # リクエストボディ取得
    body = env['REQUEST_BODY']

    # パラメータがA1文字ずつのリストになっているので整形する
    body = ''.join(body).split('&')
    body = [(x.split('=')) for x in body]

    # csv形式の文字列に変換
    line = ','.join(list(map(lambda x: x[1], body)))
    
    # ファイルに出力(app.pyと同じディレクトリにできる)
    with open('postdata.log', 'a') as f:
        f.write(line+'\n')

    start_response('200 OK', [('Content-Type','text/html')])
    return b'write ok!'
```



## uWSGIを起動してテスト
```
# Pythonアプリのある場所へ移動
cd /home/ec2-user/py364_nginx_uwsgi/

# コマンドで起動(Ctrl + cで停止)
uwsgi --socket 127.0.0.1:8931 --wsgi-file app.py
```

ブラウザから開いてみる。
<img width="662" alt="スクリーンショット 2018-02-11 0.33.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/237293/303799dc-d5ba-7ed7-1a13-6e07aaca2e5d.png">
適当な値を入力して「Push!」
<img width="77" alt="スクリーンショット 2018-02-11 0.33.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/237293/58c085e0-8fee-44a8-a468-64fbe16faa69.png">
成功メッセージが返ってきた。

次はログができているか確認。
(Ctrl + cでuWSGIを止めてから)

```
less postdata.log
```

<img width="247" alt="スクリーンショット 2018-02-11 0.37.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/237293/6fc3b885-527f-72c3-ffa8-f5c27378e942.png">
ファイル出力もOK。



## まとめ
これくらいの細かい作業ならDjango的なフレームワークなしでも実現可能だとわかった。
ファイル作成以外にも、データをDBに突っ込みたいだけとかのときに使える。

Nginxの変数はいろいろと選べるので、これ以外に探しても面白いかもしれない。
[公式?](http://mogile.web.fc2.com/nginx/varindex.html)を見たら死ぬほどあった。これは覚えられないw

NginxやuWSGIの細かい話については後日記事を書く予定なのでそのときにリンク追加しておきます。

以上、お疲れ様でした。