EBに置いたrailsからfluentdでlogをamazonESに投げたメモ

More than 1 year has passed since last update.

AWS Elastic Beanstalkに設置したrailsから、Amazon Elasticsearch Serviceにfluentdでログを投げつけたときのもろもろをメモ。


railsをEBに設置

略。

公式のドキュメントなんかを読みつつ。

環境変数にSECRET_KEY_BASEやらAWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEYを設定するのを忘れずに。


logrageでjsonのlog吐き出す

https://github.com/roidrage/lograge

http://qiita.com/tos-miyake/items/cafa31049e543dba3049 を参考にしつつ必要な情報をjsonに突っ込むよう設定。


Gemfile

gem 'lograge'

gem 'logstash-event'
gem "rack-user_agent"


app/controllers/application_controller.rb


def append_info_to_payload(payload)
super

payload[:uuid] = request.uuid
payload[:host] = request.host
payload[:remote_ip] = request.remote_ip
payload[:user_agent] = request.user_agent
payload[:os] = request.os
payload[:os_version] = request.os_version
payload[:browser] = request.browser
payload[:browser_version] = request.browser_version

payload[:user_id] = current_user.id.to_s if user_signed_in?
payload[:administrator_id] = current_administrator.id.to_s if administrator_signed_in?
end



config/initializers/lograge.rb

Rails.application.configure do

config.lograge.enabled = true
config.lograge.formatter = Lograge::Formatters::Logstash.new
config.lograge.logger = ActiveSupport::Logger.new(Rails.root.join("log/lograge_#{Rails.env}.log"), 1, 100.megabytes)
config.lograge.keep_original_rails_log = true

config.lograge.custom_options = lambda do |event|
payload = event.payload

data = payload.slice(*%i(
uuid host remote_ip user_agent os os_version browser browser_version
user_id administrator_id
)
)

if payload[:exception]
e = payload[:exception_object]
data[:exception_class] = e.class.to_s
data[:exception_message] = e.message
data[:stacktrace] = "#{e.class}: #{e.message}\n" + (e.backtrace || []).join("\n")
end

data
end
end



Amazon Elesticesearch Serviceを立ち上げる

画面の指示に従ってポチポチ設定。

アクセスポリシーは設定画面で出てくるテンプレートを参考にしつつEBで使用しているIAMユーザーとIP制限とを設定。

参考: http://dev.classmethod.jp/cloud/aws/cm-advent-calendar-2015-getting-started-again-amazon-es/

{

"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::IAMユーザーのarn"
]
},
"Action": [
"es:*"
],
"Resource": "arn:aws:es:ESのarn/*"
},
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "es:*",
"Condition": {
"IpAddress": {
"aws:SourceIp": [
"IPその1",
"IPその2"
]
}
},
"Resource": "arn:aws:es:ESのarn/*"
}
]
}


template設定

ドメインの用意ができたら、elasticsearchデフォのままだとstringが勝手にトークナイズされてしまうので、Dynamic templatesという機能を使うことでごっそりstringは全部解析するのとしないのを用意するようにした。

参考: http://qiita.com/harukasan/items/4ec517d8d96f557367e1

$ curl -XPUT https://ESのどめいん/_template/template_all -d "`cat template_all.json`"


template_all.json

{

"template": "*",
"mappings": {
"_default_": {
"dynamic_templates": [
{
"strings": {
"match_mapping_type": "string",
"match": "*",
"mapping": {
"type": "multi_field",
"fields": {
"{name}": {
"type": "string",
"index": "analyzed"
},
"full": {
"type": "string",
"index": "not_analyzed"
}
}
}
}
}
]
}
}
}


EBにfluentd入れたり設定したり

.ebextensionsで設定。

fluentd公式が用意してくれてる設定をベースにいじる。

アウトプットのpluginはhttps://github.com/uken/fluent-plugin-elasticsearch によると


Note: For Amazon Elasticsearch Service please consider using fluent-plugin-aws-elasticsearch-service


とのことなので、今回はfluent-plugin-aws-elasticsearch-serviceを使用。

参考: http://qiita.com/k-nishigaki/items/d6b4d39391914ca4a278


.ebextensions/40_td-agent-gen-config.config

files:

"/etc/td-agent/td-agent.conf":
owner: root
group: root
content: |
<source>
@type tail
format json
tag rails.lograge
path "/var/app/current/log/lograge_#{ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'unknown'}.log"
pos_file "/var/log/td-agent/lograge_#{ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'unknown'}.log.pos"
time_key time
</source>

<filter **>
@type stdout
</filter>

<match rails.lograge>
@type aws-elasticsearch-service
logstash_format true
logstash_prefix "lograge-#{ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'unknown'}"
id_key uuid
include_tag_key true
flush_interval 1s
reload_connections false
reload_on_failure false

<endpoint>
url "#{ENV['AWS_ES_URL']}"
region ap-northeast-1
access_key_id "#{ENV['AWS_ACCESS_KEY_ID']}"
secret_access_key "#{ENV['AWS_SECRET_KEY']}"
</endpoint>
</match>
EOS



.ebextensions/41_td-agent-install.config

commands:

01-command:
command: grep '^Defaults:root !requiretty' /etc/sudoers || echo 'Defaults:root !requiretty' >> /etc/sudoers

02-command:
command: curl -L https://toolbelt.treasuredata.com/sh/install-redhat-td-agent2.sh | sh

03-command:
command: /usr/sbin/td-agent-gem install fluent-plugin-aws-elasticsearch-service

container_commands: # confにENVが必要なので
01-command:
command: /etc/init.d/td-agent restart


td-agent.confで環境変数使ってるので、commandsではなくcontainer_commandsでrestartさせてる。

あと、EBにてamazonESのエンドポイントをAWS_ES_URL環境変数に設定してる。


kibanaで見たり

amazonESでドメイン用意した時点で一緒に用意されているkibanaで、indexパターンをtd-agent.confで設定したもの(lograge-production-*的な)で設定して色々さわったり見たり。