RailsのログをfluentdでBigQuery、あるいはS3に取り込む
GCP BigQueryやAWS Athenaを実際に触る機会が欲しかったので、RailsのログをfluentdでBigQueryやS3に取り込んでみます。 とりあえず触ることが目的で、実用できるかはとりあえず脇においておきます。
なお、fluentd(td-agent)はOS Xに0.14.21 をインストールしています。
Rails fluent logger
Railsのログはデフォルトでは log ディレクトリに出力されるため、これをfluentdで扱えるようにする必要があります。
ドキュメント Collecting and Analyzing Ruby on Rails Logs | Fluentd に従って、lograge と act-fluent-logger-rails を使ってみます。
ほぼドキュメント通りですが、以下のように設定しました。
config/application.rb
class Application < Rails::Application
config.log_level = :info
config.logger = ActFluentLoggerRails::Logger.new
config.lograge.enabled = true
config.lograge.formatter = Lograge::Formatters::Json.new
config.lograge.custom_options = lambda do |event|
exceptions = %w(controller action format id)
{
params: event.payload[:params].except(*exceptions)
}
end
end
custom_optionsでリクエストパラメタをログに出力するようにしています。
config/fluent-logger.yml
development: fluent_host: '127.0.0.1' fluent_port: 24224 tag: 'foo' messages_type: 'string'
アプリケーションの設定はこれで終わりです。
fluentd + BigQuery
次は、BigQueryにログを出力です。 fluent-plugin-bigquery を使います。
/etc/td-agent/td-agent.conf
<match foo>
@type parser
key_name messages
format json
tag rails
</match>
<filter rails>
@type record_transformer
remove_keys location
</filter>
<match rails>
@type copy
<store>
@type stdout
</store>
<store>
@type bigquery
method insert
auth_method json_key
json_key /path/to/json_key
auto_create_table true
project your-project-id
dataset rails_playground
table logs
schema [
{"name": "method", "type": "STRING"},
{"name": "path", "type": "STRING"},
{"name": "format", "type": "STRING"},
{"name": "controller", "type": "STRING"},
{"name": "action", "type": "STRING"},
{"name": "status", "type": "INTEGER"},
{"name": "duration", "type": "FLOAT"},
{"name": "view", "type": "FLOAT"},
{"name": "db", "type": "FLOAT"},
{"name": "params", "type": "STRING"}
]
</store>
</match>
BigQueryのスキーマも設定します。

実際にクエリを実行してみた結果がこちら。

fluentd + S3
次はfluentdでS3にログを保存してみます。 まずはtd-agentの設定です。Amazon S3 Output Plugin | Fluentdに従えばOKです。
<match pattern>
@type s3
aws_key_id YOUR_AWS_KEY_ID
aws_sec_key YOUR_AWS_SECRET_KEY
s3_bucket YOUR_S3_BUCKET_NAME
s3_region ap-northeast-1
path kotaroito/rails-playground/dt=%Y-%m-%d/
s3_object_key_format %{path}%{time_slice}_%{hostname}_%{index}.%{file_extension}
<buffer tag,time>
@type file
path /var/log/td-agent/s3
timekey 60
timekey_wait 1m
timekey_use_utc true # use utc
</buffer>
format json
include_time_key true
</match>
検証を早くしたいので、timekey は60に設定しています。 これでログがS3に保存されていきます。
{"method":"GET","path":"/books","format":"html","controller":"BooksController","action":"index","status":200,"duration":184.47,"view":156.19,"db":1.52,"params":{},"time":"2017-09-27T14:00:11Z"} {"method":"GET","path":"/books/6","format":"html","controller":"BooksController","action":"show","status":200,"duration":43.6,"view":37.93,"db":0.34,"params":{},"time":"2017-09-27T14:00:21Z"}
Athena
S3に保存しただけじゃ面白くないので、以前から気になっていたAthenaを使ってみることにします。
Amazon Athena (サーバーレスのインタラクティブなクエリサービス) | AWS
Amazon Athena はインタラクティブなクエリサービスで、Amazon S3 内のデータを標準的な SQL を使用して簡単に分析できます。Athena はサーバーレスなので、インフラストラクチャの管理は不要です。実行したクエリに対してのみ料金が発生します。
Athena は簡単に使えます。Amazon S3 にあるデータを指定して、スキーマを定義し、標準的な SQL を使ってデータのクエリを開始するだけです。多くの場合、数秒で結果が出てきます。Athena を使用すると、分析用データを準備するための複雑な ETL ジョブは不要になります。これによって、誰でも SQL のスキルを使って、大型データセットをすばやく、簡単に分析できるようになります。
Athenaには Getting Started — User Guideにてチュートリアルが用意されているので、これを最初にやると雰囲気が掴めます。
やるべきことは、CREATE TABLE をして、
CREATE EXTERNAL TABLE IF NOT EXISTS default.rails_logs ( `method` string, `path` string, `format` string, `controller` string, `action` string, `status` int, `duration` float, `view` float, `db` float, `params` map<string,string>, `time` string ) ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe' WITH SERDEPROPERTIES ( 'serialization.format' = '1' ) LOCATION 's3://your-bucket-name/path_to_log_dir/' TBLPROPERTIES ('has_encrypted_data'='false')
あとはクエリを実行するだけです。
SELECT * FROM default."rails_logs" limit 10

ね、簡単でしょ?
と言いたいところなんですが、色々調べると「S3にログだけ置いておけばあとはAthenaがいい感じやってくれるぜー」という夢のような話はなく、(まともに運用するなら)パーティショニング、ログフォーマット、実行結果の保存等、考えることは多そうです。
日常的に見ることはないログをS3に保存しておき、ad-hocに分析したいという時にはAthenaは1つの選択肢かもなと思いました。 (その他ユースケースでAthenaが最適解になるかはもうちょっと自身が勉強しないと、答が出なそう)
まとめというか、感想
logrageとact-fluent-logger-railsを使うと、RailsのログをかんたんにBigQueryやS3に取り込みできました。 ただし、logrageは例外ログまではサポートしていない(FAQ)ので、例外トラッキングサービス(airbrake.ioなど)別の方法を用意する必要がありそうです。
Athenaはどんなユースケースに使えるかもう少し研究したいところ。