最近はISUCONの過去問を解いています。今回はnotify_slackを利用してalpの集計結果をSlackで通知する方法をまとめます。
以下の流れで説明していきます。
notify_slackを利用してテキストをSlackで通知する
notify_slackのインストール
Releases · catatsuy/notify_slack · GitHub からバイナリファイルを落としてくる
# wget https://github.com/catatsuy/notify_slack/releases/download/v0.4.8/notify_slack-linux-amd64.tar.gz # tar zxvf notify_slack-linux-amd64.tar.gz # ./notify_slack -version notify_slack version v0.4.8; go1.15.6
Go1.15以上の環境があるならgit cloneしてmakeでもOK
# git clone https://github.com/catatsuy/notify_slack.git # cd notify_slack/ # make # ./notify_slack -version notify_slack version v0.4.8; go1.15.6
Slackアプリの作成
notify_slackのREADMEに書かれているので、これに則ってSlackアプリを作成し、通知したいチャンネルに追加する。
https://github.com/catatsuy/notify_slack#how-to-create-a-token
notify_slackの設定ファイルの作成
https://github.com/catatsuy/notify_slack#toml-configuration-file を参考に以下のようなnotify_slack.toml
を作成する。
[slack] url = "https://hooks.slack.com/services/**" token = "xoxp-xxxxx" channel = "#general" username = "tester" icon_emoji = ":rocket:" interval = "1s"
各パラメータの意味は https://github.com/catatsuy/notify_slack#cli-options を参照してください。
作成した設定ファイルは以下のように実行時に-c
オプションで指定するか、
# ./notify_slack -c notify_slack.toml
もしくは、以下のディレクトリに配置しておけば自動的に読み込んでくれる
$HOME/.notify_slack.toml
$HOME/etc/notify_slack.toml
/etc/notify_slack.toml
動作確認
# echo a | ./notify_slack -c notify_slack.toml
↑これを実行すると、Slackにテキストが投稿される。
alpの集計結果をhtmlファイルとして配信する
alpのインストール
Releases · tkuchiki/alp · GitHub からバイナリファイルを落としてくる
# wget https://github.com/tkuchiki/alp/releases/download/v1.0.3/alp_linux_amd64.zip # unzip alp_linux_amd64.zip # ./alp --version 1.0.3
ログ形式をLTSV形式に変更
alpでログを集計するために、nginxのアクセスログの形式をLTSV形式に変更する。
# vim /etc/nginx/nginx.conf // 中略 // 以下を追加 log_format ltsv "time:$time_local" "\thost:$remote_addr" "\tforwardedfor:$http_x_forwarded_for" "\treq:$request" "\tstatus:$status" "\tmethod:$request_method" "\turi:$request_uri" "\tsize:$body_bytes_sent" "\treferer:$http_referer" "\tua:$http_user_agent" "\treqtime:$request_time" "\tcache:$upstream_http_x_cache" "\truntime:$upstream_http_x_runtime" "\tapptime:$upstream_response_time" "\tvhost:$host"; access_log /var/log/nginx/access.log ltsv; // 中略
設定が完了したら、設定ファイルの文法チェック
# nginx -t
問題がなければnginxの設定ファイルを再読み込みする
# nginx -s reload
alpでログを集計してみる
ベンチマーク実行後、アクセスログをalpで集計してみる。 今回はISUCON9予選の過去問をやっていたので、alpのオプションでエンドポイントをまとめて集計するような指定をしている。
# ./bin/benchmarker # cat /var/log/nginx/access.log |./alp ltsv -m "/upload/[0-9a-z]+.jpg,/items/[0-9]+.json,/new_items/[0-9]+.json,/users/[0-9]+.json,/transactions/[0-9]+.png,/static/*" +-------+-----+------+-----+-----+-----+--------+------------------------------+-------+-------+---------+-------+-------+-------+-------+--------+-----------+------------+--------------+------------+ | COUNT | 1XX | 2XX | 3XX | 4XX | 5XX | METHOD | URI | MIN | MAX | SUM | AVG | P1 | P50 | P99 | STDDEV | MIN(BODY) | MAX(BODY) | SUM(BODY) | AVG(BODY) | +-------+-----+------+-----+-----+-----+--------+------------------------------+-------+-------+---------+-------+-------+-------+-------+--------+-----------+------------+--------------+------------+ | 1 | 0 | 1 | 0 | 0 | 0 | GET | /logo.png | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 23082.000 | 23082.000 | 23082.000 | 23082.000 | | 1 | 0 | 0 | 0 | 1 | 0 | GET | /aaaa | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 19.000 | 19.000 | 19.000 | 19.000 | | 1 | 0 | 0 | 0 | 1 | 0 | GET | /health | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 19.000 | 19.000 | 19.000 | 19.000 | | 1 | 0 | 1 | 0 | 0 | 0 | POST | /register | 0.088 | 0.088 | 0.088 | 0.088 | 0.088 | 0.088 | 0.088 | 0.000 | 70.000 | 70.000 | 70.000 | 70.000 | | 1 | 0 | 0 | 1 | 0 | 0 | GET | /logs/index.html | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | | 2 | 0 | 2 | 0 | 0 | 0 | GET | /reports.json | 0.008 | 0.008 | 0.016 | 0.008 | 0.008 | 0.008 | 0.008 | 0.000 | 87837.000 | 105839.000 | 193676.000 | 96838.000 | | 2 | 0 | 0 | 0 | 2 | 0 | GET | /logs/test | 0.004 | 0.004 | 0.004 | 0.002 | 0.000 | 0.000 | 0.000 | 0.002 | 19.000 | 564.000 | 583.000 | 291.500 | | 2 | 0 | 0 | 0 | 2 | 0 | GET | /_status/vars | 0.000 | 0.004 | 0.004 | 0.002 | 0.004 | 0.004 | 0.004 | 0.002 | 19.000 | 19.000 | 38.000 | 19.000 | | 2 | 0 | 2 | 0 | 0 | 0 | POST | /initialize | 6.980 | 7.300 | 14.280 | 7.140 | 6.980 | 6.980 | 6.980 | 0.160 | 31.000 | 31.000 | 62.000 | 31.000 | | 2 | 0 | 0 | 0 | 2 | 0 | GET | /logs/test.html | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 19.000 | 564.000 | 583.000 | 291.500 | | 2 | 0 | 0 | 0 | 2 | 0 | GET | /actuator/prometheus | 0.000 | 0.032 | 0.032 | 0.016 | 0.032 | 0.032 | 0.032 | 0.016 | 19.000 | 19.000 | 38.000 | 19.000 | | 2 | 0 | 0 | 0 | 2 | 0 | GET | /manager/status | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 19.000 | 19.000 | 38.000 | 19.000 | | 2 | 0 | 0 | 0 | 2 | 0 | GET | /squid-internal-mgr/counters | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 166.000 | 166.000 | 332.000 | 166.000 | | 2 | 0 | 0 | 0 | 2 | 0 | - | - | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 166.000 | 166.000 | 332.000 | 166.000 | | 4 | 0 | 0 | 0 | 4 | 0 | GET | /metrics | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 19.000 | 19.000 | 76.000 | 19.000 | | 5 | 0 | 0 | 0 | 5 | 0 | GET | /favicon.ico | 0.000 | 0.004 | 0.004 | 0.001 | 0.000 | 0.004 | 0.000 | 0.002 | 19.000 | 19.000 | 95.000 | 19.000 | | 6 | 0 | 6 | 0 | 0 | 0 | GET | /favicon.png | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 176.000 | 176.000 | 1056.000 | 176.000 | | 8 | 0 | 8 | 0 | 0 | 0 | GET | / | 0.000 | 0.016 | 0.020 | 0.003 | 0.004 | 0.000 | 0.016 | 0.005 | 2037.000 | 2037.000 | 16296.000 | 2037.000 | | 8 | 0 | 7 | 1 | 0 | 0 | GET | /logs/alp.html | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 0.000 | 8517.000 | 59190.000 | 7398.750 | | 10 | 0 | 0 | 0 | 10 | 0 | GET | /logs | 0.000 | 0.004 | 0.004 | 0.000 | 0.000 | 0.000 | 0.000 | 0.001 | 19.000 | 564.000 | 2915.000 | 291.500 | | 11 | 0 | 11 | 0 | 0 | 0 | GET | /static/* | 0.008 | 0.216 | 1.032 | 0.094 | 0.004 | 0.024 | 0.008 | 0.087 | 994.000 | 508459.000 | 1802458.000 | 163859.818 | | 17 | 0 | 6 | 0 | 11 | 0 | POST | /items/edit | 0.000 | 0.024 | 0.120 | 0.007 | 0.008 | 0.020 | 0.004 | 0.008 | 58.000 | 93.000 | 1191.000 | 70.059 | | 26 | 0 | 26 | 0 | 0 | 0 | POST | /bump | 0.004 | 0.616 | 1.384 | 0.053 | 0.024 | 0.016 | 0.028 | 0.131 | 90.000 | 92.000 | 2366.000 | 91.000 | | 40 | 0 | 39 | 0 | 1 | 0 | POST | /complete | 0.004 | 0.880 | 27.613 | 0.690 | 0.024 | 0.880 | 0.808 | 0.290 | 34.000 | 34.000 | 1326.000 | 33.150 | | 68 | 0 | 46 | 0 | 22 | 0 | GET | /transactions/[0-9]+.png | 0.004 | 0.024 | 0.148 | 0.002 | 0.004 | 0.000 | 0.000 | 0.004 | 33.000 | 623.000 | 29065.000 | 427.426 | | 72 | 0 | 50 | 0 | 22 | 0 | POST | /ship | 0.812 | 0.836 | 36.184 | 0.503 | 0.000 | 0.812 | 0.812 | 0.394 | 29.000 | 61.000 | 3776.000 | 52.444 | | 79 | 0 | 45 | 0 | 34 | 0 | POST | /ship_done | 0.004 | 0.860 | 39.544 | 0.501 | 0.008 | 0.808 | 0.812 | 0.391 | 29.000 | 83.000 | 3169.000 | 40.114 | | 102 | 0 | 52 | 0 | 50 | 0 | POST | /buy | 0.004 | 1.684 | 95.174 | 0.933 | 0.008 | 1.616 | 0.996 | 0.787 | 0.000 | 49.000 | 3541.000 | 34.716 | | 103 | 0 | 67 | 0 | 36 | 0 | POST | /sell | 0.020 | 0.852 | 9.632 | 0.094 | 0.000 | 0.012 | 0.000 | 0.172 | 13.000 | 106.000 | 3763.000 | 36.534 | | 113 | 0 | 113 | 0 | 0 | 0 | GET | /settings | 0.000 | 0.520 | 12.944 | 0.115 | 0.004 | 0.000 | 0.012 | 0.136 | 2799.000 | 2953.000 | 331583.000 | 2934.363 | | 121 | 0 | 105 | 0 | 16 | 0 | POST | /login | 0.068 | 0.908 | 47.844 | 0.395 | 0.472 | 0.072 | 0.084 | 0.258 | 73.000 | 107.000 | 11449.000 | 94.620 | | 233 | 0 | 1 | 220 | 12 | 0 | GET | /logs/ | 0.000 | 0.004 | 0.032 | 0.000 | 0.000 | 0.000 | 0.000 | 0.001 | 13.000 | 564.000 | 4056.000 | 17.408 | | 248 | 0 | 248 | 0 | 0 | 0 | GET | /upload/[0-9a-z]+.jpg | 0.000 | 0.068 | 2.260 | 0.009 | 0.004 | 0.016 | 0.000 | 0.012 | 51480.000 | 150881.000 | 19921321.000 | 80327.907 | | 263 | 0 | 262 | 0 | 1 | 0 | GET | /new_items.json | 0.040 | 1.216 | 95.107 | 0.362 | 0.056 | 0.052 | 0.052 | 0.247 | 0.000 | 23728.000 | 6131659.000 | 23314.293 | | 323 | 0 | 304 | 0 | 19 | 0 | GET | /users/transactions.json | 0.020 | 6.780 | 920.902 | 2.851 | 0.220 | 2.138 | 1.667 | 1.756 | 0.000 | 29240.000 | 6247445.000 | 19341.935 | | 533 | 0 | 533 | 0 | 0 | 0 | GET | /users/[0-9]+.json | 0.012 | 1.800 | 104.540 | 0.196 | 0.216 | 0.080 | 0.032 | 0.175 | 94.000 | 24033.000 | 7384995.000 | 13855.525 | | 1429 | 0 | 1429 | 0 | 0 | 0 | GET | /new_items/[0-9]+.json | 0.020 | 2.380 | 331.060 | 0.232 | 1.344 | 0.088 | 0.188 | 0.202 | 22666.000 | 24058.000 | 33558952.000 | 23484.221 | | 4501 | 0 | 4501 | 0 | 0 | 0 | GET | /items/[0-9]+.json | 0.004 | 0.548 | 21.088 | 0.005 | 0.028 | 0.000 | 0.004 | 0.013 | 1828.000 | 4326.000 | 9918458.000 | 2203.612 | +-------+-----+------+-----+-----+-----+--------+------------------------------+-------+-------+---------+-------+-------+-------+-------+--------+-----------+------------+--------------+------------+
集計したログのhtmlファイルを作成
アクセスログの集計結果をブラウザから見れるようにするために、htmlファイルを作成する
# mkdir -p /www/data/logs # echo "<html><body><pre style=\"font-family: 'Courier New', Consolas\">" > /www/data/logs/alp.html # cat /var/log/nginx/access.log | ./alp ltsv -m "/upload/[0-9a-z]+.jpg,/items/[0-9]+.json,/new_items/[0-9]+.json,/users/[0-9]+.json,/transactions/[0-9]+.png,/static/*" >> /www/data/logs/alp.html
静的ファイルの配信設定
作成したhtmlファイルをローカルのブラウザから確認できるようにするためnginxの設定を変更する。
# vim /etc/nginx/nginx/conf // 中略 // 以下のように/logs/xxxx.htmlでアクセスできるようにしておく server { listen 8080; location / { proxy_pass http://localhost:8000; } location /logs/ { root /www/data; index alp.html; } } // 中略
設定が完了したらnginxの設定ファイルを再読み込みする
# nginx -t # nginx -s reload
動作確認
ローカルのブラウザからhttp://<nginxが起動しているIPアドレス>:8080/logs/alp.html
にアクセスすると、集計結果が表示されている。
notify_slackを利用してhtmlファイルをSlackに通知する
最後にnotify_slackを使ってhttp://<nginxが起動しているIPアドレス>:8080/logs/alp.html
をslackに通知する。
# echo "http://172.28.128.3:8080/logs/alp.html" | ./notify_slack -c notify_slack.toml