新年あけましておめでとうございます。 年末にかかった風邪がようやく治りかけてきたので、isucon本で気になるところを手元で試したりしています。
こちらの本、トップレビューは酷評されてますが、isucon対策本として読むには面白かったです。alp
本書で紹介されているalpが非常に良いです。
アクセスログをコマンド1発で集計してくれる優れものです。
昔はawkとか使って集計してましたよね。便利。
使い方
# nginx の log_formatをjsonで出力 log_format json escape=json '{"time": "$time_iso8601",' '"host": "$remote_addr",' '"port": "$remote_port",' '"method": "$request_method",' '"uri": "$request_uri",' '"status": "$status",' '"body_bytes": "$body_bytes_sent",' '"referer": "$http_referer",' '"ua": "$http_user_agent",' '"request_time": "$request_time",' '"apptime": "$upstream_response_time"}';
# ログの例 {"time": "2023-01-01T11:48:37+00:00","host": "172.18.0.1","port": "61388","method": "GET","uri": "/","status": "200","body_bytes": "35624","referer": "","ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36","request_time": "10.961","apptime": "10.963"} ...
こんな感じで簡単に解析してくれます。
$ cat logs/nginx/access.log | alp json +-------+-----+-----+-----+-----+-----+--------+------------------+--------+--------+--------+--------+--------+--------+--------+--------+-------------+-------------+-------------+-------------+ | COUNT | 1XX | 2XX | 3XX | 4XX | 5XX | METHOD | URI | MIN | MAX | SUM | AVG | P90 | P95 | P99 | STDDEV | MIN(BODY) | MAX(BODY) | SUM(BODY) | AVG(BODY) | +-------+-----+-----+-----+-----+-----+--------+------------------+--------+--------+--------+--------+--------+--------+--------+--------+-------------+-------------+-------------+-------------+ | 1 | 0 | 1 | 0 | 0 | 0 | GET | / | 10.961 | 10.961 | 10.961 | 10.961 | 10.961 | 10.961 | 10.961 | 0.000 | 35624.000 | 35624.000 | 35624.000 | 35624.000 | | 1 | 0 | 1 | 0 | 0 | 0 | GET | /image/10000.png | 0.088 | 0.088 | 0.088 | 0.088 | 0.088 | 0.088 | 0.088 | 0.000 | 1056749.000 | 1056749.000 | 1056749.000 | 1056749.000 | | 1 | 0 | 1 | 0 | 0 | 0 | GET | /image/9998.jpg | 0.082 | 0.082 | 0.082 | 0.082 | 0.082 | 0.082 | 0.082 | 0.000 | 61656.000 | 61656.000 | 61656.000 | 61656.000 | | 1 | 0 | 1 | 0 | 0 | 0 | GET | /image/9995.jpg | 0.101 | 0.101 | 0.101 | 0.101 | 0.101 | 0.101 | 0.101 | 0.000 | 123364.000 | 123364.000 | 123364.000 | 123364.000 | | 1 | 0 | 1 | 0 | 0 | 0 | GET | /image/9997.jpg | 0.116 | 0.116 | 0.116 | 0.116 | 0.116 | 0.116 | 0.116 | 0.000 | 176404.000 | 176404.000 | 176404.000 | 176404.000 | | 1 | 0 | 1 | 0 | 0 | 0 | GET | /image/9996.jpg | 0.138 | 0.138 | 0.138 | 0.138 | 0.138 | 0.138 | 0.138 | 0.000 | 374805.000 | 374805.000 | 374805.000 | 374805.000 | | 1 | 0 | 1 | 0 | 0 | 0 | GET | /image/9999.jpg | 0.146 | 0.146 | 0.146 | 0.146 | 0.146 | 0.146 | 0.146 | 0.000 | 89928.000 | 89928.000 | 89928.000 | 89928.000 | | 1 | 0 | 1 | 0 | 0 | 0 | GET | /image/9994.jpg | 0.068 | 0.068 | 0.068 | 0.068 | 0.068 | 0.068 | 0.068 | 0.000 | 105154.000 | 105154.000 | 105154.000 | 105154.000 | | 1 | 0 | 1 | 0 | 0 | 0 | GET | /image/9993.jpg | 0.055 | 0.055 | 0.055 | 0.055 | 0.055 | 0.055 | 0.055 | 0.000 | 85546.000 | 85546.000 | 85546.000 | 85546.000 | | 1 | 0 | 1 | 0 | 0 | 0 | GET | /image/9991.jpg | 0.067 | 0.067 | 0.067 | 0.067 | 0.067 | 0.067 | 0.067 | 0.000 | 153465.000 | 153465.000 | 153465.000 | 153465.000 | | 1 | 0 | 1 | 0 | 0 | 0 | GET | /image/9990.jpg | 0.066 | 0.066 | 0.066 | 0.066 | 0.066 | 0.066 | 0.066 | 0.000 | 102371.000 | 102371.000 | 102371.000 | 102371.000 | | 1 | 0 | 1 | 0 | 0 | 0 | GET | /image/9989.jpg | 0.048 | 0.048 | 0.048 | 0.048 | 0.048 | 0.048 | 0.048 | 0.000 | 107460.000 | 107460.000 | 107460.000 | 107460.000 | | 1 | 0 | 1 | 0 | 0 | 0 | GET | /image/9988.jpg | 0.063 | 0.063 | 0.063 | 0.063 | 0.063 | 0.063 | 0.063 | 0.000 | 111515.000 | 111515.000 | 111515.000 | 111515.000 | | 1 | 0 | 1 | 0 | 0 | 0 | GET | /image/9987.jpg | 0.086 | 0.086 | 0.086 | 0.086 | 0.086 | 0.086 | 0.086 | 0.000 | 367388.000 | 367388.000 | 367388.000 | 367388.000 | | 1 | 0 | 1 | 0 | 0 | 0 | GET | /image/9986.jpg | 0.094 | 0.094 | 0.094 | 0.094 | 0.094 | 0.094 | 0.094 | 0.000 | 86624.000 | 86624.000 | 86624.000 | 86624.000 | | 1 | 0 | 1 | 0 | 0 | 0 | GET | /image/9985.jpg | 0.093 | 0.093 | 0.093 | 0.093 | 0.093 | 0.093 | 0.093 | 0.000 | 83264.000 | 83264.000 | 83264.000 | 83264.000 | | 1 | 0 | 1 | 0 | 0 | 0 | GET | /image/9983.jpg | 0.093 | 0.093 | 0.093 | 0.093 | 0.093 | 0.093 | 0.093 | 0.000 | 98082.000 | 98082.000 | 98082.000 | 98082.000 | | 1 | 0 | 1 | 0 | 0 | 0 | GET | /image/9982.jpg | 0.087 | 0.087 | 0.087 | 0.087 | 0.087 | 0.087 | 0.087 | 0.000 | 149874.000 | 149874.000 | 149874.000 | 149874.000 | | 1 | 0 | 1 | 0 | 0 | 0 | GET | /image/9981.jpg | 0.077 | 0.077 | 0.077 | 0.077 | 0.077 | 0.077 | 0.077 | 0.000 | 81386.000 | 81386.000 | 81386.000 | 81386.000 | | 1 | 0 | 1 | 0 | 0 | 0 | GET | /image/9980.jpg | 0.037 | 0.037 | 0.037 | 0.037 | 0.037 | 0.037 | 0.037 | 0.000 | 95919.000 | 95919.000 | 95919.000 | 95919.000 | | 1 | 0 | 1 | 0 | 0 | 0 | GET | /image/9979.jpg | 0.040 | 0.040 | 0.040 | 0.040 | 0.040 | 0.040 | 0.040 | 0.000 | 66941.000 | 66941.000 | 66941.000 | 66941.000 | +-------+-----+-----+-----+-----+-----+--------+------------------+--------+--------+--------+--------+--------+--------+--------+--------+-------------+-------------+-------------+-------------+
使い方の詳細
ここに詳細が記載されていますが、フィルターやマージも可能です。GETだけとか、特定日以降とかでも絞れます。
alp/usage_samples.md at main · tkuchiki/alp
以下、日時でフィルターして、画像をひとまとめにする例。
$ cat logs/nginx/access.log | alp json -m "/image/*" --filters "Time > '2023-01-01T11:48:36+00:00'" +-------+-----+-----+-----+-----+-----+--------+----------+--------+--------+--------+--------+--------+--------+--------+--------+-----------+-------------+-------------+------------+ | COUNT | 1XX | 2XX | 3XX | 4XX | 5XX | METHOD | URI | MIN | MAX | SUM | AVG | P90 | P95 | P99 | STDDEV | MIN(BODY) | MAX(BODY) | SUM(BODY) | AVG(BODY) | +-------+-----+-----+-----+-----+-----+--------+----------+--------+--------+--------+--------+--------+--------+--------+--------+-----------+-------------+-------------+------------+ | 1 | 0 | 1 | 0 | 0 | 0 | GET | / | 10.961 | 10.961 | 10.961 | 10.961 | 10.961 | 10.961 | 10.961 | 0.000 | 35624.000 | 35624.000 | 35624.000 | 35624.000 | | 20 | 0 | 20 | 0 | 0 | 0 | GET | /image/* | 0.037 | 0.146 | 1.645 | 0.082 | 0.116 | 0.138 | 0.146 | 0.028 | 61656.000 | 1056749.000 | 3577895.000 | 178894.750 | +-------+-----+-----+-----+-----+-----+--------+----------+--------+--------+--------+--------+--------+--------+--------+--------+-----------+-------------+-------------+------------+
補足
本書には、集計に利用するJSONキーとして、以下が必要と記載されてました。
method, uri, status, body_bytes, response_time
キー名が異なる場合は、optionで設定可能です。
ただ、ドキュメントのどこにも見当たらなかったので、ソースを見てみると、確かにそれっぽいことをやっていました。
alp/alp.go at main · tkuchiki/alp