この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
先日行われたre:Invent 2016で発表されたAmazon Athenaを利用して、Apache HTTP Serverのアクセスログを解析するまでの手順を紹介します。
Athenaで検索するためには、ログファイルをAmazon S3に配置しておく必要があります。LinuxからS3への転送にはfluentd(td-agent)を利用しました。
やりたいこと
Amazon Athenaを利用して、Apacheアクセスログ(combined log)に対しての検索クエリを実行できるようになりたい
前提環境
- LinuxはAmazon EC2のRedHat Enterprise Linux 7.3 AMIから起動
- EC2には、S3にPutObjectできる権限を持ったIAM Roleを紐付けておく
- Amazon Athenaはus-west-2(Oregon)リージョンで実行
手順概要
- OS側セットアップ
- Athena側セットアップ
- クエリ実行
OS側セットアップ
まずは、Linuxにtd-agentとApacheをインストールします。
$ sudo yum install httpd
$ curl -L https://toolbelt.treasuredata.com/sh/install-redhat-td-agent2.sh | sh
インストールしたままの状態だと、 td-agent
ユーザがApacheのアクセスログを読めないので、ディレクトリのパーミッション変更と td-agent
ユーザのグループ追加を行います。
$ sudo usermod -a -G apache td-agent
$ sudo chown apache:apache /var/log/httpd/
$ sudo chmod g+rx /var/log/httpd
td-agent.confは以下のとおりです。バケット名(s3_bucket
)やPrefix(path
)のパラメータはご自由に調整下さい。
<source>
type tail
path "/var/log/httpd/access_log"
pos_file "/var/log/td-agent/access_log.pos"
tag log.access
format apache2
</source>
<match log.access>
type s3
s3_bucket <bucket_name>
path "athena_apache/"
s3_object_key_format %{path}%{time_slice}/access_%{index}.%{file_extension}
buffer_path /var/log/td-agent/s3/access
time_slice_format year=%Y/month=%m/day=%d/hour=%H/minute=%M
time_slice_wait 10s
utc
buffer_chunk_limit 64m
format json
include_time_key true
time_key log_time
</match>
ポイントは time_slice_format
パラメータに、Amazon Athenaでパーティション定義をするためのラベリングをしている点です。Athenaにおけるパーティションの詳しい説明は以下ブログを参照下さい。
- S3のデータをAmazon Athenaを使って分析する | Amazon Web Services ブログ
- Amazon Athenaのパーティションを理解する #reinvent | Developers.IO
あとはtd-agentとApacheを起動すれば、OS側の設定は完了です。
$ sudo systemctl enable td-agent
$ sudo systemctl start td-agent
$ sudo systemctl enable httpd
$ sudo systemctl start httpd
設定に成功していると、アクセスログがS3に以下のような形で出力されてきます。
{"host":"192.0.2.233","user":null,"method":"GET","path":"/index.html","code":200,"size":10,"referer":null,"agent":"Go-http-client/1.1","log_time":"2016-12-21T06:08:21Z"}
Athena側設定
AWS管理コンソールのAthena画面を開きます。前述のとおり、今回はオレゴンリージョンで試行しています。
Athenaでのテーブルはウィザードで作ることもできますが、今回はサンプルをベースにDDLを作成してそれを実行しました。以下のSQLをウィンドウに貼り付け、実行します。
まずはデータベースの作成です。
CREATE DATABASE IF NOT EXISTS access_table;
続いてテーブルを作成します。
CREATE EXTERNAL TABLE IF NOT EXISTS access_table.apache_access (
`host` string,
`user` string,
`log_time` string,
`method` string,
`path` string,
`code` int,
`size` int,
`referer` string,
`agent` string
)
PARTITIONED BY (
year int,
month int,
day int,
hour int,
minute int
)
ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
WITH serdeproperties ( 'paths'='host, user, log_time, method, path, code, size, referer, agent' )
LOCATION 's3://<bucket_name>/athena_apache/';
パーティションの定義に、先ほど td-agent.conf
の紹介の際に触れた time_slice_format
の値を入力しておきます。 LOCATION
の値も td-agent.conf
で設定した出力先と合うように設定しましょう。
テーブル作成が完了したら、データをロードします。以下のステートメントを実行して下さい。
MSCK REPAIR TABLE access_table.apache_access;
ここまで成功したら、完了です。
動作確認
実際にクエリを流して、データが入っているか確認してみましょう。
SELECT * from access_table.apache_access LIMIT 10;
実行すると、アクセスログが入っていることが確認できます。
もう少し複雑な集計クエリも流してみましょう。
SELECT host, count(*) FROM apache_access
where log_time < '2016-12-21T06:14:05Z'
and log_time > '2016-12-21T06:14:00Z'
group by host;
ある一定期間内のリクエスト数をIPアドレス毎に表示するクエリです。
こちらも問題なく結果が出せました!今回はテスト用のサーバで実験したので結果が寂しいですが、本番稼働しているサーバのアクセスログを読ませれば、もっと興味深い値が出ると思います。
つまづいた場所
Athenaを触るのが初めてで、Hiveにも触れたことがなかったのでテーブル定義を作成するのに一番苦労しました。特にPARTITIONのところはつまづきました。今回は分単位でPARTITIONを作成しましたが、この粒度についてはもう少し検討が必要だと思います。それは個人的な今後の宿題です。
まとめ
多少のつまづきはありましたが、かなり簡単にApacheのアクセスログをAthenaで出力することができました!
S3に保存はしているが使われていないログ、結構あると思います。そういったログを活用するためのツールとしてAthenaを活用してみてはいかがでしょうか?